diff --git a/.github/workflows/contracts.yml b/.github/workflows/contracts.yml deleted file mode 100644 index 1dc6e9f0a..000000000 --- a/.github/workflows/contracts.yml +++ /dev/null @@ -1,138 +0,0 @@ -name: Contracts - -on: - push: - branches: - - main - - staging - - develop - - alpha - paths: - - 'contracts/**' - - '.github/workflows/contracts.yaml' - pull_request: - types: - - opened - - reopened - - synchronize - - ready_for_review - paths: - - 'contracts/**' - - '.github/workflows/contracts.yaml' - -defaults: - run: - working-directory: 'contracts' - -jobs: - foundry: - if: github.event.pull_request.draft == false - runs-on: ubuntu-latest - - steps: - - name: Checkout sources - uses: actions/checkout@v4 - with: - submodules: recursive - - - name: Install Foundry - uses: foundry-rs/foundry-toolchain@v1 - with: - version: nightly - - - name: Setup LCOV - uses: hrishikesh-kadam/setup-lcov@v1 - - - name: Install Node.js 18 - uses: actions/setup-node@v2 - with: - node-version: '18' - - - name: Get yarn cache directory path - id: yarn-cache-dir-path - run: echo "::set-output name=dir::$(yarn cache dir)" - - - name: Cache yarn dependencies - uses: actions/cache@v2 - id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`) - with: - path: ${{ steps.yarn-cache-dir-path.outputs.dir }} - key: ${{ runner.os }}-yarn-${{ hashFiles('contracts/yarn.lock') }} - restore-keys: | - ${{ runner.os }}-yarn- - - - name: Cache node_modules - id: npm_cache - uses: actions/cache@v2 - with: - path: node_modules - key: node_modules-${{ hashFiles('contracts/yarn.lock') }} - - - name: yarn install - # if: steps.npm_cache.outputs.cache-hit != 'true' - run: yarn install - - - name: Compile with foundry - run: forge build --evm-version cancun - - - name: Run foundry tests - run: forge test --evm-version cancun -vvv - - - name: Run foundry coverage - run : forge coverage --evm-version cancun --report lcov - - - name : Prune coverage - run : lcov --rc branch_coverage=1 --remove ./lcov.info -o ./lcov.info.pruned 'src/mocks/*' 'src/test/*' 'scripts/*' 'node_modules/*' 'lib/*' - - - name: Upload coverage reports to Codecov - uses: codecov/codecov-action@v3 - env: - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} - with: - files: contracts/lcov.info.pruned - flags: contracts - - hardhat: - if: github.event.pull_request.draft == false - runs-on: ubuntu-latest - - steps: - - name: Checkout sources - uses: actions/checkout@v4 - with: - submodules: recursive - - - name: Install Node.js 18 - uses: actions/setup-node@v2 - with: - node-version: '18' - - - name: Get yarn cache directory path - id: yarn-cache-dir-path - run: echo "::set-output name=dir::$(yarn cache dir)" - - - name: Cache yarn dependencies - uses: actions/cache@v2 - id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`) - with: - path: ${{ steps.yarn-cache-dir-path.outputs.dir }} - key: ${{ runner.os }}-yarn-${{ hashFiles('contracts/yarn.lock') }} - restore-keys: | - ${{ runner.os }}-yarn- - - - name: Cache node_modules - id: npm_cache - uses: actions/cache@v2 - with: - path: node_modules - key: node_modules-${{ hashFiles('contracts/yarn.lock') }} - - - name: yarn install - # if: steps.npm_cache.outputs.cache-hit != 'true' - run: yarn install - - - name: Compile with hardhat - run: npx hardhat compile - - - name: Run hardhat tests - run: npx hardhat test diff --git a/.gitmodules b/.gitmodules index fdf8ed7b5..158c61213 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,12 +1,3 @@ -[submodule "l2geth"] - path = l2geth - url = git@github.com:scroll-tech/go-ethereum.git -[submodule "contracts/lib/ds-test"] - path = contracts/lib/ds-test - url = https://github.com/dapphub/ds-test -[submodule "contracts/lib/forge-std"] - path = contracts/lib/forge-std - url = https://github.com/foundry-rs/forge-std -[submodule "contracts/lib/solmate"] - path = contracts/lib/solmate - url = https://github.com/rari-capital/solmate +[submodule "scroll-contracts"] + path = scroll-contracts + url = https://github.com/scroll-tech/scroll-contracts.git diff --git a/README.md b/README.md index c221626cd..a27185f5f 100644 --- a/README.md +++ b/README.md @@ -52,12 +52,6 @@ go test -v -race -covermode=atomic scroll-tech/database/... go test -v -race -covermode=atomic scroll-tech/common/... ``` -## Testing Contracts - -You can find the unit tests in [`contracts/src/test/`](/contracts/src/test/), and integration tests in [`contracts/integration-test/`](/contracts/integration-test/). - -See [`contracts`](/contracts) for more details on the contracts. - ## License Scroll Monorepo is licensed under the [MIT](./LICENSE) license. diff --git a/contracts/.env.example b/contracts/.env.example deleted file mode 100644 index 49e95ed1d..000000000 --- a/contracts/.env.example +++ /dev/null @@ -1,12 +0,0 @@ -### NOTE: DO NOT USE THIS FILE IF USING TESTNET'S .ENV -ETHERSCAN_API_KEY=ABC123ABC123ABC123ABC123ABC123ABC1 - -RINKEBY_RPC=https://eth-rinkeby.alchemyapi.io/v2/ -SCROLL_L1_RPC=https://prealpha.scroll.io/l1 -SCROLL_L2_RPC=https://prealpha.scroll.io/l2 - -RINKEBY_PRIVATE_KEY=0xabc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc1 -L1_DEPLOYER_PRIVATE_KEY=0xabc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc1 -L2_DEPLOYER_PRIVATE_KEY=0xabc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc1 - -CHAIN_ID_L2="5343541" diff --git a/contracts/.eslintignore b/contracts/.eslintignore deleted file mode 100644 index 85f5562af..000000000 --- a/contracts/.eslintignore +++ /dev/null @@ -1,4 +0,0 @@ -node_modules -artifacts -cache -coverage diff --git a/contracts/.eslintrc.js b/contracts/.eslintrc.js deleted file mode 100644 index 98ce1937b..000000000 --- a/contracts/.eslintrc.js +++ /dev/null @@ -1,24 +0,0 @@ -module.exports = { - env: { - browser: false, - es2021: true, - mocha: true, - node: true, - }, - plugins: ["@typescript-eslint"], - extends: [ - "standard", - "plugin:prettier/recommended", - "plugin:node/recommended", - ], - parser: "@typescript-eslint/parser", - parserOptions: { - ecmaVersion: 12, - }, - rules: { - "node/no-unsupported-features/es-syntax": [ - "error", - { ignores: ["modules"] }, - ], - }, -}; diff --git a/contracts/.gitignore b/contracts/.gitignore deleted file mode 100644 index 10418cae4..000000000 --- a/contracts/.gitignore +++ /dev/null @@ -1,17 +0,0 @@ -node_modules -.env -coverage -coverage.json -typechain - -# Hardhat/Foundry files -cache -cache-hardhat -artifacts -broadcast - -# logs -*.log - -# eslint -.eslintcache diff --git a/contracts/.husky/pre-commit b/contracts/.husky/pre-commit deleted file mode 100755 index cdb0f5569..000000000 --- a/contracts/.husky/pre-commit +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env sh -. "$(dirname -- "$0")/_/husky.sh" - -cd contracts -yarn lint-staged \ No newline at end of file diff --git a/contracts/.npmignore b/contracts/.npmignore deleted file mode 100644 index dc037817b..000000000 --- a/contracts/.npmignore +++ /dev/null @@ -1,3 +0,0 @@ -hardhat.config.ts -scripts -test diff --git a/contracts/.nvmrc b/contracts/.nvmrc deleted file mode 100644 index e048c8ca1..000000000 --- a/contracts/.nvmrc +++ /dev/null @@ -1 +0,0 @@ -v18.15.0 diff --git a/contracts/.prettierignore b/contracts/.prettierignore deleted file mode 100644 index 290dcbed3..000000000 --- a/contracts/.prettierignore +++ /dev/null @@ -1,8 +0,0 @@ -node_modules -artifacts -cache -coverage* -gasReporterOutput.json -src/libraries/verifier/ZkTrieVerifier.sol -src/libraries/verifier/PatriciaMerkleTrieVerifier.sol -src/L2/predeploys/L1BlockContainer.sol diff --git a/contracts/.prettierrc b/contracts/.prettierrc deleted file mode 100644 index 1f89d8a73..000000000 --- a/contracts/.prettierrc +++ /dev/null @@ -1,28 +0,0 @@ -{ - "printWidth": 120, - "singleQuote": false, - "tabWidth": 2, - "bracketSpacing": true, - "overrides": [ - { - "files": "src/**/*.sol", - "options": { - "printWidth": 120, - "tabWidth": 4, - "useTabs": false, - "singleQuote": false, - "bracketSpacing": false - } - }, - { - "files": "scripts/**/*.sol", - "options": { - "printWidth": 120, - "tabWidth": 4, - "useTabs": false, - "singleQuote": false, - "bracketSpacing": false - } - } - ] -} diff --git a/contracts/.solcover.js b/contracts/.solcover.js deleted file mode 100644 index 4df81f948..000000000 --- a/contracts/.solcover.js +++ /dev/null @@ -1,10 +0,0 @@ -module.exports = { - skipFiles: [ - 'mocks', - 'test', - 'L2/predeploys/L1BlockContainer.sol', - 'libraries/verifier/ZkTrieVerifier.sol', - 'libraries/verifier/PatriciaMerkleTrieVerifier.sol' - ], - istanbulReporter: ["lcov", "json"] -}; diff --git a/contracts/.solhint.json b/contracts/.solhint.json deleted file mode 100644 index f3e31e8c5..000000000 --- a/contracts/.solhint.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "extends": "solhint:recommended", - "rules": { - "compiler-version": ["error", "^0.8.0"], - "func-visibility": ["warn", { "ignoreConstructors": true }] - } -} diff --git a/contracts/.solhintignore b/contracts/.solhintignore deleted file mode 100644 index 3c3629e64..000000000 --- a/contracts/.solhintignore +++ /dev/null @@ -1 +0,0 @@ -node_modules diff --git a/contracts/README.md b/contracts/README.md deleted file mode 100644 index 50466220b..000000000 --- a/contracts/README.md +++ /dev/null @@ -1,78 +0,0 @@ -# Scroll Contracts - -This directory contains the solidity code for Scroll L1 bridge and rollup contracts and L2 bridge and pre-deployed contracts. You can also find contract APIs and more details in the [`docs`](./docs) folder. - -## Directory Structure - -
-├── docs: Documentation for the contracts
-├── integration-test: Hardhat integration tests
-├── lib: External libraries and testing tools
-├── scripts: Deployment scripts
-├── src
-│   ├── gas-swap: Utility contract that allows gas payment in other tokens
-│   ├── interfaces: Common contract interfaces
-│   ├── L1: Contracts deployed on the L1 (Ethereum)
-│   │   ├── gateways: Gateway router and token gateway contracts
-│   │   ├── rollup: Rollup contracts for data availability and finalization
-│   │   ├── IL1ScrollMessenger.sol: L1 Scroll messenger interface
-│   │   └── L1ScrollMessenger.sol: L1 Scroll messenger contract
-│   ├── L2: Contracts deployed on the L2 (Scroll)
-│   │   ├── gateways: Gateway router and token gateway contracts
-│   │   ├── predeploys: Pre-deployed contracts on L2
-│   │   ├── IL2ScrollMessenger.sol: L2 Scroll messenger interface
-│   │   └── L2ScrollMessenger.sol: L2 Scroll messenger contract
-│   ├── libraries: Shared contract libraries
-│   ├── misc: Miscellaneous contracts
-│   ├── mocks: Mock contracts used in the testing
-│   ├── rate-limiter: Rater limiter contract
-│   └── test: Unit tests in solidity
-├── foundry.toml: Foundry configuration
-├── hardhat.config.ts: Hardhat configuration
-├── remappings.txt: Foundry dependency mappings
-...
-
- -## Dependencies - -### Node.js - -First install [`Node.js`](https://nodejs.org/en) and [`npm`](https://www.npmjs.com/). -Run the following command to install [`yarn`](https://classic.yarnpkg.com/en/): - -```bash -npm install --global yarn -``` - -### Foundry - -Install `foundryup`, the Foundry toolchain installer: - -```bash -curl -L https://foundry.paradigm.xyz | bash -``` - -If you do not want to use the redirect, feel free to manually download the `foundryup` installation script from [here](https://raw.githubusercontent.com/foundry-rs/foundry/master/foundryup/foundryup). - -Then, run `foundryup` in a new terminal session or after reloading `PATH`. - -Other ways to install Foundry can be found [here](https://github.com/foundry-rs/foundry#installation). - -### Hardhat - -Run the following command to install [Hardhat](https://hardhat.org/) and other dependencies. - -``` -yarn install -``` - -## Build - -- Run `git submodule update --init --recursive` to initialize git submodules. -- Run `yarn prettier:solidity` to run linting in fix mode, will auto-format all solidity codes. -- Run `yarn prettier` to run linting in fix mode, will auto-format all typescript codes. -- Run `yarn prepare` to install the precommit linting hook. -- Run `forge build` to compile contracts with foundry. -- Run `npx hardhat compile` to compile with hardhat. -- Run `forge test -vvv` to run foundry units tests. It will compile all contracts before running the unit tests. -- Run `npx hardhat test` to run integration tests. It may not compile all contracts before running, it's better to run `npx hardhat compile` first. diff --git a/contracts/circomlib.d.ts b/contracts/circomlib.d.ts deleted file mode 100644 index de593f544..000000000 --- a/contracts/circomlib.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -declare module "circomlib/src/evmasm"; -declare module "circomlib/src/poseidon_gencontract"; -declare module "circomlib/src/poseidon_constants"; diff --git a/contracts/deployments/README.md b/contracts/deployments/README.md deleted file mode 100644 index 88b430f1f..000000000 --- a/contracts/deployments/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# Deployments - -## local testnet - -```bash -# start local hardhat node -npx hardhat node -``` - -### layer 1 - -Contract addresses can be found in [deployments](./l1geth.json). - -### layer 2 - -Contract addresses can be found in [deployments](./l2geth.json). diff --git a/contracts/deployments/l1geth.json b/contracts/deployments/l1geth.json deleted file mode 100644 index 4a391321b..000000000 --- a/contracts/deployments/l1geth.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "ProxyAdmin": null, - "ZKRollup": { - "implementation": null, - "proxy": null - }, - "L1ScrollMessenger": { - "implementation": null, - "proxy": null - }, - "L1GatewayRouter": { - "implementation": null, - "proxy": null - }, - "L1StandardERC20Gateway": { - "implementation": null, - "proxy": null - }, - "L1WETHGateway": { - "implementation": null, - "proxy": null - } -} diff --git a/contracts/deployments/l2geth.json b/contracts/deployments/l2geth.json deleted file mode 100644 index 52032aa91..000000000 --- a/contracts/deployments/l2geth.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "ProxyAdmin": null, - "WETH": null, - "Whitelist": null, - "ScrollStandardERC20": null, - "ScrollStandardERC20Factory": null, - "L2ScrollMessenger": null, - "L2GatewayRouter": { - "implementation": null, - "proxy": null - }, - "L2StandardERC20Gateway": { - "implementation": null, - "proxy": null - }, - "L2WETHGateway": { - "implementation": null, - "proxy": null - } -} diff --git a/contracts/docs/apis/L1ERC1155Gateway.md b/contracts/docs/apis/L1ERC1155Gateway.md deleted file mode 100644 index e410f029a..000000000 --- a/contracts/docs/apis/L1ERC1155Gateway.md +++ /dev/null @@ -1,599 +0,0 @@ -# L1ERC1155Gateway - - - -> L1ERC1155Gateway - -The `L1ERC1155Gateway` is used to deposit ERC1155 compatible NFT on layer 1 and finalize withdraw the NFTs from layer 2. - -*The deposited NFTs are held in this gateway. On finalizing withdraw, the corresponding NFT will be transfer to the recipient directly. This will be changed if we have more specific scenarios.* - -## Methods - -### batchDepositERC1155 - -```solidity -function batchDepositERC1155(address _token, uint256[] _tokenIds, uint256[] _amounts, uint256 _gasLimit) external payable -``` - -Deposit a list of some ERC1155 NFT to caller's account on layer 2. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _token | address | The address of ERC1155 NFT on layer 1. | -| _tokenIds | uint256[] | The list of token ids to deposit. | -| _amounts | uint256[] | The list of corresponding number of token to deposit. | -| _gasLimit | uint256 | Estimated gas limit required to complete the deposit on layer 2. | - -### batchDepositERC1155 - -```solidity -function batchDepositERC1155(address _token, address _to, uint256[] _tokenIds, uint256[] _amounts, uint256 _gasLimit) external payable -``` - -Deposit a list of some ERC1155 NFT to a recipient's account on layer 2. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _token | address | The address of ERC1155 NFT on layer 1. | -| _to | address | The address of recipient on layer 2. | -| _tokenIds | uint256[] | The list of token ids to deposit. | -| _amounts | uint256[] | The list of corresponding number of token to deposit. | -| _gasLimit | uint256 | Estimated gas limit required to complete the deposit on layer 2. | - -### counterpart - -```solidity -function counterpart() external view returns (address) -``` - -The address of corresponding L1/L2 Gateway contract. - - - - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### depositERC1155 - -```solidity -function depositERC1155(address _token, address _to, uint256 _tokenId, uint256 _amount, uint256 _gasLimit) external payable -``` - -Deposit some ERC1155 NFT to a recipient's account on layer 2. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _token | address | The address of ERC1155 NFT on layer 1. | -| _to | address | The address of recipient on layer 2. | -| _tokenId | uint256 | The token id to deposit. | -| _amount | uint256 | The amount of token to deposit. | -| _gasLimit | uint256 | Estimated gas limit required to complete the deposit on layer 2. | - -### depositERC1155 - -```solidity -function depositERC1155(address _token, uint256 _tokenId, uint256 _amount, uint256 _gasLimit) external payable -``` - -Deposit some ERC1155 NFT to caller's account on layer 2. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _token | address | The address of ERC1155 NFT on layer 1. | -| _tokenId | uint256 | The token id to deposit. | -| _amount | uint256 | The amount of token to deposit. | -| _gasLimit | uint256 | Estimated gas limit required to complete the deposit on layer 2. | - -### finalizeBatchWithdrawERC1155 - -```solidity -function finalizeBatchWithdrawERC1155(address _l1Token, address _l2Token, address _from, address _to, uint256[] _tokenIds, uint256[] _amounts) external nonpayable -``` - -Complete ERC1155 batch withdraw from layer 2 to layer 1 and send fund to recipient's account on layer 1. The function should only be called by L1ScrollMessenger. The function should also only be called by L2ERC1155Gateway on layer 2. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _l1Token | address | The address of corresponding layer 1 token. | -| _l2Token | address | The address of corresponding layer 2 token. | -| _from | address | The address of account who withdraw the token on layer 2. | -| _to | address | The address of recipient on layer 1 to receive the token. | -| _tokenIds | uint256[] | The list of token ids to withdraw. | -| _amounts | uint256[] | The list of corresponding number of token to withdraw. | - -### finalizeWithdrawERC1155 - -```solidity -function finalizeWithdrawERC1155(address _l1Token, address _l2Token, address _from, address _to, uint256 _tokenId, uint256 _amount) external nonpayable -``` - -Complete ERC1155 withdraw from layer 2 to layer 1 and send fund to recipient's account on layer 1. The function should only be called by L1ScrollMessenger. The function should also only be called by L2ERC1155Gateway on layer 2. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _l1Token | address | The address of corresponding layer 1 token. | -| _l2Token | address | The address of corresponding layer 2 token. | -| _from | address | The address of account who withdraw the token on layer 2. | -| _to | address | The address of recipient on layer 1 to receive the token. | -| _tokenId | uint256 | The token id to withdraw. | -| _amount | uint256 | The amount of token to withdraw. | - -### initialize - -```solidity -function initialize(address _counterpart, address _messenger) external nonpayable -``` - -Initialize the storage of L1ERC1155Gateway. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _counterpart | address | The address of L2ERC1155Gateway in L2. | -| _messenger | address | The address of L1ScrollMessenger in L1. | - -### messenger - -```solidity -function messenger() external view returns (address) -``` - -The address of corresponding L1ScrollMessenger/L2ScrollMessenger contract. - - - - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### onDropMessage - -```solidity -function onDropMessage(bytes _message) external payable -``` - - - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _message | bytes | undefined | - -### onERC1155BatchReceived - -```solidity -function onERC1155BatchReceived(address, address, uint256[], uint256[], bytes) external nonpayable returns (bytes4) -``` - - - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | -| _1 | address | undefined | -| _2 | uint256[] | undefined | -| _3 | uint256[] | undefined | -| _4 | bytes | undefined | - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | bytes4 | undefined | - -### onERC1155Received - -```solidity -function onERC1155Received(address, address, uint256, uint256, bytes) external nonpayable returns (bytes4) -``` - - - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | -| _1 | address | undefined | -| _2 | uint256 | undefined | -| _3 | uint256 | undefined | -| _4 | bytes | undefined | - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | bytes4 | undefined | - -### owner - -```solidity -function owner() external view returns (address) -``` - - - -*Returns the address of the current owner.* - - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### renounceOwnership - -```solidity -function renounceOwnership() external nonpayable -``` - - - -*Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner.* - - -### router - -```solidity -function router() external view returns (address) -``` - -The address of L1GatewayRouter/L2GatewayRouter contract. - - - - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### supportsInterface - -```solidity -function supportsInterface(bytes4 interfaceId) external view returns (bool) -``` - - - -*See {IERC165-supportsInterface}.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| interfaceId | bytes4 | undefined | - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | bool | undefined | - -### tokenMapping - -```solidity -function tokenMapping(address) external view returns (address) -``` - -Mapping from l1 token address to l2 token address for ERC1155 NFT. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### transferOwnership - -```solidity -function transferOwnership(address newOwner) external nonpayable -``` - - - -*Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| newOwner | address | undefined | - -### updateTokenMapping - -```solidity -function updateTokenMapping(address _l1Token, address _l2Token) external nonpayable -``` - -Update layer 2 to layer 2 token mapping. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _l1Token | address | The address of ERC1155 token on layer 1. | -| _l2Token | address | The address of corresponding ERC1155 token on layer 2. | - - - -## Events - -### BatchDepositERC1155 - -```solidity -event BatchDepositERC1155(address indexed _l1Token, address indexed _l2Token, address indexed _from, address _to, uint256[] _tokenIds, uint256[] _amounts) -``` - -Emitted when the ERC1155 NFT is batch deposited to gateway on layer 1. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _l1Token `indexed` | address | The address of ERC1155 NFT on layer 1. | -| _l2Token `indexed` | address | The address of ERC1155 NFT on layer 2. | -| _from `indexed` | address | The address of sender on layer 1. | -| _to | address | The address of recipient on layer 2. | -| _tokenIds | uint256[] | The list of token ids of the ERC1155 NFT to deposit on layer 1. | -| _amounts | uint256[] | The list of corresponding number of token to deposit on layer 1. | - -### BatchRefundERC1155 - -```solidity -event BatchRefundERC1155(address indexed token, address indexed recipient, uint256[] tokenIds, uint256[] amounts) -``` - -Emitted when some ERC1155 token is refunded. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| token `indexed` | address | The address of the token in L1. | -| recipient `indexed` | address | The address of receiver in L1. | -| tokenIds | uint256[] | The list of ids of token refunded. | -| amounts | uint256[] | The list of amount of token refunded. | - -### DepositERC1155 - -```solidity -event DepositERC1155(address indexed _l1Token, address indexed _l2Token, address indexed _from, address _to, uint256 _tokenId, uint256 _amount) -``` - -Emitted when the ERC1155 NFT is deposited to gateway on layer 1. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _l1Token `indexed` | address | The address of ERC1155 NFT on layer 1. | -| _l2Token `indexed` | address | The address of ERC1155 NFT on layer 2. | -| _from `indexed` | address | The address of sender on layer 1. | -| _to | address | The address of recipient on layer 2. | -| _tokenId | uint256 | The token id of the ERC1155 NFT to deposit on layer 1. | -| _amount | uint256 | The number of token to deposit on layer 1. | - -### FinalizeBatchWithdrawERC1155 - -```solidity -event FinalizeBatchWithdrawERC1155(address indexed _l1Token, address indexed _l2Token, address indexed _from, address _to, uint256[] _tokenIds, uint256[] _amounts) -``` - -Emitted when the ERC1155 NFT is batch transferred to recipient on layer 1. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _l1Token `indexed` | address | The address of ERC1155 NFT on layer 1. | -| _l2Token `indexed` | address | The address of ERC1155 NFT on layer 2. | -| _from `indexed` | address | The address of sender on layer 2. | -| _to | address | The address of recipient on layer 1. | -| _tokenIds | uint256[] | The list of token ids of the ERC1155 NFT to withdraw from layer 2. | -| _amounts | uint256[] | The list of corresponding number of token to withdraw from layer 2. | - -### FinalizeWithdrawERC1155 - -```solidity -event FinalizeWithdrawERC1155(address indexed _l1Token, address indexed _l2Token, address indexed _from, address _to, uint256 _tokenId, uint256 _amount) -``` - -Emitted when the ERC1155 NFT is transferred to recipient on layer 1. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _l1Token `indexed` | address | The address of ERC1155 NFT on layer 1. | -| _l2Token `indexed` | address | The address of ERC1155 NFT on layer 2. | -| _from `indexed` | address | The address of sender on layer 2. | -| _to | address | The address of recipient on layer 1. | -| _tokenId | uint256 | The token id of the ERC1155 NFT to withdraw from layer 2. | -| _amount | uint256 | The number of token to withdraw from layer 2. | - -### Initialized - -```solidity -event Initialized(uint8 version) -``` - - - -*Triggered when the contract has been initialized or reinitialized.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| version | uint8 | undefined | - -### OwnershipTransferred - -```solidity -event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -``` - - - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| previousOwner `indexed` | address | undefined | -| newOwner `indexed` | address | undefined | - -### RefundERC1155 - -```solidity -event RefundERC1155(address indexed token, address indexed recipient, uint256 tokenId, uint256 amount) -``` - -Emitted when some ERC1155 token is refunded. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| token `indexed` | address | The address of the token in L1. | -| recipient `indexed` | address | The address of receiver in L1. | -| tokenId | uint256 | The id of token refunded. | -| amount | uint256 | The amount of token refunded. | - -### UpdateTokenMapping - -```solidity -event UpdateTokenMapping(address indexed l1Token, address indexed oldL2Token, address indexed newL2Token) -``` - -Emitted when token mapping for ERC1155 token is updated. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| l1Token `indexed` | address | The address of ERC1155 token in layer 1. | -| oldL2Token `indexed` | address | The address of the old corresponding ERC1155 token in layer 2. | -| newL2Token `indexed` | address | The address of the new corresponding ERC1155 token in layer 2. | - - - -## Errors - -### ErrorCallerIsNotCounterpartGateway - -```solidity -error ErrorCallerIsNotCounterpartGateway() -``` - - - -*Thrown when the cross chain sender is not the counterpart gateway contract.* - - -### ErrorCallerIsNotMessenger - -```solidity -error ErrorCallerIsNotMessenger() -``` - - - -*Thrown when the caller is not corresponding `L1ScrollMessenger` or `L2ScrollMessenger`.* - - -### ErrorNotInDropMessageContext - -```solidity -error ErrorNotInDropMessageContext() -``` - - - -*Thrown when ScrollMessenger is not dropping message.* - - -### ErrorZeroAddress - -```solidity -error ErrorZeroAddress() -``` - - - -*Thrown when the given address is `address(0)`.* - - - diff --git a/contracts/docs/apis/L1ERC721Gateway.md b/contracts/docs/apis/L1ERC721Gateway.md deleted file mode 100644 index 17f54006a..000000000 --- a/contracts/docs/apis/L1ERC721Gateway.md +++ /dev/null @@ -1,538 +0,0 @@ -# L1ERC721Gateway - - - -> L1ERC721Gateway - -The `L1ERC721Gateway` is used to deposit ERC721 compatible NFT on layer 1 and finalize withdraw the NFTs from layer 2. - -*The deposited NFTs are held in this gateway. On finalizing withdraw, the corresponding NFT will be transfer to the recipient directly. This will be changed if we have more specific scenarios.* - -## Methods - -### batchDepositERC721 - -```solidity -function batchDepositERC721(address _token, address _to, uint256[] _tokenIds, uint256 _gasLimit) external payable -``` - -Deposit a list of some ERC721 NFT to a recipient's account on layer 2. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _token | address | The address of ERC721 NFT on layer 1. | -| _to | address | The address of recipient on layer 2. | -| _tokenIds | uint256[] | The list of token ids to deposit. | -| _gasLimit | uint256 | Estimated gas limit required to complete the deposit on layer 2. | - -### batchDepositERC721 - -```solidity -function batchDepositERC721(address _token, uint256[] _tokenIds, uint256 _gasLimit) external payable -``` - -Deposit a list of some ERC721 NFT to caller's account on layer 2. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _token | address | The address of ERC721 NFT on layer 1. | -| _tokenIds | uint256[] | The list of token ids to deposit. | -| _gasLimit | uint256 | Estimated gas limit required to complete the deposit on layer 2. | - -### counterpart - -```solidity -function counterpart() external view returns (address) -``` - -The address of corresponding L1/L2 Gateway contract. - - - - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### depositERC721 - -```solidity -function depositERC721(address _token, address _to, uint256 _tokenId, uint256 _gasLimit) external payable -``` - -Deposit some ERC721 NFT to a recipient's account on layer 2. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _token | address | The address of ERC721 NFT on layer 1. | -| _to | address | The address of recipient on layer 2. | -| _tokenId | uint256 | The token id to deposit. | -| _gasLimit | uint256 | Estimated gas limit required to complete the deposit on layer 2. | - -### depositERC721 - -```solidity -function depositERC721(address _token, uint256 _tokenId, uint256 _gasLimit) external payable -``` - -Deposit some ERC721 NFT to caller's account on layer 2. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _token | address | The address of ERC721 NFT on layer 1. | -| _tokenId | uint256 | The token id to deposit. | -| _gasLimit | uint256 | Estimated gas limit required to complete the deposit on layer 2. | - -### finalizeBatchWithdrawERC721 - -```solidity -function finalizeBatchWithdrawERC721(address _l1Token, address _l2Token, address _from, address _to, uint256[] _tokenIds) external nonpayable -``` - -Complete ERC721 batch withdraw from layer 2 to layer 1 and send NFT to recipient's account on layer 1. - -*Requirements: - The function should only be called by L1ScrollMessenger. - The function should also only be called by L2ERC721Gateway on layer 2.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _l1Token | address | The address of corresponding layer 1 token. | -| _l2Token | address | The address of corresponding layer 2 token. | -| _from | address | The address of account who withdraw the token on layer 2. | -| _to | address | The address of recipient on layer 1 to receive the token. | -| _tokenIds | uint256[] | The list of token ids to withdraw. | - -### finalizeWithdrawERC721 - -```solidity -function finalizeWithdrawERC721(address _l1Token, address _l2Token, address _from, address _to, uint256 _tokenId) external nonpayable -``` - -Complete ERC721 withdraw from layer 2 to layer 1 and send NFT to recipient's account on layer 1. - -*Requirements: - The function should only be called by L1ScrollMessenger. - The function should also only be called by L2ERC721Gateway on layer 2.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _l1Token | address | The address of corresponding layer 1 token. | -| _l2Token | address | The address of corresponding layer 2 token. | -| _from | address | The address of account who withdraw the token on layer 2. | -| _to | address | The address of recipient on layer 1 to receive the token. | -| _tokenId | uint256 | The token id to withdraw. | - -### initialize - -```solidity -function initialize(address _counterpart, address _messenger) external nonpayable -``` - -Initialize the storage of L1ERC721Gateway. - -*The parameters `_counterpart` and `_messenger` are no longer used.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _counterpart | address | The address of L2ERC721Gateway in L2. | -| _messenger | address | The address of L1ScrollMessenger in L1. | - -### messenger - -```solidity -function messenger() external view returns (address) -``` - -The address of corresponding L1ScrollMessenger/L2ScrollMessenger contract. - - - - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### onDropMessage - -```solidity -function onDropMessage(bytes _message) external payable -``` - - - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _message | bytes | undefined | - -### onERC721Received - -```solidity -function onERC721Received(address, address, uint256, bytes) external nonpayable returns (bytes4) -``` - - - -*See {IERC721Receiver-onERC721Received}. Always returns `IERC721Receiver.onERC721Received.selector`.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | -| _1 | address | undefined | -| _2 | uint256 | undefined | -| _3 | bytes | undefined | - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | bytes4 | undefined | - -### owner - -```solidity -function owner() external view returns (address) -``` - - - -*Returns the address of the current owner.* - - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### renounceOwnership - -```solidity -function renounceOwnership() external nonpayable -``` - - - -*Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner.* - - -### router - -```solidity -function router() external view returns (address) -``` - -The address of L1GatewayRouter/L2GatewayRouter contract. - - - - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### tokenMapping - -```solidity -function tokenMapping(address) external view returns (address) -``` - -Mapping from l1 token address to l2 token address for ERC721 NFT. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### transferOwnership - -```solidity -function transferOwnership(address newOwner) external nonpayable -``` - - - -*Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| newOwner | address | undefined | - -### updateTokenMapping - -```solidity -function updateTokenMapping(address _l1Token, address _l2Token) external nonpayable -``` - -Update layer 2 to layer 2 token mapping. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _l1Token | address | The address of ERC721 token on layer 1. | -| _l2Token | address | The address of corresponding ERC721 token on layer 2. | - - - -## Events - -### BatchDepositERC721 - -```solidity -event BatchDepositERC721(address indexed _l1Token, address indexed _l2Token, address indexed _from, address _to, uint256[] _tokenIds) -``` - -Emitted when the ERC721 NFT is batch deposited to gateway on layer 1. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _l1Token `indexed` | address | The address of ERC721 NFT on layer 1. | -| _l2Token `indexed` | address | The address of ERC721 NFT on layer 2. | -| _from `indexed` | address | The address of sender on layer 1. | -| _to | address | The address of recipient on layer 2. | -| _tokenIds | uint256[] | The list of token ids of the ERC721 NFT to deposit on layer 1. | - -### BatchRefundERC721 - -```solidity -event BatchRefundERC721(address indexed token, address indexed recipient, uint256[] tokenIds) -``` - -Emitted when a batch of ERC721 tokens are refunded. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| token `indexed` | address | The address of the token in L1. | -| recipient `indexed` | address | The address of receiver in L1. | -| tokenIds | uint256[] | The list of token ids of the ERC721 NFT refunded. | - -### DepositERC721 - -```solidity -event DepositERC721(address indexed _l1Token, address indexed _l2Token, address indexed _from, address _to, uint256 _tokenId) -``` - -Emitted when the ERC721 NFT is deposited to gateway on layer 1. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _l1Token `indexed` | address | The address of ERC721 NFT on layer 1. | -| _l2Token `indexed` | address | The address of ERC721 NFT on layer 2. | -| _from `indexed` | address | The address of sender on layer 1. | -| _to | address | The address of recipient on layer 2. | -| _tokenId | uint256 | The token id of the ERC721 NFT to deposit on layer 1. | - -### FinalizeBatchWithdrawERC721 - -```solidity -event FinalizeBatchWithdrawERC721(address indexed _l1Token, address indexed _l2Token, address indexed _from, address _to, uint256[] _tokenIds) -``` - -Emitted when the ERC721 NFT is batch transferred to recipient on layer 1. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _l1Token `indexed` | address | The address of ERC721 NFT on layer 1. | -| _l2Token `indexed` | address | The address of ERC721 NFT on layer 2. | -| _from `indexed` | address | The address of sender on layer 2. | -| _to | address | The address of recipient on layer 1. | -| _tokenIds | uint256[] | The list of token ids of the ERC721 NFT to withdraw from layer 2. | - -### FinalizeWithdrawERC721 - -```solidity -event FinalizeWithdrawERC721(address indexed _l1Token, address indexed _l2Token, address indexed _from, address _to, uint256 _tokenId) -``` - -Emitted when the ERC721 NFT is transferred to recipient on layer 1. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _l1Token `indexed` | address | The address of ERC721 NFT on layer 1. | -| _l2Token `indexed` | address | The address of ERC721 NFT on layer 2. | -| _from `indexed` | address | The address of sender on layer 2. | -| _to | address | The address of recipient on layer 1. | -| _tokenId | uint256 | The token id of the ERC721 NFT to withdraw from layer 2. | - -### Initialized - -```solidity -event Initialized(uint8 version) -``` - - - -*Triggered when the contract has been initialized or reinitialized.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| version | uint8 | undefined | - -### OwnershipTransferred - -```solidity -event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -``` - - - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| previousOwner `indexed` | address | undefined | -| newOwner `indexed` | address | undefined | - -### RefundERC721 - -```solidity -event RefundERC721(address indexed token, address indexed recipient, uint256 tokenId) -``` - -Emitted when some ERC721 token is refunded. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| token `indexed` | address | The address of the token in L1. | -| recipient `indexed` | address | The address of receiver in L1. | -| tokenId | uint256 | The id of token refunded. | - -### UpdateTokenMapping - -```solidity -event UpdateTokenMapping(address indexed l1Token, address indexed oldL2Token, address indexed newL2Token) -``` - -Emitted when token mapping for ERC721 token is updated. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| l1Token `indexed` | address | The address of ERC721 token in layer 1. | -| oldL2Token `indexed` | address | The address of the old corresponding ERC721 token in layer 2. | -| newL2Token `indexed` | address | The address of the new corresponding ERC721 token in layer 2. | - - - -## Errors - -### ErrorCallerIsNotCounterpartGateway - -```solidity -error ErrorCallerIsNotCounterpartGateway() -``` - - - -*Thrown when the cross chain sender is not the counterpart gateway contract.* - - -### ErrorCallerIsNotMessenger - -```solidity -error ErrorCallerIsNotMessenger() -``` - - - -*Thrown when the caller is not corresponding `L1ScrollMessenger` or `L2ScrollMessenger`.* - - -### ErrorNotInDropMessageContext - -```solidity -error ErrorNotInDropMessageContext() -``` - - - -*Thrown when ScrollMessenger is not dropping message.* - - -### ErrorZeroAddress - -```solidity -error ErrorZeroAddress() -``` - - - -*Thrown when the given address is `address(0)`.* - - - diff --git a/contracts/docs/apis/L1GatewayRouter.md b/contracts/docs/apis/L1GatewayRouter.md deleted file mode 100644 index a4a84f197..000000000 --- a/contracts/docs/apis/L1GatewayRouter.md +++ /dev/null @@ -1,620 +0,0 @@ -# L1GatewayRouter - - - -> L1GatewayRouter - -The `L1GatewayRouter` is the main entry for depositing Ether and ERC20 tokens. All deposited tokens are routed to corresponding gateways. - -*One can also use this contract to query L1/L2 token address mapping. In the future, ERC-721 and ERC-1155 tokens will be added to the router too.* - -## Methods - -### ERC20Gateway - -```solidity -function ERC20Gateway(address) external view returns (address) -``` - -Mapping from ERC20 token address to corresponding L1ERC20Gateway. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### defaultERC20Gateway - -```solidity -function defaultERC20Gateway() external view returns (address) -``` - -The addess of default ERC20 gateway, normally the L1StandardERC20Gateway contract. - - - - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### depositERC20 - -```solidity -function depositERC20(address _token, uint256 _amount, uint256 _gasLimit) external payable -``` - -Deposit some token to a caller's account on L2. - -*Make this function payable to send relayer fee in Ether.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _token | address | The address of token in L1. | -| _amount | uint256 | The amount of token to transfer. | -| _gasLimit | uint256 | Gas limit required to complete the deposit on L2. | - -### depositERC20 - -```solidity -function depositERC20(address _token, address _to, uint256 _amount, uint256 _gasLimit) external payable -``` - -Deposit some token to a recipient's account on L2. - -*Make this function payable to send relayer fee in Ether.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _token | address | The address of token in L1. | -| _to | address | The address of recipient's account on L2. | -| _amount | uint256 | The amount of token to transfer. | -| _gasLimit | uint256 | Gas limit required to complete the deposit on L2. | - -### depositERC20AndCall - -```solidity -function depositERC20AndCall(address _token, address _to, uint256 _amount, bytes _data, uint256 _gasLimit) external payable -``` - -Deposit some token to a recipient's account on L2 and call. - -*Make this function payable to send relayer fee in Ether.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _token | address | The address of token in L1. | -| _to | address | The address of recipient's account on L2. | -| _amount | uint256 | The amount of token to transfer. | -| _data | bytes | Optional data to forward to recipient's account. | -| _gasLimit | uint256 | Gas limit required to complete the deposit on L2. | - -### depositETH - -```solidity -function depositETH(uint256 _amount, uint256 _gasLimit) external payable -``` - -Deposit ETH to caller's account in L2. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _amount | uint256 | undefined | -| _gasLimit | uint256 | undefined | - -### depositETH - -```solidity -function depositETH(address _to, uint256 _amount, uint256 _gasLimit) external payable -``` - -Deposit ETH to some recipient's account in L2. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _to | address | undefined | -| _amount | uint256 | undefined | -| _gasLimit | uint256 | undefined | - -### depositETHAndCall - -```solidity -function depositETHAndCall(address _to, uint256 _amount, bytes _data, uint256 _gasLimit) external payable -``` - -Deposit ETH to some recipient's account in L2 and call the target contract. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _to | address | undefined | -| _amount | uint256 | undefined | -| _data | bytes | undefined | -| _gasLimit | uint256 | undefined | - -### ethGateway - -```solidity -function ethGateway() external view returns (address) -``` - -The address of L1ETHGateway. - - - - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### finalizeWithdrawERC20 - -```solidity -function finalizeWithdrawERC20(address, address, address, address, uint256, bytes) external payable -``` - -Complete ERC20 withdraw from L2 to L1 and send fund to recipient's account in L1. - -*Make this function payable to handle WETH deposit/withdraw. The function should only be called by L1ScrollMessenger. The function should also only be called by L2ERC20Gateway in L2.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | -| _1 | address | undefined | -| _2 | address | undefined | -| _3 | address | undefined | -| _4 | uint256 | undefined | -| _5 | bytes | undefined | - -### finalizeWithdrawETH - -```solidity -function finalizeWithdrawETH(address, address, uint256, bytes) external payable -``` - -Complete ETH withdraw from L2 to L1 and send fund to recipient's account in L1. - -*This function should only be called by L1ScrollMessenger. This function should also only be called by L1ETHGateway in L2.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | -| _1 | address | undefined | -| _2 | uint256 | undefined | -| _3 | bytes | undefined | - -### gatewayInContext - -```solidity -function gatewayInContext() external view returns (address) -``` - -The address of gateway in current execution context. - - - - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### getERC20Gateway - -```solidity -function getERC20Gateway(address _token) external view returns (address) -``` - -Return the corresponding gateway address for given token address. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _token | address | The address of token to query. | - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### getL2ERC20Address - -```solidity -function getL2ERC20Address(address _l1Address) external view returns (address) -``` - -Return the corresponding l2 token address given l1 token address. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _l1Address | address | undefined | - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### initialize - -```solidity -function initialize(address _ethGateway, address _defaultERC20Gateway) external nonpayable -``` - -Initialize the storage of L1GatewayRouter. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _ethGateway | address | The address of L1ETHGateway contract. | -| _defaultERC20Gateway | address | The address of default ERC20 Gateway contract. | - -### owner - -```solidity -function owner() external view returns (address) -``` - - - -*Returns the address of the current owner.* - - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### renounceOwnership - -```solidity -function renounceOwnership() external nonpayable -``` - - - -*Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner.* - - -### requestERC20 - -```solidity -function requestERC20(address _sender, address _token, uint256 _amount) external nonpayable returns (uint256) -``` - -Request ERC20 token transfer from users to gateways. - -*All the gateways should have reentrancy guard to prevent potential attack though this function.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _sender | address | undefined | -| _token | address | undefined | -| _amount | uint256 | undefined | - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | uint256 | undefined | - -### setDefaultERC20Gateway - -```solidity -function setDefaultERC20Gateway(address _newDefaultERC20Gateway) external nonpayable -``` - -Update the address of default ERC20 gateway contract. - -*This function should only be called by contract owner.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _newDefaultERC20Gateway | address | undefined | - -### setERC20Gateway - -```solidity -function setERC20Gateway(address[] _tokens, address[] _gateways) external nonpayable -``` - -Update the mapping from token address to gateway address. - -*This function should only be called by contract owner.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _tokens | address[] | The list of addresses of tokens to update. | -| _gateways | address[] | The list of addresses of gateways to update. | - -### setETHGateway - -```solidity -function setETHGateway(address _newEthGateway) external nonpayable -``` - -Update the address of ETH gateway contract. - -*This function should only be called by contract owner.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _newEthGateway | address | undefined | - -### transferOwnership - -```solidity -function transferOwnership(address newOwner) external nonpayable -``` - - - -*Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| newOwner | address | undefined | - - - -## Events - -### DepositERC20 - -```solidity -event DepositERC20(address indexed l1Token, address indexed l2Token, address indexed from, address to, uint256 amount, bytes data) -``` - -Emitted when someone deposit ERC20 token from L1 to L2. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| l1Token `indexed` | address | The address of the token in L1. | -| l2Token `indexed` | address | The address of the token in L2. | -| from `indexed` | address | The address of sender in L1. | -| to | address | The address of recipient in L2. | -| amount | uint256 | The amount of token will be deposited from L1 to L2. | -| data | bytes | The optional calldata passed to recipient in L2. | - -### DepositETH - -```solidity -event DepositETH(address indexed from, address indexed to, uint256 amount, bytes data) -``` - -Emitted when someone deposit ETH from L1 to L2. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| from `indexed` | address | The address of sender in L1. | -| to `indexed` | address | The address of recipient in L2. | -| amount | uint256 | The amount of ETH will be deposited from L1 to L2. | -| data | bytes | The optional calldata passed to recipient in L2. | - -### FinalizeWithdrawERC20 - -```solidity -event FinalizeWithdrawERC20(address indexed l1Token, address indexed l2Token, address indexed from, address to, uint256 amount, bytes data) -``` - -Emitted when ERC20 token is withdrawn from L2 to L1 and transfer to recipient. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| l1Token `indexed` | address | The address of the token in L1. | -| l2Token `indexed` | address | The address of the token in L2. | -| from `indexed` | address | The address of sender in L2. | -| to | address | The address of recipient in L1. | -| amount | uint256 | The amount of token withdrawn from L2 to L1. | -| data | bytes | The optional calldata passed to recipient in L1. | - -### FinalizeWithdrawETH - -```solidity -event FinalizeWithdrawETH(address indexed from, address indexed to, uint256 amount, bytes data) -``` - -Emitted when ETH is withdrawn from L2 to L1 and transfer to recipient. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| from `indexed` | address | The address of sender in L2. | -| to `indexed` | address | The address of recipient in L1. | -| amount | uint256 | The amount of ETH withdrawn from L2 to L1. | -| data | bytes | The optional calldata passed to recipient in L1. | - -### Initialized - -```solidity -event Initialized(uint8 version) -``` - - - -*Triggered when the contract has been initialized or reinitialized.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| version | uint8 | undefined | - -### OwnershipTransferred - -```solidity -event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -``` - - - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| previousOwner `indexed` | address | undefined | -| newOwner `indexed` | address | undefined | - -### RefundERC20 - -```solidity -event RefundERC20(address indexed token, address indexed recipient, uint256 amount) -``` - -Emitted when some ERC20 token is refunded. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| token `indexed` | address | The address of the token in L1. | -| recipient `indexed` | address | The address of receiver in L1. | -| amount | uint256 | The amount of token refunded to receiver. | - -### RefundETH - -```solidity -event RefundETH(address indexed recipient, uint256 amount) -``` - -Emitted when some ETH is refunded. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| recipient `indexed` | address | The address of receiver in L1. | -| amount | uint256 | The amount of ETH refunded to receiver. | - -### SetDefaultERC20Gateway - -```solidity -event SetDefaultERC20Gateway(address indexed oldDefaultERC20Gateway, address indexed newDefaultERC20Gateway) -``` - -Emitted when the address of default ERC20 Gateway is updated. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| oldDefaultERC20Gateway `indexed` | address | The address of the old default ERC20 Gateway. | -| newDefaultERC20Gateway `indexed` | address | The address of the new default ERC20 Gateway. | - -### SetERC20Gateway - -```solidity -event SetERC20Gateway(address indexed token, address indexed oldGateway, address indexed newGateway) -``` - -Emitted when the `gateway` for `token` is updated. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| token `indexed` | address | The address of token updated. | -| oldGateway `indexed` | address | The corresponding address of the old gateway. | -| newGateway `indexed` | address | The corresponding address of the new gateway. | - -### SetETHGateway - -```solidity -event SetETHGateway(address indexed oldETHGateway, address indexed newEthGateway) -``` - -Emitted when the address of ETH Gateway is updated. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| oldETHGateway `indexed` | address | The address of the old ETH Gateway. | -| newEthGateway `indexed` | address | The address of the new ETH Gateway. | - - - diff --git a/contracts/docs/apis/L1ScrollMessenger.md b/contracts/docs/apis/L1ScrollMessenger.md deleted file mode 100644 index d31959b59..000000000 --- a/contracts/docs/apis/L1ScrollMessenger.md +++ /dev/null @@ -1,627 +0,0 @@ -# L1ScrollMessenger - - - -> L1ScrollMessenger - -The `L1ScrollMessenger` contract can: 1. send messages from layer 1 to layer 2; 2. relay messages from layer 2 layer 1; 3. replay failed message by replacing the gas limit; 4. drop expired message due to sequencer problems. - -*All deposited Ether (including `WETH` deposited throng `L1WETHGateway`) will locked in this contract.* - -## Methods - -### counterpart - -```solidity -function counterpart() external view returns (address) -``` - -The address of counterpart ScrollMessenger contract in L1/L2. - - - - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### dropMessage - -```solidity -function dropMessage(address _from, address _to, uint256 _value, uint256 _messageNonce, bytes _message) external nonpayable -``` - -Drop a skipped message. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _from | address | undefined | -| _to | address | undefined | -| _value | uint256 | undefined | -| _messageNonce | uint256 | undefined | -| _message | bytes | undefined | - -### feeVault - -```solidity -function feeVault() external view returns (address) -``` - -The address of fee vault, collecting cross domain messaging fee. - - - - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### initialize - -```solidity -function initialize(address _counterpart, address _feeVault, address _rollup, address _messageQueue) external nonpayable -``` - -Initialize the storage of L1ScrollMessenger. - -*The parameters `_counterpart`, `_rollup` and `_messageQueue` are no longer used.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _counterpart | address | The address of L2ScrollMessenger contract in L2. | -| _feeVault | address | The address of fee vault, which will be used to collect relayer fee. | -| _rollup | address | The address of ScrollChain contract. | -| _messageQueue | address | The address of L1MessageQueue contract. | - -### isL1MessageDropped - -```solidity -function isL1MessageDropped(bytes32) external view returns (bool) -``` - -Mapping from L1 message hash to drop status. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _0 | bytes32 | undefined | - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | bool | undefined | - -### isL2MessageExecuted - -```solidity -function isL2MessageExecuted(bytes32) external view returns (bool) -``` - -Mapping from L2 message hash to a boolean value indicating if the message has been successfully executed. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _0 | bytes32 | undefined | - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | bool | undefined | - -### maxReplayTimes - -```solidity -function maxReplayTimes() external view returns (uint256) -``` - -The maximum number of times each L1 message can be replayed. - - - - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | uint256 | undefined | - -### messageQueue - -```solidity -function messageQueue() external view returns (address) -``` - -The address of L1MessageQueue contract. - - - - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### messageSendTimestamp - -```solidity -function messageSendTimestamp(bytes32) external view returns (uint256) -``` - -Mapping from L1 message hash to the timestamp when the message is sent. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _0 | bytes32 | undefined | - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | uint256 | undefined | - -### owner - -```solidity -function owner() external view returns (address) -``` - - - -*Returns the address of the current owner.* - - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### paused - -```solidity -function paused() external view returns (bool) -``` - - - -*Returns true if the contract is paused, and false otherwise.* - - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | bool | undefined | - -### prevReplayIndex - -```solidity -function prevReplayIndex(uint256) external view returns (uint256) -``` - -Mapping from queue index to previous replay queue index. - -*If a message `x` was replayed 3 times with index `q1`, `q2` and `q3`, the value of `prevReplayIndex` and `replayStates` will be `replayStates[hash(x)].lastIndex = q3`, `replayStates[hash(x)].times = 3`, `prevReplayIndex[q3] = q2`, `prevReplayIndex[q2] = q1`, `prevReplayIndex[q1] = x` and `prevReplayIndex[x]=nil`.The index `x` that `prevReplayIndex[x]=nil` is used as the termination of the list. Usually we use `0` to represent `nil`, but we cannot distinguish it with the first message with index zero. So a nonzero offset `1` is added to the value of `prevReplayIndex[x]` to avoid such situation.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _0 | uint256 | undefined | - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | uint256 | undefined | - -### relayMessageWithProof - -```solidity -function relayMessageWithProof(address _from, address _to, uint256 _value, uint256 _nonce, bytes _message, IL1ScrollMessenger.L2MessageProof _proof) external nonpayable -``` - - - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _from | address | undefined | -| _to | address | undefined | -| _value | uint256 | undefined | -| _nonce | uint256 | undefined | -| _message | bytes | undefined | -| _proof | IL1ScrollMessenger.L2MessageProof | undefined | - -### renounceOwnership - -```solidity -function renounceOwnership() external nonpayable -``` - - - -*Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner.* - - -### replayMessage - -```solidity -function replayMessage(address _from, address _to, uint256 _value, uint256 _messageNonce, bytes _message, uint32 _newGasLimit, address _refundAddress) external payable -``` - -Replay an existing message. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _from | address | undefined | -| _to | address | undefined | -| _value | uint256 | undefined | -| _messageNonce | uint256 | undefined | -| _message | bytes | undefined | -| _newGasLimit | uint32 | undefined | -| _refundAddress | address | undefined | - -### replayStates - -```solidity -function replayStates(bytes32) external view returns (uint128 times, uint128 lastIndex) -``` - -Mapping from L1 message hash to replay state. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _0 | bytes32 | undefined | - -#### Returns - -| Name | Type | Description | -|---|---|---| -| times | uint128 | undefined | -| lastIndex | uint128 | undefined | - -### rollup - -```solidity -function rollup() external view returns (address) -``` - -The address of Rollup contract. - - - - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### sendMessage - -```solidity -function sendMessage(address _to, uint256 _value, bytes _message, uint256 _gasLimit, address _refundAddress) external payable -``` - -Send cross chain message from L1 to L2 or L2 to L1. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _to | address | undefined | -| _value | uint256 | undefined | -| _message | bytes | undefined | -| _gasLimit | uint256 | undefined | -| _refundAddress | address | undefined | - -### sendMessage - -```solidity -function sendMessage(address _to, uint256 _value, bytes _message, uint256 _gasLimit) external payable -``` - -Send cross chain message from L1 to L2 or L2 to L1. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _to | address | undefined | -| _value | uint256 | undefined | -| _message | bytes | undefined | -| _gasLimit | uint256 | undefined | - -### setPause - -```solidity -function setPause(bool _status) external nonpayable -``` - -Pause the contract - -*This function can only called by contract owner.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _status | bool | The pause status to update. | - -### transferOwnership - -```solidity -function transferOwnership(address newOwner) external nonpayable -``` - - - -*Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| newOwner | address | undefined | - -### updateFeeVault - -```solidity -function updateFeeVault(address _newFeeVault) external nonpayable -``` - -Update fee vault contract. - -*This function can only called by contract owner.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _newFeeVault | address | The address of new fee vault contract. | - -### updateMaxReplayTimes - -```solidity -function updateMaxReplayTimes(uint256 _newMaxReplayTimes) external nonpayable -``` - -Update max replay times. - -*This function can only called by contract owner.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _newMaxReplayTimes | uint256 | The new max replay times. | - -### xDomainMessageSender - -```solidity -function xDomainMessageSender() external view returns (address) -``` - -See {IScrollMessenger-xDomainMessageSender} - - - - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - - - -## Events - -### FailedRelayedMessage - -```solidity -event FailedRelayedMessage(bytes32 indexed messageHash) -``` - -Emitted when a cross domain message is failed to relay. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| messageHash `indexed` | bytes32 | The hash of the message. | - -### Initialized - -```solidity -event Initialized(uint8 version) -``` - - - -*Triggered when the contract has been initialized or reinitialized.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| version | uint8 | undefined | - -### OwnershipTransferred - -```solidity -event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -``` - - - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| previousOwner `indexed` | address | undefined | -| newOwner `indexed` | address | undefined | - -### Paused - -```solidity -event Paused(address account) -``` - - - -*Emitted when the pause is triggered by `account`.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| account | address | undefined | - -### RelayedMessage - -```solidity -event RelayedMessage(bytes32 indexed messageHash) -``` - -Emitted when a cross domain message is relayed successfully. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| messageHash `indexed` | bytes32 | The hash of the message. | - -### SentMessage - -```solidity -event SentMessage(address indexed sender, address indexed target, uint256 value, uint256 messageNonce, uint256 gasLimit, bytes message) -``` - -Emitted when a cross domain message is sent. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| sender `indexed` | address | The address of the sender who initiates the message. | -| target `indexed` | address | The address of target contract to call. | -| value | uint256 | The amount of value passed to the target contract. | -| messageNonce | uint256 | The nonce of the message. | -| gasLimit | uint256 | The optional gas limit passed to L1 or L2. | -| message | bytes | The calldata passed to the target contract. | - -### Unpaused - -```solidity -event Unpaused(address account) -``` - - - -*Emitted when the pause is lifted by `account`.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| account | address | undefined | - -### UpdateFeeVault - -```solidity -event UpdateFeeVault(address _oldFeeVault, address _newFeeVault) -``` - -Emitted when owner updates fee vault contract. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _oldFeeVault | address | The address of old fee vault contract. | -| _newFeeVault | address | The address of new fee vault contract. | - -### UpdateMaxReplayTimes - -```solidity -event UpdateMaxReplayTimes(uint256 oldMaxReplayTimes, uint256 newMaxReplayTimes) -``` - -Emitted when the maximum number of times each message can be replayed is updated. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| oldMaxReplayTimes | uint256 | The old maximum number of times each message can be replayed. | -| newMaxReplayTimes | uint256 | The new maximum number of times each message can be replayed. | - - - -## Errors - -### ErrorZeroAddress - -```solidity -error ErrorZeroAddress() -``` - - - -*Thrown when the given address is `address(0)`.* - - - diff --git a/contracts/docs/apis/L1StandardERC20Gateway.md b/contracts/docs/apis/L1StandardERC20Gateway.md deleted file mode 100644 index 3cf8ade86..000000000 --- a/contracts/docs/apis/L1StandardERC20Gateway.md +++ /dev/null @@ -1,423 +0,0 @@ -# L1StandardERC20Gateway - - - -> L1StandardERC20Gateway - -The `L1StandardERC20Gateway` is used to deposit standard ERC20 tokens on layer 1 and finalize withdraw the tokens from layer 2. - -*The deposited ERC20 tokens are held in this gateway. On finalizing withdraw, the corresponding token will be transfer to the recipient directly. Any ERC20 that requires non-standard functionality should use a separate gateway.* - -## Methods - -### counterpart - -```solidity -function counterpart() external view returns (address) -``` - -The address of corresponding L1/L2 Gateway contract. - - - - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### depositERC20 - -```solidity -function depositERC20(address _token, uint256 _amount, uint256 _gasLimit) external payable -``` - -Deposit some token to a caller's account on L2. - -*Make this function payable to send relayer fee in Ether.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _token | address | The address of token in L1. | -| _amount | uint256 | The amount of token to transfer. | -| _gasLimit | uint256 | Gas limit required to complete the deposit on L2. | - -### depositERC20 - -```solidity -function depositERC20(address _token, address _to, uint256 _amount, uint256 _gasLimit) external payable -``` - -Deposit some token to a recipient's account on L2. - -*Make this function payable to send relayer fee in Ether.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _token | address | The address of token in L1. | -| _to | address | The address of recipient's account on L2. | -| _amount | uint256 | The amount of token to transfer. | -| _gasLimit | uint256 | Gas limit required to complete the deposit on L2. | - -### depositERC20AndCall - -```solidity -function depositERC20AndCall(address _token, address _to, uint256 _amount, bytes _data, uint256 _gasLimit) external payable -``` - -Deposit some token to a recipient's account on L2 and call. - -*Make this function payable to send relayer fee in Ether.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _token | address | The address of token in L1. | -| _to | address | The address of recipient's account on L2. | -| _amount | uint256 | The amount of token to transfer. | -| _data | bytes | Optional data to forward to recipient's account. | -| _gasLimit | uint256 | Gas limit required to complete the deposit on L2. | - -### finalizeWithdrawERC20 - -```solidity -function finalizeWithdrawERC20(address _l1Token, address _l2Token, address _from, address _to, uint256 _amount, bytes _data) external payable -``` - -Complete ERC20 withdraw from L2 to L1 and send fund to recipient's account in L1. - -*Make this function payable to handle WETH deposit/withdraw. The function should only be called by L1ScrollMessenger. The function should also only be called by L2ERC20Gateway in L2.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _l1Token | address | The address of corresponding L1 token. | -| _l2Token | address | The address of corresponding L2 token. | -| _from | address | The address of account who withdraw the token in L2. | -| _to | address | The address of recipient in L1 to receive the token. | -| _amount | uint256 | The amount of the token to withdraw. | -| _data | bytes | Optional data to forward to recipient's account. | - -### getL2ERC20Address - -```solidity -function getL2ERC20Address(address _l1Token) external view returns (address) -``` - -Return the corresponding l2 token address given l1 token address. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _l1Token | address | The address of l1 token. | - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### initialize - -```solidity -function initialize(address _counterpart, address _router, address _messenger, address, address) external nonpayable -``` - -Initialize the storage of L1StandardERC20Gateway. - -*The parameters `_counterpart`, `_router`, `_messenger`, `_l2TokenImplementation` and `_l2TokenFactory` are no longer used.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _counterpart | address | The address of L2StandardERC20Gateway in L2. | -| _router | address | The address of L1GatewayRouter in L1. | -| _messenger | address | The address of L1ScrollMessenger in L1. | -| _3 | address | undefined | -| _4 | address | undefined | - -### l2TokenFactory - -```solidity -function l2TokenFactory() external view returns (address) -``` - -The address of ScrollStandardERC20Factory contract in L2. - - - - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### l2TokenImplementation - -```solidity -function l2TokenImplementation() external view returns (address) -``` - -The address of ScrollStandardERC20 implementation in L2. - - - - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### messenger - -```solidity -function messenger() external view returns (address) -``` - -The address of corresponding L1ScrollMessenger/L2ScrollMessenger contract. - - - - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### onDropMessage - -```solidity -function onDropMessage(bytes _message) external payable -``` - - - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _message | bytes | undefined | - -### owner - -```solidity -function owner() external view returns (address) -``` - - - -*Returns the address of the current owner.* - - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### renounceOwnership - -```solidity -function renounceOwnership() external nonpayable -``` - - - -*Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner.* - - -### router - -```solidity -function router() external view returns (address) -``` - -The address of L1GatewayRouter/L2GatewayRouter contract. - - - - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### transferOwnership - -```solidity -function transferOwnership(address newOwner) external nonpayable -``` - - - -*Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| newOwner | address | undefined | - - - -## Events - -### DepositERC20 - -```solidity -event DepositERC20(address indexed l1Token, address indexed l2Token, address indexed from, address to, uint256 amount, bytes data) -``` - -Emitted when someone deposit ERC20 token from L1 to L2. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| l1Token `indexed` | address | The address of the token in L1. | -| l2Token `indexed` | address | The address of the token in L2. | -| from `indexed` | address | The address of sender in L1. | -| to | address | The address of recipient in L2. | -| amount | uint256 | The amount of token will be deposited from L1 to L2. | -| data | bytes | The optional calldata passed to recipient in L2. | - -### FinalizeWithdrawERC20 - -```solidity -event FinalizeWithdrawERC20(address indexed l1Token, address indexed l2Token, address indexed from, address to, uint256 amount, bytes data) -``` - -Emitted when ERC20 token is withdrawn from L2 to L1 and transfer to recipient. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| l1Token `indexed` | address | The address of the token in L1. | -| l2Token `indexed` | address | The address of the token in L2. | -| from `indexed` | address | The address of sender in L2. | -| to | address | The address of recipient in L1. | -| amount | uint256 | The amount of token withdrawn from L2 to L1. | -| data | bytes | The optional calldata passed to recipient in L1. | - -### Initialized - -```solidity -event Initialized(uint8 version) -``` - - - -*Triggered when the contract has been initialized or reinitialized.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| version | uint8 | undefined | - -### OwnershipTransferred - -```solidity -event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -``` - - - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| previousOwner `indexed` | address | undefined | -| newOwner `indexed` | address | undefined | - -### RefundERC20 - -```solidity -event RefundERC20(address indexed token, address indexed recipient, uint256 amount) -``` - -Emitted when some ERC20 token is refunded. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| token `indexed` | address | The address of the token in L1. | -| recipient `indexed` | address | The address of receiver in L1. | -| amount | uint256 | The amount of token refunded to receiver. | - - - -## Errors - -### ErrorCallerIsNotCounterpartGateway - -```solidity -error ErrorCallerIsNotCounterpartGateway() -``` - - - -*Thrown when the cross chain sender is not the counterpart gateway contract.* - - -### ErrorCallerIsNotMessenger - -```solidity -error ErrorCallerIsNotMessenger() -``` - - - -*Thrown when the caller is not corresponding `L1ScrollMessenger` or `L2ScrollMessenger`.* - - -### ErrorNotInDropMessageContext - -```solidity -error ErrorNotInDropMessageContext() -``` - - - -*Thrown when ScrollMessenger is not dropping message.* - - -### ErrorZeroAddress - -```solidity -error ErrorZeroAddress() -``` - - - -*Thrown when the given address is `address(0)`.* - - - diff --git a/contracts/docs/apis/L1WETHGateway.md b/contracts/docs/apis/L1WETHGateway.md deleted file mode 100644 index 141a2e9ef..000000000 --- a/contracts/docs/apis/L1WETHGateway.md +++ /dev/null @@ -1,421 +0,0 @@ -# L1WETHGateway - - - -> L1WETHGateway - -The `L1WETHGateway` contract is used to deposit `WETH` token on layer 1 and finalize withdraw `WETH` from layer 2. - -*The deposited WETH tokens are not held in the gateway. It will first be unwrapped as Ether and then the Ether will be sent to the `L1ScrollMessenger` contract. On finalizing withdraw, the Ether will be transferred from `L1ScrollMessenger`, then wrapped as WETH and finally transfer to recipient.* - -## Methods - -### WETH - -```solidity -function WETH() external view returns (address) -``` - -The address of L1 WETH address. - - - - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### counterpart - -```solidity -function counterpart() external view returns (address) -``` - -The address of corresponding L1/L2 Gateway contract. - - - - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### depositERC20 - -```solidity -function depositERC20(address _token, uint256 _amount, uint256 _gasLimit) external payable -``` - -Deposit some token to a caller's account on L2. - -*Make this function payable to send relayer fee in Ether.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _token | address | The address of token in L1. | -| _amount | uint256 | The amount of token to transfer. | -| _gasLimit | uint256 | Gas limit required to complete the deposit on L2. | - -### depositERC20 - -```solidity -function depositERC20(address _token, address _to, uint256 _amount, uint256 _gasLimit) external payable -``` - -Deposit some token to a recipient's account on L2. - -*Make this function payable to send relayer fee in Ether.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _token | address | The address of token in L1. | -| _to | address | The address of recipient's account on L2. | -| _amount | uint256 | The amount of token to transfer. | -| _gasLimit | uint256 | Gas limit required to complete the deposit on L2. | - -### depositERC20AndCall - -```solidity -function depositERC20AndCall(address _token, address _to, uint256 _amount, bytes _data, uint256 _gasLimit) external payable -``` - -Deposit some token to a recipient's account on L2 and call. - -*Make this function payable to send relayer fee in Ether.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _token | address | The address of token in L1. | -| _to | address | The address of recipient's account on L2. | -| _amount | uint256 | The amount of token to transfer. | -| _data | bytes | Optional data to forward to recipient's account. | -| _gasLimit | uint256 | Gas limit required to complete the deposit on L2. | - -### finalizeWithdrawERC20 - -```solidity -function finalizeWithdrawERC20(address _l1Token, address _l2Token, address _from, address _to, uint256 _amount, bytes _data) external payable -``` - -Complete ERC20 withdraw from L2 to L1 and send fund to recipient's account in L1. - -*Make this function payable to handle WETH deposit/withdraw. The function should only be called by L1ScrollMessenger. The function should also only be called by L2ERC20Gateway in L2.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _l1Token | address | The address of corresponding L1 token. | -| _l2Token | address | The address of corresponding L2 token. | -| _from | address | The address of account who withdraw the token in L2. | -| _to | address | The address of recipient in L1 to receive the token. | -| _amount | uint256 | The amount of the token to withdraw. | -| _data | bytes | Optional data to forward to recipient's account. | - -### getL2ERC20Address - -```solidity -function getL2ERC20Address(address) external view returns (address) -``` - -Return the corresponding l2 token address given l1 token address. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### initialize - -```solidity -function initialize(address _counterpart, address _router, address _messenger) external nonpayable -``` - -Initialize the storage of L1WETHGateway. - -*The parameters `_counterpart`, `_router` and `_messenger` are no longer used.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _counterpart | address | The address of L2ETHGateway in L2. | -| _router | address | The address of L1GatewayRouter in L1. | -| _messenger | address | The address of L1ScrollMessenger in L1. | - -### l2WETH - -```solidity -function l2WETH() external view returns (address) -``` - -The address of L2 WETH address. - - - - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### messenger - -```solidity -function messenger() external view returns (address) -``` - -The address of corresponding L1ScrollMessenger/L2ScrollMessenger contract. - - - - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### onDropMessage - -```solidity -function onDropMessage(bytes _message) external payable -``` - - - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _message | bytes | undefined | - -### owner - -```solidity -function owner() external view returns (address) -``` - - - -*Returns the address of the current owner.* - - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### renounceOwnership - -```solidity -function renounceOwnership() external nonpayable -``` - - - -*Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner.* - - -### router - -```solidity -function router() external view returns (address) -``` - -The address of L1GatewayRouter/L2GatewayRouter contract. - - - - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### transferOwnership - -```solidity -function transferOwnership(address newOwner) external nonpayable -``` - - - -*Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| newOwner | address | undefined | - - - -## Events - -### DepositERC20 - -```solidity -event DepositERC20(address indexed l1Token, address indexed l2Token, address indexed from, address to, uint256 amount, bytes data) -``` - -Emitted when someone deposit ERC20 token from L1 to L2. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| l1Token `indexed` | address | The address of the token in L1. | -| l2Token `indexed` | address | The address of the token in L2. | -| from `indexed` | address | The address of sender in L1. | -| to | address | The address of recipient in L2. | -| amount | uint256 | The amount of token will be deposited from L1 to L2. | -| data | bytes | The optional calldata passed to recipient in L2. | - -### FinalizeWithdrawERC20 - -```solidity -event FinalizeWithdrawERC20(address indexed l1Token, address indexed l2Token, address indexed from, address to, uint256 amount, bytes data) -``` - -Emitted when ERC20 token is withdrawn from L2 to L1 and transfer to recipient. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| l1Token `indexed` | address | The address of the token in L1. | -| l2Token `indexed` | address | The address of the token in L2. | -| from `indexed` | address | The address of sender in L2. | -| to | address | The address of recipient in L1. | -| amount | uint256 | The amount of token withdrawn from L2 to L1. | -| data | bytes | The optional calldata passed to recipient in L1. | - -### Initialized - -```solidity -event Initialized(uint8 version) -``` - - - -*Triggered when the contract has been initialized or reinitialized.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| version | uint8 | undefined | - -### OwnershipTransferred - -```solidity -event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -``` - - - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| previousOwner `indexed` | address | undefined | -| newOwner `indexed` | address | undefined | - -### RefundERC20 - -```solidity -event RefundERC20(address indexed token, address indexed recipient, uint256 amount) -``` - -Emitted when some ERC20 token is refunded. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| token `indexed` | address | The address of the token in L1. | -| recipient `indexed` | address | The address of receiver in L1. | -| amount | uint256 | The amount of token refunded to receiver. | - - - -## Errors - -### ErrorCallerIsNotCounterpartGateway - -```solidity -error ErrorCallerIsNotCounterpartGateway() -``` - - - -*Thrown when the cross chain sender is not the counterpart gateway contract.* - - -### ErrorCallerIsNotMessenger - -```solidity -error ErrorCallerIsNotMessenger() -``` - - - -*Thrown when the caller is not corresponding `L1ScrollMessenger` or `L2ScrollMessenger`.* - - -### ErrorNotInDropMessageContext - -```solidity -error ErrorNotInDropMessageContext() -``` - - - -*Thrown when ScrollMessenger is not dropping message.* - - -### ErrorZeroAddress - -```solidity -error ErrorZeroAddress() -``` - - - -*Thrown when the given address is `address(0)`.* - - - diff --git a/contracts/docs/apis/L2ERC1155Gateway.md b/contracts/docs/apis/L2ERC1155Gateway.md deleted file mode 100644 index d4565aad0..000000000 --- a/contracts/docs/apis/L2ERC1155Gateway.md +++ /dev/null @@ -1,545 +0,0 @@ -# L2ERC1155Gateway - - - -> L2ERC1155Gateway - -The `L2ERC1155Gateway` is used to withdraw ERC1155 compatible NFTs on layer 2 and finalize deposit the NFTs from layer 1. - -*The withdrawn NFTs tokens will be burned directly. On finalizing deposit, the corresponding NFT will be minted and transferred to the recipient. This will be changed if we have more specific scenarios.* - -## Methods - -### batchWithdrawERC1155 - -```solidity -function batchWithdrawERC1155(address _token, uint256[] _tokenIds, uint256[] _amounts, uint256 _gasLimit) external payable -``` - -Batch withdraw a list of ERC1155 NFT to caller's account on layer 1. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _token | address | undefined | -| _tokenIds | uint256[] | undefined | -| _amounts | uint256[] | undefined | -| _gasLimit | uint256 | undefined | - -### batchWithdrawERC1155 - -```solidity -function batchWithdrawERC1155(address _token, address _to, uint256[] _tokenIds, uint256[] _amounts, uint256 _gasLimit) external payable -``` - -Batch withdraw a list of ERC1155 NFT to caller's account on layer 1. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _token | address | undefined | -| _to | address | undefined | -| _tokenIds | uint256[] | undefined | -| _amounts | uint256[] | undefined | -| _gasLimit | uint256 | undefined | - -### counterpart - -```solidity -function counterpart() external view returns (address) -``` - -The address of corresponding L1/L2 Gateway contract. - - - - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### finalizeBatchDepositERC1155 - -```solidity -function finalizeBatchDepositERC1155(address _l1Token, address _l2Token, address _from, address _to, uint256[] _tokenIds, uint256[] _amounts) external nonpayable -``` - -Complete ERC1155 deposit from layer 1 to layer 2 and send NFT to recipient's account on layer 2. - -*Requirements: - The function should only be called by L2ScrollMessenger. - The function should also only be called by L1ERC1155Gateway on layer 1.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _l1Token | address | undefined | -| _l2Token | address | undefined | -| _from | address | undefined | -| _to | address | undefined | -| _tokenIds | uint256[] | undefined | -| _amounts | uint256[] | undefined | - -### finalizeDepositERC1155 - -```solidity -function finalizeDepositERC1155(address _l1Token, address _l2Token, address _from, address _to, uint256 _tokenId, uint256 _amount) external nonpayable -``` - -Complete ERC1155 deposit from layer 1 to layer 2 and send NFT to recipient's account on layer 2. - -*Requirements: - The function should only be called by L2ScrollMessenger. - The function should also only be called by L1ERC1155Gateway on layer 1.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _l1Token | address | undefined | -| _l2Token | address | undefined | -| _from | address | undefined | -| _to | address | undefined | -| _tokenId | uint256 | undefined | -| _amount | uint256 | undefined | - -### initialize - -```solidity -function initialize(address _counterpart, address _messenger) external nonpayable -``` - -Initialize the storage of `L2ERC1155Gateway`. - -*The parameters `_counterpart` and `_messenger` are no longer used.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _counterpart | address | The address of `L1ERC1155Gateway` contract in L1. | -| _messenger | address | The address of `L2ScrollMessenger` contract in L2. | - -### messenger - -```solidity -function messenger() external view returns (address) -``` - -The address of corresponding L1ScrollMessenger/L2ScrollMessenger contract. - - - - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### onERC1155BatchReceived - -```solidity -function onERC1155BatchReceived(address, address, uint256[], uint256[], bytes) external nonpayable returns (bytes4) -``` - - - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | -| _1 | address | undefined | -| _2 | uint256[] | undefined | -| _3 | uint256[] | undefined | -| _4 | bytes | undefined | - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | bytes4 | undefined | - -### onERC1155Received - -```solidity -function onERC1155Received(address, address, uint256, uint256, bytes) external nonpayable returns (bytes4) -``` - - - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | -| _1 | address | undefined | -| _2 | uint256 | undefined | -| _3 | uint256 | undefined | -| _4 | bytes | undefined | - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | bytes4 | undefined | - -### owner - -```solidity -function owner() external view returns (address) -``` - - - -*Returns the address of the current owner.* - - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### renounceOwnership - -```solidity -function renounceOwnership() external nonpayable -``` - - - -*Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner.* - - -### router - -```solidity -function router() external view returns (address) -``` - -The address of L1GatewayRouter/L2GatewayRouter contract. - - - - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### supportsInterface - -```solidity -function supportsInterface(bytes4 interfaceId) external view returns (bool) -``` - - - -*See {IERC165-supportsInterface}.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| interfaceId | bytes4 | undefined | - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | bool | undefined | - -### tokenMapping - -```solidity -function tokenMapping(address) external view returns (address) -``` - -Mapping from layer 2 token address to layer 1 token address for ERC1155 NFT. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### transferOwnership - -```solidity -function transferOwnership(address newOwner) external nonpayable -``` - - - -*Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| newOwner | address | undefined | - -### updateTokenMapping - -```solidity -function updateTokenMapping(address _l2Token, address _l1Token) external nonpayable -``` - -Update layer 2 to layer 1 token mapping. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _l2Token | address | The address of corresponding ERC1155 token on layer 2. | -| _l1Token | address | The address of ERC1155 token on layer 1. | - -### withdrawERC1155 - -```solidity -function withdrawERC1155(address _token, uint256 _tokenId, uint256 _amount, uint256 _gasLimit) external payable -``` - -Withdraw some ERC1155 NFT to caller's account on layer 1. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _token | address | undefined | -| _tokenId | uint256 | undefined | -| _amount | uint256 | undefined | -| _gasLimit | uint256 | undefined | - -### withdrawERC1155 - -```solidity -function withdrawERC1155(address _token, address _to, uint256 _tokenId, uint256 _amount, uint256 _gasLimit) external payable -``` - -Withdraw some ERC1155 NFT to caller's account on layer 1. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _token | address | undefined | -| _to | address | undefined | -| _tokenId | uint256 | undefined | -| _amount | uint256 | undefined | -| _gasLimit | uint256 | undefined | - - - -## Events - -### BatchWithdrawERC1155 - -```solidity -event BatchWithdrawERC1155(address indexed l1Token, address indexed l2Token, address indexed from, address to, uint256[] tokenIds, uint256[] amounts) -``` - -Emitted when the ERC1155 NFT is batch transferred to gateway on layer 2. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| l1Token `indexed` | address | The address of ERC1155 NFT on layer 1. | -| l2Token `indexed` | address | The address of ERC1155 NFT on layer 2. | -| from `indexed` | address | The address of sender on layer 2. | -| to | address | The address of recipient on layer 1. | -| tokenIds | uint256[] | The list of token ids of the ERC1155 NFT to withdraw on layer 2. | -| amounts | uint256[] | The list of corresponding amounts to withdraw. | - -### FinalizeBatchDepositERC1155 - -```solidity -event FinalizeBatchDepositERC1155(address indexed l1Token, address indexed l2Token, address indexed from, address to, uint256[] tokenIds, uint256[] amounts) -``` - -Emitted when the ERC1155 NFT is batch transferred to recipient on layer 2. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| l1Token `indexed` | address | The address of ERC1155 NFT on layer 1. | -| l2Token `indexed` | address | The address of ERC1155 NFT on layer 2. | -| from `indexed` | address | The address of sender on layer 1. | -| to | address | The address of recipient on layer 2. | -| tokenIds | uint256[] | The list of token ids of the ERC1155 NFT deposited on layer 1. | -| amounts | uint256[] | The list of corresponding amounts deposited. | - -### FinalizeDepositERC1155 - -```solidity -event FinalizeDepositERC1155(address indexed l1Token, address indexed l2Token, address indexed from, address to, uint256 tokenId, uint256 amount) -``` - -Emitted when the ERC1155 NFT is transferred to recipient on layer 2. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| l1Token `indexed` | address | The address of ERC1155 NFT on layer 1. | -| l2Token `indexed` | address | The address of ERC1155 NFT on layer 2. | -| from `indexed` | address | The address of sender on layer 1. | -| to | address | The address of recipient on layer 2. | -| tokenId | uint256 | The token id of the ERC1155 NFT deposited on layer 1. | -| amount | uint256 | The amount of token deposited. | - -### Initialized - -```solidity -event Initialized(uint8 version) -``` - - - -*Triggered when the contract has been initialized or reinitialized.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| version | uint8 | undefined | - -### OwnershipTransferred - -```solidity -event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -``` - - - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| previousOwner `indexed` | address | undefined | -| newOwner `indexed` | address | undefined | - -### UpdateTokenMapping - -```solidity -event UpdateTokenMapping(address indexed l2Token, address indexed oldL1Token, address indexed newL1Token) -``` - -Emitted when token mapping for ERC1155 token is updated. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| l2Token `indexed` | address | The address of corresponding ERC1155 token in layer 2. | -| oldL1Token `indexed` | address | The address of the old corresponding ERC1155 token in layer 1. | -| newL1Token `indexed` | address | The address of the new corresponding ERC1155 token in layer 1. | - -### WithdrawERC1155 - -```solidity -event WithdrawERC1155(address indexed l1Token, address indexed l2Token, address indexed from, address to, uint256 tokenId, uint256 amount) -``` - -Emitted when the ERC1155 NFT is transferred to gateway on layer 2. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| l1Token `indexed` | address | The address of ERC1155 NFT on layer 1. | -| l2Token `indexed` | address | The address of ERC1155 NFT on layer 2. | -| from `indexed` | address | The address of sender on layer 2. | -| to | address | The address of recipient on layer 1. | -| tokenId | uint256 | The token id of the ERC1155 NFT to withdraw on layer 2. | -| amount | uint256 | The amount of token to withdraw. | - - - -## Errors - -### ErrorCallerIsNotCounterpartGateway - -```solidity -error ErrorCallerIsNotCounterpartGateway() -``` - - - -*Thrown when the cross chain sender is not the counterpart gateway contract.* - - -### ErrorCallerIsNotMessenger - -```solidity -error ErrorCallerIsNotMessenger() -``` - - - -*Thrown when the caller is not corresponding `L1ScrollMessenger` or `L2ScrollMessenger`.* - - -### ErrorNotInDropMessageContext - -```solidity -error ErrorNotInDropMessageContext() -``` - - - -*Thrown when ScrollMessenger is not dropping message.* - - -### ErrorZeroAddress - -```solidity -error ErrorZeroAddress() -``` - - - -*Thrown when the given address is `address(0)`.* - - - diff --git a/contracts/docs/apis/L2ERC721Gateway.md b/contracts/docs/apis/L2ERC721Gateway.md deleted file mode 100644 index d615a16a4..000000000 --- a/contracts/docs/apis/L2ERC721Gateway.md +++ /dev/null @@ -1,486 +0,0 @@ -# L2ERC721Gateway - - - -> L2ERC721Gateway - -The `L2ERC721Gateway` is used to withdraw ERC721 compatible NFTs on layer 2 and finalize deposit the NFTs from layer 1. - -*The withdrawn NFTs tokens will be burned directly. On finalizing deposit, the corresponding NFT will be minted and transferred to the recipient. This will be changed if we have more specific scenarios.* - -## Methods - -### batchWithdrawERC721 - -```solidity -function batchWithdrawERC721(address _token, uint256[] _tokenIds, uint256 _gasLimit) external payable -``` - -Batch withdraw a list of ERC721 NFT to caller's account on layer 1. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _token | address | undefined | -| _tokenIds | uint256[] | undefined | -| _gasLimit | uint256 | undefined | - -### batchWithdrawERC721 - -```solidity -function batchWithdrawERC721(address _token, address _to, uint256[] _tokenIds, uint256 _gasLimit) external payable -``` - -Batch withdraw a list of ERC721 NFT to caller's account on layer 1. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _token | address | undefined | -| _to | address | undefined | -| _tokenIds | uint256[] | undefined | -| _gasLimit | uint256 | undefined | - -### counterpart - -```solidity -function counterpart() external view returns (address) -``` - -The address of corresponding L1/L2 Gateway contract. - - - - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### finalizeBatchDepositERC721 - -```solidity -function finalizeBatchDepositERC721(address _l1Token, address _l2Token, address _from, address _to, uint256[] _tokenIds) external nonpayable -``` - -Complete ERC721 deposit from layer 1 to layer 2 and send NFT to recipient's account on layer 2. - -*Requirements: - The function should only be called by L2ScrollMessenger. - The function should also only be called by L1ERC721Gateway on layer 1.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _l1Token | address | undefined | -| _l2Token | address | undefined | -| _from | address | undefined | -| _to | address | undefined | -| _tokenIds | uint256[] | undefined | - -### finalizeDepositERC721 - -```solidity -function finalizeDepositERC721(address _l1Token, address _l2Token, address _from, address _to, uint256 _tokenId) external nonpayable -``` - -Complete ERC721 deposit from layer 1 to layer 2 and send NFT to recipient's account on layer 2. - -*Requirements: - The function should only be called by L2ScrollMessenger. - The function should also only be called by L1ERC721Gateway on layer 1.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _l1Token | address | undefined | -| _l2Token | address | undefined | -| _from | address | undefined | -| _to | address | undefined | -| _tokenId | uint256 | undefined | - -### initialize - -```solidity -function initialize(address _counterpart, address _messenger) external nonpayable -``` - -Initialize the storage of `L2ERC721Gateway`. - -*The parameters `_counterpart` and `_messenger` are no longer used.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _counterpart | address | The address of `L1ERC721Gateway` contract in L1. | -| _messenger | address | The address of `L2ScrollMessenger` contract in L2. | - -### messenger - -```solidity -function messenger() external view returns (address) -``` - -The address of corresponding L1ScrollMessenger/L2ScrollMessenger contract. - - - - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### onERC721Received - -```solidity -function onERC721Received(address, address, uint256, bytes) external nonpayable returns (bytes4) -``` - - - -*See {IERC721Receiver-onERC721Received}. Always returns `IERC721Receiver.onERC721Received.selector`.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | -| _1 | address | undefined | -| _2 | uint256 | undefined | -| _3 | bytes | undefined | - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | bytes4 | undefined | - -### owner - -```solidity -function owner() external view returns (address) -``` - - - -*Returns the address of the current owner.* - - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### renounceOwnership - -```solidity -function renounceOwnership() external nonpayable -``` - - - -*Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner.* - - -### router - -```solidity -function router() external view returns (address) -``` - -The address of L1GatewayRouter/L2GatewayRouter contract. - - - - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### tokenMapping - -```solidity -function tokenMapping(address) external view returns (address) -``` - -Mapping from layer 2 token address to layer 1 token address for ERC721 NFT. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### transferOwnership - -```solidity -function transferOwnership(address newOwner) external nonpayable -``` - - - -*Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| newOwner | address | undefined | - -### updateTokenMapping - -```solidity -function updateTokenMapping(address _l2Token, address _l1Token) external nonpayable -``` - -Update layer 2 to layer 1 token mapping. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _l2Token | address | The address of corresponding ERC721 token on layer 2. | -| _l1Token | address | The address of ERC721 token on layer 1. | - -### withdrawERC721 - -```solidity -function withdrawERC721(address _token, uint256 _tokenId, uint256 _gasLimit) external payable -``` - -Withdraw some ERC721 NFT to caller's account on layer 1. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _token | address | undefined | -| _tokenId | uint256 | undefined | -| _gasLimit | uint256 | undefined | - -### withdrawERC721 - -```solidity -function withdrawERC721(address _token, address _to, uint256 _tokenId, uint256 _gasLimit) external payable -``` - -Withdraw some ERC721 NFT to caller's account on layer 1. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _token | address | undefined | -| _to | address | undefined | -| _tokenId | uint256 | undefined | -| _gasLimit | uint256 | undefined | - - - -## Events - -### BatchWithdrawERC721 - -```solidity -event BatchWithdrawERC721(address indexed l1Token, address indexed l2Token, address indexed from, address to, uint256[] tokenIds) -``` - -Emitted when the ERC721 NFT is batch transferred to gateway on layer 2. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| l1Token `indexed` | address | The address of ERC721 NFT on layer 1. | -| l2Token `indexed` | address | The address of ERC721 NFT on layer 2. | -| from `indexed` | address | The address of sender on layer 2. | -| to | address | The address of recipient on layer 1. | -| tokenIds | uint256[] | The list of token ids of the ERC721 NFT to withdraw on layer 2. | - -### FinalizeBatchDepositERC721 - -```solidity -event FinalizeBatchDepositERC721(address indexed l1Token, address indexed l2Token, address indexed from, address to, uint256[] tokenIds) -``` - -Emitted when the ERC721 NFT is batch transferred to recipient on layer 2. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| l1Token `indexed` | address | The address of ERC721 NFT on layer 1. | -| l2Token `indexed` | address | The address of ERC721 NFT on layer 2. | -| from `indexed` | address | The address of sender on layer 1. | -| to | address | The address of recipient on layer 2. | -| tokenIds | uint256[] | The list of token ids of the ERC721 NFT deposited on layer 1. | - -### FinalizeDepositERC721 - -```solidity -event FinalizeDepositERC721(address indexed l1Token, address indexed l2Token, address indexed from, address to, uint256 tokenId) -``` - -Emitted when the ERC721 NFT is transferred to recipient on layer 2. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| l1Token `indexed` | address | The address of ERC721 NFT on layer 1. | -| l2Token `indexed` | address | The address of ERC721 NFT on layer 2. | -| from `indexed` | address | The address of sender on layer 1. | -| to | address | The address of recipient on layer 2. | -| tokenId | uint256 | The token id of the ERC721 NFT deposited on layer 1. | - -### Initialized - -```solidity -event Initialized(uint8 version) -``` - - - -*Triggered when the contract has been initialized or reinitialized.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| version | uint8 | undefined | - -### OwnershipTransferred - -```solidity -event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -``` - - - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| previousOwner `indexed` | address | undefined | -| newOwner `indexed` | address | undefined | - -### UpdateTokenMapping - -```solidity -event UpdateTokenMapping(address indexed l2Token, address indexed oldL1Token, address indexed newL1Token) -``` - -Emitted when token mapping for ERC721 token is updated. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| l2Token `indexed` | address | The address of corresponding ERC721 token in layer 2. | -| oldL1Token `indexed` | address | The address of the old corresponding ERC721 token in layer 1. | -| newL1Token `indexed` | address | The address of the new corresponding ERC721 token in layer 1. | - -### WithdrawERC721 - -```solidity -event WithdrawERC721(address indexed l1Token, address indexed l2Token, address indexed from, address to, uint256 tokenId) -``` - -Emitted when the ERC721 NFT is transferred to gateway on layer 2. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| l1Token `indexed` | address | The address of ERC721 NFT on layer 1. | -| l2Token `indexed` | address | The address of ERC721 NFT on layer 2. | -| from `indexed` | address | The address of sender on layer 2. | -| to | address | The address of recipient on layer 1. | -| tokenId | uint256 | The token id of the ERC721 NFT to withdraw on layer 2. | - - - -## Errors - -### ErrorCallerIsNotCounterpartGateway - -```solidity -error ErrorCallerIsNotCounterpartGateway() -``` - - - -*Thrown when the cross chain sender is not the counterpart gateway contract.* - - -### ErrorCallerIsNotMessenger - -```solidity -error ErrorCallerIsNotMessenger() -``` - - - -*Thrown when the caller is not corresponding `L1ScrollMessenger` or `L2ScrollMessenger`.* - - -### ErrorNotInDropMessageContext - -```solidity -error ErrorNotInDropMessageContext() -``` - - - -*Thrown when ScrollMessenger is not dropping message.* - - -### ErrorZeroAddress - -```solidity -error ErrorZeroAddress() -``` - - - -*Thrown when the given address is `address(0)`.* - - - diff --git a/contracts/docs/apis/L2GatewayRouter.md b/contracts/docs/apis/L2GatewayRouter.md deleted file mode 100644 index 48df049f0..000000000 --- a/contracts/docs/apis/L2GatewayRouter.md +++ /dev/null @@ -1,566 +0,0 @@ -# L2GatewayRouter - - - -> L2GatewayRouter - -The `L2GatewayRouter` is the main entry for withdrawing Ether and ERC20 tokens. All deposited tokens are routed to corresponding gateways. - -*One can also use this contract to query L1/L2 token address mapping. In the future, ERC-721 and ERC-1155 tokens will be added to the router too.* - -## Methods - -### ERC20Gateway - -```solidity -function ERC20Gateway(address) external view returns (address) -``` - -Mapping from L2 ERC20 token address to corresponding L2ERC20Gateway. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### defaultERC20Gateway - -```solidity -function defaultERC20Gateway() external view returns (address) -``` - -The address of default L2 ERC20 gateway, normally the L2StandardERC20Gateway contract. - - - - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### ethGateway - -```solidity -function ethGateway() external view returns (address) -``` - -The address of L2ETHGateway. - - - - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### finalizeDepositERC20 - -```solidity -function finalizeDepositERC20(address, address, address, address, uint256, bytes) external payable -``` - -Complete a deposit from L1 to L2 and send fund to recipient's account in L2. - -*Make this function payable to handle WETH deposit/withdraw. The function should only be called by L2ScrollMessenger. The function should also only be called by L1ERC20Gateway in L1.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | -| _1 | address | undefined | -| _2 | address | undefined | -| _3 | address | undefined | -| _4 | uint256 | undefined | -| _5 | bytes | undefined | - -### finalizeDepositETH - -```solidity -function finalizeDepositETH(address, address, uint256, bytes) external payable -``` - -Complete ETH deposit from L1 to L2 and send fund to recipient's account in L2. - -*This function should only be called by L2ScrollMessenger. This function should also only be called by L1GatewayRouter in L1.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | -| _1 | address | undefined | -| _2 | uint256 | undefined | -| _3 | bytes | undefined | - -### getERC20Gateway - -```solidity -function getERC20Gateway(address _token) external view returns (address) -``` - -Return the corresponding gateway address for given token address. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _token | address | The address of token to query. | - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### getL1ERC20Address - -```solidity -function getL1ERC20Address(address _l2Address) external view returns (address) -``` - -Return the corresponding l1 token address given l2 token address. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _l2Address | address | undefined | - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### getL2ERC20Address - -```solidity -function getL2ERC20Address(address) external pure returns (address) -``` - -Return the corresponding l2 token address given l1 token address. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### initialize - -```solidity -function initialize(address _ethGateway, address _defaultERC20Gateway) external nonpayable -``` - - - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _ethGateway | address | undefined | -| _defaultERC20Gateway | address | undefined | - -### owner - -```solidity -function owner() external view returns (address) -``` - - - -*Returns the address of the current owner.* - - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### renounceOwnership - -```solidity -function renounceOwnership() external nonpayable -``` - - - -*Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner.* - - -### setDefaultERC20Gateway - -```solidity -function setDefaultERC20Gateway(address _newDefaultERC20Gateway) external nonpayable -``` - -Update the address of default ERC20 gateway contract. - -*This function should only be called by contract owner.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _newDefaultERC20Gateway | address | The address to update. | - -### setERC20Gateway - -```solidity -function setERC20Gateway(address[] _tokens, address[] _gateways) external nonpayable -``` - -Update the mapping from token address to gateway address. - -*This function should only be called by contract owner.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _tokens | address[] | The list of addresses of tokens to update. | -| _gateways | address[] | The list of addresses of gateways to update. | - -### setETHGateway - -```solidity -function setETHGateway(address _newEthGateway) external nonpayable -``` - -Update the address of ETH gateway contract. - -*This function should only be called by contract owner.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _newEthGateway | address | The address to update. | - -### transferOwnership - -```solidity -function transferOwnership(address newOwner) external nonpayable -``` - - - -*Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| newOwner | address | undefined | - -### withdrawERC20 - -```solidity -function withdrawERC20(address _token, uint256 _amount, uint256 _gasLimit) external payable -``` - -Withdraw of some token to a caller's account on L1. - -*Make this function payable to send relayer fee in Ether.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _token | address | undefined | -| _amount | uint256 | undefined | -| _gasLimit | uint256 | undefined | - -### withdrawERC20 - -```solidity -function withdrawERC20(address _token, address _to, uint256 _amount, uint256 _gasLimit) external payable -``` - -Withdraw of some token to a recipient's account on L1. - -*Make this function payable to send relayer fee in Ether.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _token | address | undefined | -| _to | address | undefined | -| _amount | uint256 | undefined | -| _gasLimit | uint256 | undefined | - -### withdrawERC20AndCall - -```solidity -function withdrawERC20AndCall(address _token, address _to, uint256 _amount, bytes _data, uint256 _gasLimit) external payable -``` - -Withdraw of some token to a recipient's account on L1 and call. - -*Make this function payable to send relayer fee in Ether.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _token | address | undefined | -| _to | address | undefined | -| _amount | uint256 | undefined | -| _data | bytes | undefined | -| _gasLimit | uint256 | undefined | - -### withdrawETH - -```solidity -function withdrawETH(address _to, uint256 _amount, uint256 _gasLimit) external payable -``` - -Withdraw ETH to caller's account in L1. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _to | address | undefined | -| _amount | uint256 | undefined | -| _gasLimit | uint256 | undefined | - -### withdrawETH - -```solidity -function withdrawETH(uint256 _amount, uint256 _gasLimit) external payable -``` - -Withdraw ETH to caller's account in L1. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _amount | uint256 | undefined | -| _gasLimit | uint256 | undefined | - -### withdrawETHAndCall - -```solidity -function withdrawETHAndCall(address _to, uint256 _amount, bytes _data, uint256 _gasLimit) external payable -``` - -Withdraw ETH to caller's account in L1. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _to | address | undefined | -| _amount | uint256 | undefined | -| _data | bytes | undefined | -| _gasLimit | uint256 | undefined | - - - -## Events - -### FinalizeDepositERC20 - -```solidity -event FinalizeDepositERC20(address indexed l1Token, address indexed l2Token, address indexed from, address to, uint256 amount, bytes data) -``` - -Emitted when ERC20 token is deposited from L1 to L2 and transfer to recipient. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| l1Token `indexed` | address | The address of the token in L1. | -| l2Token `indexed` | address | The address of the token in L2. | -| from `indexed` | address | The address of sender in L1. | -| to | address | The address of recipient in L2. | -| amount | uint256 | The amount of token withdrawn from L1 to L2. | -| data | bytes | The optional calldata passed to recipient in L2. | - -### FinalizeDepositETH - -```solidity -event FinalizeDepositETH(address indexed from, address indexed to, uint256 amount, bytes data) -``` - -Emitted when ETH is deposited from L1 to L2 and transfer to recipient. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| from `indexed` | address | The address of sender in L1. | -| to `indexed` | address | The address of recipient in L2. | -| amount | uint256 | The amount of ETH deposited from L1 to L2. | -| data | bytes | The optional calldata passed to recipient in L2. | - -### Initialized - -```solidity -event Initialized(uint8 version) -``` - - - -*Triggered when the contract has been initialized or reinitialized.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| version | uint8 | undefined | - -### OwnershipTransferred - -```solidity -event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -``` - - - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| previousOwner `indexed` | address | undefined | -| newOwner `indexed` | address | undefined | - -### SetDefaultERC20Gateway - -```solidity -event SetDefaultERC20Gateway(address indexed oldDefaultERC20Gateway, address indexed newDefaultERC20Gateway) -``` - -Emitted when the address of default ERC20 Gateway is updated. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| oldDefaultERC20Gateway `indexed` | address | The address of the old default ERC20 Gateway. | -| newDefaultERC20Gateway `indexed` | address | The address of the new default ERC20 Gateway. | - -### SetERC20Gateway - -```solidity -event SetERC20Gateway(address indexed token, address indexed oldGateway, address indexed newGateway) -``` - -Emitted when the `gateway` for `token` is updated. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| token `indexed` | address | The address of token updated. | -| oldGateway `indexed` | address | The corresponding address of the old gateway. | -| newGateway `indexed` | address | The corresponding address of the new gateway. | - -### SetETHGateway - -```solidity -event SetETHGateway(address indexed oldETHGateway, address indexed newEthGateway) -``` - -Emitted when the address of ETH Gateway is updated. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| oldETHGateway `indexed` | address | The address of the old ETH Gateway. | -| newEthGateway `indexed` | address | The address of the new ETH Gateway. | - -### WithdrawERC20 - -```solidity -event WithdrawERC20(address indexed l1Token, address indexed l2Token, address indexed from, address to, uint256 amount, bytes data) -``` - -Emitted when someone withdraw ERC20 token from L2 to L1. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| l1Token `indexed` | address | The address of the token in L1. | -| l2Token `indexed` | address | The address of the token in L2. | -| from `indexed` | address | The address of sender in L2. | -| to | address | The address of recipient in L1. | -| amount | uint256 | The amount of token will be deposited from L2 to L1. | -| data | bytes | The optional calldata passed to recipient in L1. | - -### WithdrawETH - -```solidity -event WithdrawETH(address indexed from, address indexed to, uint256 amount, bytes data) -``` - -Emitted when someone withdraw ETH from L2 to L1. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| from `indexed` | address | The address of sender in L2. | -| to `indexed` | address | The address of recipient in L1. | -| amount | uint256 | The amount of ETH will be deposited from L2 to L1. | -| data | bytes | The optional calldata passed to recipient in L1. | - - - diff --git a/contracts/docs/apis/L2ScrollMessenger.md b/contracts/docs/apis/L2ScrollMessenger.md deleted file mode 100644 index 170bb4a80..000000000 --- a/contracts/docs/apis/L2ScrollMessenger.md +++ /dev/null @@ -1,464 +0,0 @@ -# L2ScrollMessenger - - - -> L2ScrollMessenger - -The `L2ScrollMessenger` contract can: 1. send messages from layer 2 to layer 1; 2. relay messages from layer 1 layer 2; 3. drop expired message due to sequencer problems. - -*It should be a predeployed contract on layer 2 and should hold infinite amount of Ether (Specifically, `uint256(-1)`), which can be initialized in Genesis Block.* - -## Methods - -### counterpart - -```solidity -function counterpart() external view returns (address) -``` - -The address of counterpart ScrollMessenger contract in L1/L2. - - - - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### feeVault - -```solidity -function feeVault() external view returns (address) -``` - -The address of fee vault, collecting cross domain messaging fee. - - - - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### initialize - -```solidity -function initialize(address) external nonpayable -``` - - - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### isL1MessageExecuted - -```solidity -function isL1MessageExecuted(bytes32) external view returns (bool) -``` - -Mapping from L1 message hash to a boolean value indicating if the message has been successfully executed. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _0 | bytes32 | undefined | - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | bool | undefined | - -### messageQueue - -```solidity -function messageQueue() external view returns (address) -``` - -The address of L2MessageQueue. - - - - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### messageSendTimestamp - -```solidity -function messageSendTimestamp(bytes32) external view returns (uint256) -``` - -Mapping from L2 message hash to the timestamp when the message is sent. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _0 | bytes32 | undefined | - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | uint256 | undefined | - -### owner - -```solidity -function owner() external view returns (address) -``` - - - -*Returns the address of the current owner.* - - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### paused - -```solidity -function paused() external view returns (bool) -``` - - - -*Returns true if the contract is paused, and false otherwise.* - - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | bool | undefined | - -### relayMessage - -```solidity -function relayMessage(address _from, address _to, uint256 _value, uint256 _nonce, bytes _message) external nonpayable -``` - -execute L1 => L2 message - -*Make sure this is only called by privileged accounts.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _from | address | undefined | -| _to | address | undefined | -| _value | uint256 | undefined | -| _nonce | uint256 | undefined | -| _message | bytes | undefined | - -### renounceOwnership - -```solidity -function renounceOwnership() external nonpayable -``` - - - -*Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner.* - - -### sendMessage - -```solidity -function sendMessage(address _to, uint256 _value, bytes _message, uint256 _gasLimit, address) external payable -``` - -Send cross chain message from L1 to L2 or L2 to L1. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _to | address | undefined | -| _value | uint256 | undefined | -| _message | bytes | undefined | -| _gasLimit | uint256 | undefined | -| _4 | address | undefined | - -### sendMessage - -```solidity -function sendMessage(address _to, uint256 _value, bytes _message, uint256 _gasLimit) external payable -``` - -Send cross chain message from L1 to L2 or L2 to L1. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _to | address | undefined | -| _value | uint256 | undefined | -| _message | bytes | undefined | -| _gasLimit | uint256 | undefined | - -### setPause - -```solidity -function setPause(bool _status) external nonpayable -``` - -Pause the contract - -*This function can only called by contract owner.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _status | bool | The pause status to update. | - -### transferOwnership - -```solidity -function transferOwnership(address newOwner) external nonpayable -``` - - - -*Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| newOwner | address | undefined | - -### updateFeeVault - -```solidity -function updateFeeVault(address _newFeeVault) external nonpayable -``` - -Update fee vault contract. - -*This function can only called by contract owner.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _newFeeVault | address | The address of new fee vault contract. | - -### xDomainMessageSender - -```solidity -function xDomainMessageSender() external view returns (address) -``` - -See {IScrollMessenger-xDomainMessageSender} - - - - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - - - -## Events - -### FailedRelayedMessage - -```solidity -event FailedRelayedMessage(bytes32 indexed messageHash) -``` - -Emitted when a cross domain message is failed to relay. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| messageHash `indexed` | bytes32 | The hash of the message. | - -### Initialized - -```solidity -event Initialized(uint8 version) -``` - - - -*Triggered when the contract has been initialized or reinitialized.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| version | uint8 | undefined | - -### OwnershipTransferred - -```solidity -event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -``` - - - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| previousOwner `indexed` | address | undefined | -| newOwner `indexed` | address | undefined | - -### Paused - -```solidity -event Paused(address account) -``` - - - -*Emitted when the pause is triggered by `account`.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| account | address | undefined | - -### RelayedMessage - -```solidity -event RelayedMessage(bytes32 indexed messageHash) -``` - -Emitted when a cross domain message is relayed successfully. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| messageHash `indexed` | bytes32 | The hash of the message. | - -### SentMessage - -```solidity -event SentMessage(address indexed sender, address indexed target, uint256 value, uint256 messageNonce, uint256 gasLimit, bytes message) -``` - -Emitted when a cross domain message is sent. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| sender `indexed` | address | The address of the sender who initiates the message. | -| target `indexed` | address | The address of target contract to call. | -| value | uint256 | The amount of value passed to the target contract. | -| messageNonce | uint256 | The nonce of the message. | -| gasLimit | uint256 | The optional gas limit passed to L1 or L2. | -| message | bytes | The calldata passed to the target contract. | - -### Unpaused - -```solidity -event Unpaused(address account) -``` - - - -*Emitted when the pause is lifted by `account`.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| account | address | undefined | - -### UpdateFeeVault - -```solidity -event UpdateFeeVault(address _oldFeeVault, address _newFeeVault) -``` - -Emitted when owner updates fee vault contract. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _oldFeeVault | address | The address of old fee vault contract. | -| _newFeeVault | address | The address of new fee vault contract. | - -### UpdateMaxFailedExecutionTimes - -```solidity -event UpdateMaxFailedExecutionTimes(uint256 oldMaxFailedExecutionTimes, uint256 newMaxFailedExecutionTimes) -``` - -Emitted when the maximum number of times each message can fail in L2 is updated. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| oldMaxFailedExecutionTimes | uint256 | The old maximum number of times each message can fail in L2. | -| newMaxFailedExecutionTimes | uint256 | The new maximum number of times each message can fail in L2. | - - - -## Errors - -### ErrorZeroAddress - -```solidity -error ErrorZeroAddress() -``` - - - -*Thrown when the given address is `address(0)`.* - - - diff --git a/contracts/docs/apis/L2StandardERC20Gateway.md b/contracts/docs/apis/L2StandardERC20Gateway.md deleted file mode 100644 index 05dd24aa1..000000000 --- a/contracts/docs/apis/L2StandardERC20Gateway.md +++ /dev/null @@ -1,393 +0,0 @@ -# L2StandardERC20Gateway - - - -> L2StandardERC20Gateway - -The `L2StandardERC20Gateway` is used to withdraw standard ERC20 tokens on layer 2 and finalize deposit the tokens from layer 1. - -*The withdrawn ERC20 tokens will be burned directly. On finalizing deposit, the corresponding token will be minted and transferred to the recipient. Any ERC20 that requires non-standard functionality should use a separate gateway.* - -## Methods - -### counterpart - -```solidity -function counterpart() external view returns (address) -``` - -The address of corresponding L1/L2 Gateway contract. - - - - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### finalizeDepositERC20 - -```solidity -function finalizeDepositERC20(address _l1Token, address _l2Token, address _from, address _to, uint256 _amount, bytes _data) external payable -``` - -Complete a deposit from L1 to L2 and send fund to recipient's account in L2. - -*Make this function payable to handle WETH deposit/withdraw. The function should only be called by L2ScrollMessenger. The function should also only be called by L1ERC20Gateway in L1.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _l1Token | address | undefined | -| _l2Token | address | undefined | -| _from | address | undefined | -| _to | address | undefined | -| _amount | uint256 | undefined | -| _data | bytes | undefined | - -### getL1ERC20Address - -```solidity -function getL1ERC20Address(address _l2Token) external view returns (address) -``` - -Return the corresponding l1 token address given l2 token address. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _l2Token | address | undefined | - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### getL2ERC20Address - -```solidity -function getL2ERC20Address(address _l1Token) external view returns (address) -``` - -Return the corresponding l2 token address given l1 token address. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _l1Token | address | undefined | - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### initialize - -```solidity -function initialize(address _counterpart, address _router, address _messenger, address) external nonpayable -``` - -Initialize the storage of L2StandardERC20Gateway. - -*The parameters `_counterpart`, `_router`, `_messenger` and `_tokenFactory` are no longer used.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _counterpart | address | The address of `L1StandardERC20Gateway` contract in L1. | -| _router | address | The address of `L2GatewayRouter` contract in L2. | -| _messenger | address | The address of `L2ScrollMessenger` contract in L2. | -| _3 | address | undefined | - -### messenger - -```solidity -function messenger() external view returns (address) -``` - -The address of corresponding L1ScrollMessenger/L2ScrollMessenger contract. - - - - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### owner - -```solidity -function owner() external view returns (address) -``` - - - -*Returns the address of the current owner.* - - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### renounceOwnership - -```solidity -function renounceOwnership() external nonpayable -``` - - - -*Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner.* - - -### router - -```solidity -function router() external view returns (address) -``` - -The address of L1GatewayRouter/L2GatewayRouter contract. - - - - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### tokenFactory - -```solidity -function tokenFactory() external view returns (address) -``` - -The address of ScrollStandardERC20Factory. - - - - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### transferOwnership - -```solidity -function transferOwnership(address newOwner) external nonpayable -``` - - - -*Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| newOwner | address | undefined | - -### withdrawERC20 - -```solidity -function withdrawERC20(address _token, uint256 _amount, uint256 _gasLimit) external payable -``` - -Withdraw of some token to a caller's account on L1. - -*Make this function payable to send relayer fee in Ether.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _token | address | undefined | -| _amount | uint256 | undefined | -| _gasLimit | uint256 | undefined | - -### withdrawERC20 - -```solidity -function withdrawERC20(address _token, address _to, uint256 _amount, uint256 _gasLimit) external payable -``` - -Withdraw of some token to a recipient's account on L1. - -*Make this function payable to send relayer fee in Ether.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _token | address | undefined | -| _to | address | undefined | -| _amount | uint256 | undefined | -| _gasLimit | uint256 | undefined | - -### withdrawERC20AndCall - -```solidity -function withdrawERC20AndCall(address _token, address _to, uint256 _amount, bytes _data, uint256 _gasLimit) external payable -``` - -Withdraw of some token to a recipient's account on L1 and call. - -*Make this function payable to send relayer fee in Ether.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _token | address | undefined | -| _to | address | undefined | -| _amount | uint256 | undefined | -| _data | bytes | undefined | -| _gasLimit | uint256 | undefined | - - - -## Events - -### FinalizeDepositERC20 - -```solidity -event FinalizeDepositERC20(address indexed l1Token, address indexed l2Token, address indexed from, address to, uint256 amount, bytes data) -``` - -Emitted when ERC20 token is deposited from L1 to L2 and transfer to recipient. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| l1Token `indexed` | address | The address of the token in L1. | -| l2Token `indexed` | address | The address of the token in L2. | -| from `indexed` | address | The address of sender in L1. | -| to | address | The address of recipient in L2. | -| amount | uint256 | The amount of token withdrawn from L1 to L2. | -| data | bytes | The optional calldata passed to recipient in L2. | - -### Initialized - -```solidity -event Initialized(uint8 version) -``` - - - -*Triggered when the contract has been initialized or reinitialized.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| version | uint8 | undefined | - -### OwnershipTransferred - -```solidity -event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -``` - - - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| previousOwner `indexed` | address | undefined | -| newOwner `indexed` | address | undefined | - -### WithdrawERC20 - -```solidity -event WithdrawERC20(address indexed l1Token, address indexed l2Token, address indexed from, address to, uint256 amount, bytes data) -``` - -Emitted when someone withdraw ERC20 token from L2 to L1. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| l1Token `indexed` | address | The address of the token in L1. | -| l2Token `indexed` | address | The address of the token in L2. | -| from `indexed` | address | The address of sender in L2. | -| to | address | The address of recipient in L1. | -| amount | uint256 | The amount of token will be deposited from L2 to L1. | -| data | bytes | The optional calldata passed to recipient in L1. | - - - -## Errors - -### ErrorCallerIsNotCounterpartGateway - -```solidity -error ErrorCallerIsNotCounterpartGateway() -``` - - - -*Thrown when the cross chain sender is not the counterpart gateway contract.* - - -### ErrorCallerIsNotMessenger - -```solidity -error ErrorCallerIsNotMessenger() -``` - - - -*Thrown when the caller is not corresponding `L1ScrollMessenger` or `L2ScrollMessenger`.* - - -### ErrorNotInDropMessageContext - -```solidity -error ErrorNotInDropMessageContext() -``` - - - -*Thrown when ScrollMessenger is not dropping message.* - - -### ErrorZeroAddress - -```solidity -error ErrorZeroAddress() -``` - - - -*Thrown when the given address is `address(0)`.* - - - diff --git a/contracts/docs/apis/L2WETHGateway.md b/contracts/docs/apis/L2WETHGateway.md deleted file mode 100644 index 129addae6..000000000 --- a/contracts/docs/apis/L2WETHGateway.md +++ /dev/null @@ -1,409 +0,0 @@ -# L2WETHGateway - - - -> L2WETHGateway - -The `L2WETHGateway` contract is used to withdraw `WETH` token on layer 2 and finalize deposit `WETH` from layer 1. - -*The WETH tokens are not held in the gateway. It will first be unwrapped as Ether and then the Ether will be sent to the `L2ScrollMessenger` contract. On finalizing deposit, the Ether will be transferred from `L2ScrollMessenger`, then wrapped as WETH and finally transfer to recipient.* - -## Methods - -### WETH - -```solidity -function WETH() external view returns (address) -``` - -The address of L2 WETH address. - - - - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### counterpart - -```solidity -function counterpart() external view returns (address) -``` - -The address of corresponding L1/L2 Gateway contract. - - - - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### finalizeDepositERC20 - -```solidity -function finalizeDepositERC20(address _l1Token, address _l2Token, address _from, address _to, uint256 _amount, bytes _data) external payable -``` - -Complete a deposit from L1 to L2 and send fund to recipient's account in L2. - -*Make this function payable to handle WETH deposit/withdraw. The function should only be called by L2ScrollMessenger. The function should also only be called by L1ERC20Gateway in L1.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _l1Token | address | undefined | -| _l2Token | address | undefined | -| _from | address | undefined | -| _to | address | undefined | -| _amount | uint256 | undefined | -| _data | bytes | undefined | - -### getL1ERC20Address - -```solidity -function getL1ERC20Address(address) external view returns (address) -``` - -Return the corresponding l1 token address given l2 token address. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### getL2ERC20Address - -```solidity -function getL2ERC20Address(address) external view returns (address) -``` - -Return the corresponding l2 token address given l1 token address. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### initialize - -```solidity -function initialize(address _counterpart, address _router, address _messenger) external nonpayable -``` - -Initialize the storage of `L2WETHGateway`. - -*The parameters `_counterpart`, `_router` and `_messenger` are no longer used.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _counterpart | address | The address of `L1WETHGateway` contract in L1. | -| _router | address | The address of `L2GatewayRouter` contract in L2. | -| _messenger | address | The address of `L2ScrollMessenger` contract in L2. | - -### l1WETH - -```solidity -function l1WETH() external view returns (address) -``` - -The address of L1 WETH address. - - - - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### messenger - -```solidity -function messenger() external view returns (address) -``` - -The address of corresponding L1ScrollMessenger/L2ScrollMessenger contract. - - - - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### owner - -```solidity -function owner() external view returns (address) -``` - - - -*Returns the address of the current owner.* - - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### renounceOwnership - -```solidity -function renounceOwnership() external nonpayable -``` - - - -*Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner.* - - -### router - -```solidity -function router() external view returns (address) -``` - -The address of L1GatewayRouter/L2GatewayRouter contract. - - - - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### transferOwnership - -```solidity -function transferOwnership(address newOwner) external nonpayable -``` - - - -*Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| newOwner | address | undefined | - -### withdrawERC20 - -```solidity -function withdrawERC20(address _token, uint256 _amount, uint256 _gasLimit) external payable -``` - -Withdraw of some token to a caller's account on L1. - -*Make this function payable to send relayer fee in Ether.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _token | address | undefined | -| _amount | uint256 | undefined | -| _gasLimit | uint256 | undefined | - -### withdrawERC20 - -```solidity -function withdrawERC20(address _token, address _to, uint256 _amount, uint256 _gasLimit) external payable -``` - -Withdraw of some token to a recipient's account on L1. - -*Make this function payable to send relayer fee in Ether.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _token | address | undefined | -| _to | address | undefined | -| _amount | uint256 | undefined | -| _gasLimit | uint256 | undefined | - -### withdrawERC20AndCall - -```solidity -function withdrawERC20AndCall(address _token, address _to, uint256 _amount, bytes _data, uint256 _gasLimit) external payable -``` - -Withdraw of some token to a recipient's account on L1 and call. - -*Make this function payable to send relayer fee in Ether.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _token | address | undefined | -| _to | address | undefined | -| _amount | uint256 | undefined | -| _data | bytes | undefined | -| _gasLimit | uint256 | undefined | - - - -## Events - -### FinalizeDepositERC20 - -```solidity -event FinalizeDepositERC20(address indexed l1Token, address indexed l2Token, address indexed from, address to, uint256 amount, bytes data) -``` - -Emitted when ERC20 token is deposited from L1 to L2 and transfer to recipient. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| l1Token `indexed` | address | The address of the token in L1. | -| l2Token `indexed` | address | The address of the token in L2. | -| from `indexed` | address | The address of sender in L1. | -| to | address | The address of recipient in L2. | -| amount | uint256 | The amount of token withdrawn from L1 to L2. | -| data | bytes | The optional calldata passed to recipient in L2. | - -### Initialized - -```solidity -event Initialized(uint8 version) -``` - - - -*Triggered when the contract has been initialized or reinitialized.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| version | uint8 | undefined | - -### OwnershipTransferred - -```solidity -event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -``` - - - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| previousOwner `indexed` | address | undefined | -| newOwner `indexed` | address | undefined | - -### WithdrawERC20 - -```solidity -event WithdrawERC20(address indexed l1Token, address indexed l2Token, address indexed from, address to, uint256 amount, bytes data) -``` - -Emitted when someone withdraw ERC20 token from L2 to L1. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| l1Token `indexed` | address | The address of the token in L1. | -| l2Token `indexed` | address | The address of the token in L2. | -| from `indexed` | address | The address of sender in L2. | -| to | address | The address of recipient in L1. | -| amount | uint256 | The amount of token will be deposited from L2 to L1. | -| data | bytes | The optional calldata passed to recipient in L1. | - - - -## Errors - -### ErrorCallerIsNotCounterpartGateway - -```solidity -error ErrorCallerIsNotCounterpartGateway() -``` - - - -*Thrown when the cross chain sender is not the counterpart gateway contract.* - - -### ErrorCallerIsNotMessenger - -```solidity -error ErrorCallerIsNotMessenger() -``` - - - -*Thrown when the caller is not corresponding `L1ScrollMessenger` or `L2ScrollMessenger`.* - - -### ErrorNotInDropMessageContext - -```solidity -error ErrorNotInDropMessageContext() -``` - - - -*Thrown when ScrollMessenger is not dropping message.* - - -### ErrorZeroAddress - -```solidity -error ErrorZeroAddress() -``` - - - -*Thrown when the given address is `address(0)`.* - - - diff --git a/contracts/docs/apis/ScrollChain.md b/contracts/docs/apis/ScrollChain.md deleted file mode 100644 index c052a0062..000000000 --- a/contracts/docs/apis/ScrollChain.md +++ /dev/null @@ -1,1017 +0,0 @@ -# ScrollChain - - - -> ScrollChain - -This contract maintains data for the Scroll rollup. - - - -## Methods - -### addProver - -```solidity -function addProver(address _account) external nonpayable -``` - -Add an account to the prover list. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _account | address | The address of account to add. | - -### addSequencer - -```solidity -function addSequencer(address _account) external nonpayable -``` - -Add an account to the sequencer list. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _account | address | The address of account to add. | - -### commitBatch - -```solidity -function commitBatch(uint8 _version, bytes _parentBatchHeader, bytes[] _chunks, bytes _skippedL1MessageBitmap) external nonpayable -``` - -Commit a batch of transactions on layer 1. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _version | uint8 | undefined | -| _parentBatchHeader | bytes | undefined | -| _chunks | bytes[] | undefined | -| _skippedL1MessageBitmap | bytes | undefined | - -### committedBatches - -```solidity -function committedBatches(uint256) external view returns (bytes32) -``` - - - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _0 | uint256 | undefined | - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | bytes32 | The batch hash of a committed batch. | - -### finalizeBatchWithProof - -```solidity -function finalizeBatchWithProof(bytes _batchHeader, bytes32 _prevStateRoot, bytes32 _postStateRoot, bytes32 _withdrawRoot, bytes _aggrProof) external nonpayable -``` - -Finalize a committed batch on layer 1. - -*We keep this function to upgrade to 4844 more smoothly.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _batchHeader | bytes | undefined | -| _prevStateRoot | bytes32 | undefined | -| _postStateRoot | bytes32 | undefined | -| _withdrawRoot | bytes32 | undefined | -| _aggrProof | bytes | undefined | - -### finalizeBatchWithProof4844 - -```solidity -function finalizeBatchWithProof4844(bytes _batchHeader, bytes32 _prevStateRoot, bytes32 _postStateRoot, bytes32 _withdrawRoot, bytes _blobDataProof, bytes _aggrProof) external nonpayable -``` - -Finalize a committed batch (with blob) on layer 1. - -*Memory layout of `_blobDataProof`: ```text | z | y | kzg_commitment | kzg_proof | |---------|---------|----------------|-----------| | bytes32 | bytes32 | bytes48 | bytes48 | ```* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _batchHeader | bytes | undefined | -| _prevStateRoot | bytes32 | undefined | -| _postStateRoot | bytes32 | undefined | -| _withdrawRoot | bytes32 | undefined | -| _blobDataProof | bytes | undefined | -| _aggrProof | bytes | undefined | - -### finalizedStateRoots - -```solidity -function finalizedStateRoots(uint256) external view returns (bytes32) -``` - - - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _0 | uint256 | undefined | - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | bytes32 | The state root of a committed batch. | - -### importGenesisBatch - -```solidity -function importGenesisBatch(bytes _batchHeader, bytes32 _stateRoot) external nonpayable -``` - -Import layer 2 genesis block - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _batchHeader | bytes | The header of the genesis batch. | -| _stateRoot | bytes32 | The state root of the genesis block. | - -### initialize - -```solidity -function initialize(address _messageQueue, address _verifier, uint256 _maxNumTxInChunk) external nonpayable -``` - -Initialize the storage of ScrollChain. - -*The parameters `_messageQueue` are no longer used.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _messageQueue | address | The address of `L1MessageQueue` contract. | -| _verifier | address | The address of zkevm verifier contract. | -| _maxNumTxInChunk | uint256 | The maximum number of transactions allowed in each chunk. | - -### isBatchFinalized - -```solidity -function isBatchFinalized(uint256 _batchIndex) external view returns (bool) -``` - - - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _batchIndex | uint256 | undefined | - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | bool | Whether the batch is finalized by batch index. | - -### isProver - -```solidity -function isProver(address) external view returns (bool) -``` - -Whether an account is a prover. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | bool | undefined | - -### isSequencer - -```solidity -function isSequencer(address) external view returns (bool) -``` - -Whether an account is a sequencer. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | bool | undefined | - -### lastFinalizedBatchIndex - -```solidity -function lastFinalizedBatchIndex() external view returns (uint256) -``` - - - - - - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | uint256 | The latest finalized batch index. | - -### layer2ChainId - -```solidity -function layer2ChainId() external view returns (uint64) -``` - -The chain id of the corresponding layer 2 chain. - - - - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | uint64 | undefined | - -### maxNumTxInChunk - -```solidity -function maxNumTxInChunk() external view returns (uint256) -``` - -The maximum number of transactions allowed in each chunk. - - - - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | uint256 | undefined | - -### messageQueue - -```solidity -function messageQueue() external view returns (address) -``` - -The address of L1MessageQueue contract. - - - - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### owner - -```solidity -function owner() external view returns (address) -``` - - - -*Returns the address of the current owner.* - - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### paused - -```solidity -function paused() external view returns (bool) -``` - - - -*Returns true if the contract is paused, and false otherwise.* - - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | bool | undefined | - -### removeProver - -```solidity -function removeProver(address _account) external nonpayable -``` - -Add an account from the prover list. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _account | address | The address of account to remove. | - -### removeSequencer - -```solidity -function removeSequencer(address _account) external nonpayable -``` - -Remove an account from the sequencer list. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _account | address | The address of account to remove. | - -### renounceOwnership - -```solidity -function renounceOwnership() external nonpayable -``` - - - -*Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner.* - - -### revertBatch - -```solidity -function revertBatch(bytes _batchHeader, uint256 _count) external nonpayable -``` - -Revert a pending batch. - -*If the owner want to revert a sequence of batches by sending multiple transactions, make sure to revert recent batches first.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _batchHeader | bytes | undefined | -| _count | uint256 | undefined | - -### setPause - -```solidity -function setPause(bool _status) external nonpayable -``` - -Pause the contract - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _status | bool | The pause status to update. | - -### transferOwnership - -```solidity -function transferOwnership(address newOwner) external nonpayable -``` - - - -*Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| newOwner | address | undefined | - -### updateMaxNumTxInChunk - -```solidity -function updateMaxNumTxInChunk(uint256 _maxNumTxInChunk) external nonpayable -``` - -Update the value of `maxNumTxInChunk`. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _maxNumTxInChunk | uint256 | The new value of `maxNumTxInChunk`. | - -### verifier - -```solidity -function verifier() external view returns (address) -``` - -The address of RollupVerifier. - - - - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### withdrawRoots - -```solidity -function withdrawRoots(uint256) external view returns (bytes32) -``` - - - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _0 | uint256 | undefined | - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | bytes32 | The message root of a committed batch. | - - - -## Events - -### CommitBatch - -```solidity -event CommitBatch(uint256 indexed batchIndex, bytes32 indexed batchHash) -``` - -Emitted when a new batch is committed. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| batchIndex `indexed` | uint256 | The index of the batch. | -| batchHash `indexed` | bytes32 | The hash of the batch. | - -### FinalizeBatch - -```solidity -event FinalizeBatch(uint256 indexed batchIndex, bytes32 indexed batchHash, bytes32 stateRoot, bytes32 withdrawRoot) -``` - -Emitted when a batch is finalized. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| batchIndex `indexed` | uint256 | The index of the batch. | -| batchHash `indexed` | bytes32 | The hash of the batch | -| stateRoot | bytes32 | The state root on layer 2 after this batch. | -| withdrawRoot | bytes32 | The merkle root on layer2 after this batch. | - -### Initialized - -```solidity -event Initialized(uint8 version) -``` - - - -*Triggered when the contract has been initialized or reinitialized.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| version | uint8 | undefined | - -### OwnershipTransferred - -```solidity -event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -``` - - - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| previousOwner `indexed` | address | undefined | -| newOwner `indexed` | address | undefined | - -### Paused - -```solidity -event Paused(address account) -``` - - - -*Emitted when the pause is triggered by `account`.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| account | address | undefined | - -### RevertBatch - -```solidity -event RevertBatch(uint256 indexed batchIndex, bytes32 indexed batchHash) -``` - -revert a pending batch. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| batchIndex `indexed` | uint256 | The index of the batch. | -| batchHash `indexed` | bytes32 | The hash of the batch | - -### Unpaused - -```solidity -event Unpaused(address account) -``` - - - -*Emitted when the pause is lifted by `account`.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| account | address | undefined | - -### UpdateMaxNumTxInChunk - -```solidity -event UpdateMaxNumTxInChunk(uint256 oldMaxNumTxInChunk, uint256 newMaxNumTxInChunk) -``` - -Emitted when the value of `maxNumTxInChunk` is updated. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| oldMaxNumTxInChunk | uint256 | The old value of `maxNumTxInChunk`. | -| newMaxNumTxInChunk | uint256 | The new value of `maxNumTxInChunk`. | - -### UpdateProver - -```solidity -event UpdateProver(address indexed account, bool status) -``` - -Emitted when owner updates the status of prover. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| account `indexed` | address | The address of account updated. | -| status | bool | The status of the account updated. | - -### UpdateSequencer - -```solidity -event UpdateSequencer(address indexed account, bool status) -``` - -Emitted when owner updates the status of sequencer. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| account `indexed` | address | The address of account updated. | -| status | bool | The status of the account updated. | - - - -## Errors - -### ErrorAccountIsNotEOA - -```solidity -error ErrorAccountIsNotEOA() -``` - - - -*Thrown when the given account is not EOA account.* - - -### ErrorBatchHeaderLengthTooSmall - -```solidity -error ErrorBatchHeaderLengthTooSmall() -``` - - - -*Thrown when the length of batch header is smaller than 89* - - -### ErrorBatchIsAlreadyCommitted - -```solidity -error ErrorBatchIsAlreadyCommitted() -``` - - - -*Thrown when committing a committed batch.* - - -### ErrorBatchIsAlreadyVerified - -```solidity -error ErrorBatchIsAlreadyVerified() -``` - - - -*Thrown when finalizing a verified batch.* - - -### ErrorBatchIsEmpty - -```solidity -error ErrorBatchIsEmpty() -``` - - - -*Thrown when committing empty batch (batch without chunks)* - - -### ErrorCallPointEvaluationPrecompileFailed - -```solidity -error ErrorCallPointEvaluationPrecompileFailed() -``` - - - -*Thrown when call precompile failed.* - - -### ErrorCallerIsNotProver - -```solidity -error ErrorCallerIsNotProver() -``` - - - -*Thrown when the caller is not prover.* - - -### ErrorCallerIsNotSequencer - -```solidity -error ErrorCallerIsNotSequencer() -``` - - - -*Thrown when the caller is not sequencer.* - - -### ErrorFoundMultipleBlob - -```solidity -error ErrorFoundMultipleBlob() -``` - - - -*Thrown when the transaction has multiple blobs.* - - -### ErrorGenesisBatchHasNonZeroField - -```solidity -error ErrorGenesisBatchHasNonZeroField() -``` - - - -*Thrown when some fields are not zero in genesis batch.* - - -### ErrorGenesisBatchImported - -```solidity -error ErrorGenesisBatchImported() -``` - - - -*Thrown when importing genesis batch twice.* - - -### ErrorGenesisDataHashIsZero - -```solidity -error ErrorGenesisDataHashIsZero() -``` - - - -*Thrown when data hash in genesis batch is zero.* - - -### ErrorGenesisParentBatchHashIsNonZero - -```solidity -error ErrorGenesisParentBatchHashIsNonZero() -``` - - - -*Thrown when the parent batch hash in genesis batch is zero.* - - -### ErrorIncompleteL2TransactionData - -```solidity -error ErrorIncompleteL2TransactionData() -``` - - - -*Thrown when the l2 transaction is incomplete.* - - -### ErrorIncorrectBatchHash - -```solidity -error ErrorIncorrectBatchHash() -``` - - - -*Thrown when the batch hash is incorrect.* - - -### ErrorIncorrectBatchIndex - -```solidity -error ErrorIncorrectBatchIndex() -``` - - - -*Thrown when the batch index is incorrect.* - - -### ErrorIncorrectBitmapLength - -```solidity -error ErrorIncorrectBitmapLength() -``` - - - -*Thrown when the bitmap length is incorrect.* - - -### ErrorIncorrectChunkLength - -```solidity -error ErrorIncorrectChunkLength() -``` - - - -*Thrown when the length of chunk is incorrect.* - - -### ErrorIncorrectPreviousStateRoot - -```solidity -error ErrorIncorrectPreviousStateRoot() -``` - - - -*Thrown when the previous state root doesn't match stored one.* - - -### ErrorLastL1MessageSkipped - -```solidity -error ErrorLastL1MessageSkipped() -``` - - - -*Thrown when the last message is skipped.* - - -### ErrorNoBlobFound - -```solidity -error ErrorNoBlobFound() -``` - - - -*Thrown when no blob found in the transaction.* - - -### ErrorNoBlockInChunk - -```solidity -error ErrorNoBlockInChunk() -``` - - - -*Thrown when no blocks in chunk.* - - -### ErrorNumTxsLessThanNumL1Msgs - -```solidity -error ErrorNumTxsLessThanNumL1Msgs() -``` - - - -*Thrown when the number of transactions is less than number of L1 message in one block.* - - -### ErrorPreviousStateRootIsZero - -```solidity -error ErrorPreviousStateRootIsZero() -``` - - - -*Thrown when the given previous state is zero.* - - -### ErrorRevertFinalizedBatch - -```solidity -error ErrorRevertFinalizedBatch() -``` - - - -*Thrown when reverting a finalized batch.* - - -### ErrorRevertNotStartFromEnd - -```solidity -error ErrorRevertNotStartFromEnd() -``` - - - -*Thrown when the reverted batches are not in the ending of committed batch chain.* - - -### ErrorRevertZeroBatches - -```solidity -error ErrorRevertZeroBatches() -``` - - - -*Thrown when the number of batches to revert is zero.* - - -### ErrorStateRootIsZero - -```solidity -error ErrorStateRootIsZero() -``` - - - -*Thrown when the given state root is zero.* - - -### ErrorTooManyTxsInOneChunk - -```solidity -error ErrorTooManyTxsInOneChunk() -``` - - - -*Thrown when a chunk contains too many transactions.* - - -### ErrorUnexpectedPointEvaluationPrecompileOutput - -```solidity -error ErrorUnexpectedPointEvaluationPrecompileOutput() -``` - - - -*Thrown when the precompile output is incorrect.* - - -### ErrorZeroAddress - -```solidity -error ErrorZeroAddress() -``` - - - -*Thrown when the given address is `address(0)`.* - - - diff --git a/contracts/docs/apis/ScrollStandardERC20Factory.md b/contracts/docs/apis/ScrollStandardERC20Factory.md deleted file mode 100644 index 68609ca69..000000000 --- a/contracts/docs/apis/ScrollStandardERC20Factory.md +++ /dev/null @@ -1,159 +0,0 @@ -# ScrollStandardERC20Factory - - - -> ScrollStandardERC20Factory - -The `ScrollStandardERC20Factory` is used to deploy `ScrollStandardERC20` for `L2StandardERC20Gateway`. It uses the `Clones` contract to deploy contract with minimum gas usage. - -*The implementation of deployed token is non-upgradable. This design may be changed in the future.* - -## Methods - -### computeL2TokenAddress - -```solidity -function computeL2TokenAddress(address _gateway, address _l1Token) external view returns (address) -``` - -Compute the corresponding l2 token address given l1 token address. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _gateway | address | The address of gateway contract. | -| _l1Token | address | The address of l1 token. | - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### deployL2Token - -```solidity -function deployL2Token(address _gateway, address _l1Token) external nonpayable returns (address) -``` - -Deploy the corresponding l2 token address given l1 token address. - -*This function should only be called by owner to avoid DDoS attack on StandardTokenBridge.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _gateway | address | The address of gateway contract. | -| _l1Token | address | The address of l1 token. | - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### implementation - -```solidity -function implementation() external view returns (address) -``` - -The address of `ScrollStandardERC20` implementation. - - - - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### owner - -```solidity -function owner() external view returns (address) -``` - - - -*Returns the address of the current owner.* - - -#### Returns - -| Name | Type | Description | -|---|---|---| -| _0 | address | undefined | - -### renounceOwnership - -```solidity -function renounceOwnership() external nonpayable -``` - - - -*Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner.* - - -### transferOwnership - -```solidity -function transferOwnership(address newOwner) external nonpayable -``` - - - -*Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.* - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| newOwner | address | undefined | - - - -## Events - -### DeployToken - -```solidity -event DeployToken(address indexed _l1Token, address indexed _l2Token) -``` - -Emitted when a l2 token is deployed. - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| _l1Token `indexed` | address | The address of the l1 token. | -| _l2Token `indexed` | address | The address of the l2 token. | - -### OwnershipTransferred - -```solidity -event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -``` - - - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| previousOwner `indexed` | address | undefined | -| newOwner `indexed` | address | undefined | - - - diff --git a/contracts/foundry.toml b/contracts/foundry.toml deleted file mode 100644 index 21a95192f..000000000 --- a/contracts/foundry.toml +++ /dev/null @@ -1,30 +0,0 @@ -[profile.default] -src = 'src' # the source directory -test = 'src/test' # the test directory -script = 'scripts' # the script directory -out = 'artifacts/src' # the output directory (for artifacts) -libs = [] # a list of library directories -remappings = [] # a list of remappings -libraries = [] # a list of deployed libraries to link against -cache = true # whether to cache builds or not -force = true # whether to ignore the cache (clean build) -evm_version = 'cancun' # the evm version (by hardfork name) -solc_version = '0.8.24' # override for the solc version (setting this ignores `auto_detect_solc`) -optimizer = true # enable or disable the solc optimizer -optimizer_runs = 200 # the number of optimizer runs -verbosity = 2 # the verbosity of tests -ignored_error_codes = [] # a list of ignored solc error codes -fuzz_runs = 256 # the number of fuzz runs for tests -ffi = false # whether to enable ffi or not -sender = '0x00a329c0648769a73afac7f9381e08fb43dbea72' # the address of `msg.sender` in tests -tx_origin = '0x00a329c0648769a73afac7f9381e08fb43dbea72' # the address of `tx.origin` in tests -initial_balance = '0xffffffffffffffffffffffff' # the initial balance of the test contract -block_number = 0 # the block number we are at in tests -gas_limit = 9223372036854775807 # the gas limit in tests -gas_price = 0 # the gas price (in wei) in tests -block_base_fee_per_gas = 0 # the base fee (in wei) in tests -block_coinbase = '0x0000000000000000000000000000000000000000' # the address of `block.coinbase` in tests -block_timestamp = 0 # the value of `block.timestamp` in tests -block_difficulty = 0 # the value of `block.difficulty` in tests - -gas_reports = ["L2GasPriceOracle"] diff --git a/contracts/genesis.json.example b/contracts/genesis.json.example deleted file mode 100644 index 6db881ef4..000000000 --- a/contracts/genesis.json.example +++ /dev/null @@ -1,10 +0,0 @@ -{ - "blockHash": "0x3e721eda79f26bf40cd915aad0c85d501849215ad907d2e38acff524847300ab", - "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "baseFee": "0x3b9aca00", - "stateRoot": "0x183cbfdab83f8884b7cfbe234cb99bbd654d4fb18bd9c9f01e94ebf859957739", - "blockHeight": 0, - "gasUsed": 0, - "timestamp": "0x61bc34a0", - "extraData": "0x00000000000000000000000000000000000000000000000000000000000000004cb1ab63af5d8931ce09673ebd8ae2ce16fd6571adf5218f7ca8c80d90ff63af5fef486af57c20960000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" -} \ No newline at end of file diff --git a/contracts/hardhat.config.ts b/contracts/hardhat.config.ts deleted file mode 100644 index 07a5afe17..000000000 --- a/contracts/hardhat.config.ts +++ /dev/null @@ -1,151 +0,0 @@ -import * as dotenv from "dotenv"; - -import { HardhatUserConfig, subtask } from "hardhat/config"; -import * as toml from "toml"; -import "@nomicfoundation/hardhat-verify"; -import "@nomicfoundation/hardhat-ethers"; -import "@nomicfoundation/hardhat-chai-matchers"; -import "@typechain/hardhat"; -import "@primitivefi/hardhat-dodoc"; -import "hardhat-gas-reporter"; -import "solidity-coverage"; -import { readFileSync } from "fs"; -import { TASK_COMPILE_SOLIDITY_GET_SOURCE_PATHS } from "hardhat/builtin-tasks/task-names"; - -dotenv.config(); - -const L1_DEPLOYER_PRIVATE_KEY = process.env.L1_DEPLOYER_PRIVATE_KEY || "1".repeat(64); -const L2_DEPLOYER_PRIVATE_KEY = process.env.L2_DEPLOYER_PRIVATE_KEY || "1".repeat(64); - -const SOLC_DEFAULT = "0.8.24"; - -// try use forge config -let foundry: any; -try { - foundry = toml.parse(readFileSync("./foundry.toml").toString()); - foundry.default.solc = foundry.default["solc-version"] ? foundry.default["solc-version"] : SOLC_DEFAULT; -} catch (error) { - foundry = { - default: { - solc: SOLC_DEFAULT, - }, - }; -} - -// prune forge style tests from hardhat paths -subtask(TASK_COMPILE_SOLIDITY_GET_SOURCE_PATHS).setAction(async (_, __, runSuper) => { - const paths = await runSuper(); - return paths.filter((p: string) => !p.endsWith(".t.sol")).filter((p: string) => !p.includes("test/mocks")); -}); - -const config: HardhatUserConfig = { - solidity: { - version: foundry.default?.solc_version || SOLC_DEFAULT, - settings: { - optimizer: { - enabled: foundry.default?.optimizer || true, - runs: foundry.default?.optimizer_runs || 200, - }, - evmVersion: "cancun", - }, - }, - networks: { - ethereum: { - url: "https://1rpc.io/eth", - accounts: [L1_DEPLOYER_PRIVATE_KEY], - }, - sepolia: { - url: "https://1rpc.io/sepolia", - accounts: [L1_DEPLOYER_PRIVATE_KEY], - }, - scroll: { - url: "https://rpc.scroll.io", - accounts: [L2_DEPLOYER_PRIVATE_KEY], - }, - scroll_sepolia: { - url: "https://sepolia-rpc.scroll.io", - accounts: [L2_DEPLOYER_PRIVATE_KEY], - }, - }, - paths: { - cache: "./cache-hardhat", - sources: "./src", - tests: "./integration-test", - }, - typechain: { - outDir: "./typechain", - target: "ethers-v6", - }, - gasReporter: { - enabled: process.env.REPORT_GAS !== undefined, - excludeContracts: ["src/test"], - currency: "USD", - }, - etherscan: { - apiKey: { - ethereum: process.env.ETHERSCAN_API_KEY || "", - sepolia: process.env.ETHERSCAN_API_KEY || "", - scroll: process.env.SCROLLSCAN_API_KEY || "", - scroll_sepolia: process.env.SCROLLSCAN_API_KEY || "", - }, - customChains: [ - { - network: "scroll", - chainId: 534352, - urls: { - apiURL: "https://api.scrollscan.com/api", - browserURL: "https://www.scrollscan.com/", - }, - }, - { - network: "scroll_sepolia", - chainId: 534351, - urls: { - apiURL: "https://api-sepolia.scrollscan.com/api", - browserURL: "https://sepolia.scrollscan.com/", - }, - }, - ], - }, - mocha: { - timeout: 10000000, - }, - dodoc: { - runOnCompile: true, - keepFileStructure: false, - include: [ - "ScrollChain", - "L1ScrollMessenger", - "L2ScrollMessenger", - "L1GatewayRouter", - "L2GatewayRouter", - "L1StandardERC20Gateway", - "L2StandardERC20Gateway", - "L1ERC721Gateway", - "L2ERC721Gateway", - "L1ERC1155Gateway", - "L2ERC1155Gateway", - "L1WETHGateway", - "L2WETHGateway", - "ScrollStandardERC20Factory", - ], - outputDir: "docs/apis", - exclude: [ - "IERC677Receiver", - "IL1ScrollMessenger", - "IL2ScrollMessenger", - "IL1GatewayRouter", - "IL2GatewayRouter", - "IL1ERC721Gateway", - "IL2ERC721Gateway", - "IL1ERC1155Gateway", - "IL2ERC1155Gateway", - "IScrollStandardERC20Factory", - "IScrollChain", - "ScrollChainCommitmentVerifier", - "WETH9", - ], - }, -}; - -export default config; diff --git a/contracts/integration-test/EnforcedTxGateway.spec.ts b/contracts/integration-test/EnforcedTxGateway.spec.ts deleted file mode 100644 index 4dbd76baf..000000000 --- a/contracts/integration-test/EnforcedTxGateway.spec.ts +++ /dev/null @@ -1,455 +0,0 @@ -/* eslint-disable node/no-unpublished-import */ -/* eslint-disable node/no-missing-import */ -import { HardhatEthersSigner, SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; -import { expect } from "chai"; -import { BigNumberish, BytesLike, MaxUint256, ZeroAddress, getBytes } from "ethers"; -import { ethers } from "hardhat"; - -import { EnforcedTxGateway, L1MessageQueue, L2GasPriceOracle, MockCaller } from "../typechain"; - -describe("EnforcedTxGateway.spec", async () => { - let deployer: HardhatEthersSigner; - let feeVault: HardhatEthersSigner; - let signer: HardhatEthersSigner; - - let caller: MockCaller; - let gateway: EnforcedTxGateway; - let oracle: L2GasPriceOracle; - let queue: L1MessageQueue; - - const deployProxy = async (name: string, admin: string, args: any[]): Promise => { - const TransparentUpgradeableProxy = await ethers.getContractFactory("TransparentUpgradeableProxy", deployer); - const Factory = await ethers.getContractFactory(name, deployer); - const impl = args.length > 0 ? await Factory.deploy(...args) : await Factory.deploy(); - const proxy = await TransparentUpgradeableProxy.deploy(impl.getAddress(), admin, "0x"); - return proxy.getAddress(); - }; - - beforeEach(async () => { - [deployer, feeVault, signer] = await ethers.getSigners(); - - const ProxyAdmin = await ethers.getContractFactory("ProxyAdmin", deployer); - const admin = await ProxyAdmin.deploy(); - - gateway = await ethers.getContractAt( - "EnforcedTxGateway", - await deployProxy("EnforcedTxGateway", await admin.getAddress(), []), - deployer - ); - - queue = await ethers.getContractAt( - "L1MessageQueue", - await deployProxy("L1MessageQueue", await admin.getAddress(), [ - deployer.address, - deployer.address, - await gateway.getAddress(), - ]), - deployer - ); - - oracle = await ethers.getContractAt( - "L2GasPriceOracle", - await deployProxy("L2GasPriceOracle", await admin.getAddress(), []), - deployer - ); - - const MockCaller = await ethers.getContractFactory("MockCaller", deployer); - caller = await MockCaller.deploy(); - - await queue.initialize(ZeroAddress, ZeroAddress, ZeroAddress, oracle.getAddress(), 10000000); - await gateway.initialize(queue.getAddress(), feeVault.address); - await oracle.initialize(21000, 51000, 8, 16); - - const Whitelist = await ethers.getContractFactory("Whitelist", deployer); - const whitelist = await Whitelist.deploy(deployer.address); - - await whitelist.updateWhitelistStatus([deployer.address], true); - await oracle.updateWhitelist(whitelist.getAddress()); - await oracle.setL2BaseFee(1); - }); - - context("auth", async () => { - it("should initialize correctly", async () => { - expect(await gateway.owner()).to.eq(deployer.address); - expect(await gateway.messageQueue()).to.eq(await queue.getAddress()); - expect(await gateway.feeVault()).to.eq(feeVault.address); - expect(await gateway.paused()).to.eq(false); - }); - - it("should revert, when initialize again", async () => { - await expect(gateway.initialize(ZeroAddress, ZeroAddress)).to.revertedWith( - "Initializable: contract is already initialized" - ); - }); - - context("#updateFeeVault", async () => { - it("should revert, when non-owner call", async () => { - await expect(gateway.connect(signer).updateFeeVault(ZeroAddress)).to.revertedWith( - "Ownable: caller is not the owner" - ); - }); - - it("should succeed", async () => { - expect(await gateway.feeVault()).to.eq(feeVault.address); - await expect(gateway.updateFeeVault(deployer.address)) - .to.emit(gateway, "UpdateFeeVault") - .withArgs(feeVault.address, deployer.address); - expect(await gateway.feeVault()).to.eq(deployer.address); - }); - }); - - context("#setPause", async () => { - it("should revert, when non-owner call", async () => { - await expect(gateway.connect(signer).setPause(false)).to.revertedWith("Ownable: caller is not the owner"); - }); - - it("should succeed", async () => { - expect(await gateway.paused()).to.eq(false); - await expect(gateway.setPause(true)).to.emit(gateway, "Paused").withArgs(deployer.address); - expect(await gateway.paused()).to.eq(true); - await expect(gateway.setPause(false)).to.emit(gateway, "Unpaused").withArgs(deployer.address); - expect(await gateway.paused()).to.eq(false); - }); - }); - }); - - context("#sendTransaction, by EOA", async () => { - it("should revert, when contract is paused", async () => { - await gateway.setPause(true); - await expect( - gateway.connect(signer)["sendTransaction(address,uint256,uint256,bytes)"](signer.address, 0, 0, "0x") - ).to.revertedWith("Pausable: paused"); - }); - - it("should revert, when call is not EOA", async () => { - const calldata = gateway.interface.encodeFunctionData("sendTransaction(address,uint256,uint256,bytes)", [ - signer.address, - 0, - 0, - "0x", - ]); - await expect(caller.callTarget(gateway.getAddress(), calldata)).to.revertedWith( - "Only EOA senders are allowed to send enforced transaction" - ); - }); - - it("should revert, when insufficient value for fee", async () => { - const fee = await queue.estimateCrossDomainMessageFee(1000000); - await expect( - gateway - .connect(signer) - ["sendTransaction(address,uint256,uint256,bytes)"](signer.address, 0, 1000000, "0x", { value: fee - 1n }) - ).to.revertedWith("Insufficient value for fee"); - }); - - it("should revert, when failed to deduct the fee", async () => { - await gateway.updateFeeVault(gateway.getAddress()); - const fee = await queue.estimateCrossDomainMessageFee(1000000); - await expect( - gateway - .connect(signer) - ["sendTransaction(address,uint256,uint256,bytes)"](signer.address, 0, 1000000, "0x", { value: fee }) - ).to.revertedWith("Failed to deduct the fee"); - }); - - it("should succeed, no refund", async () => { - const fee = await queue.estimateCrossDomainMessageFee(1000000); - const feeVaultBalanceBefore = await ethers.provider.getBalance(feeVault.address); - await expect( - gateway - .connect(signer) - ["sendTransaction(address,uint256,uint256,bytes)"](deployer.address, 0, 1000000, "0x", { value: fee }) - ) - .to.emit(queue, "QueueTransaction") - .withArgs(signer.address, deployer.address, 0, 0, 1000000, "0x"); - const feeVaultBalanceAfter = await ethers.provider.getBalance(feeVault.address); - expect(feeVaultBalanceAfter - feeVaultBalanceBefore).to.eq(fee); - }); - - it("should succeed, with refund", async () => { - const fee = await queue.estimateCrossDomainMessageFee(1000000); - const feeVaultBalanceBefore = await ethers.provider.getBalance(feeVault.address); - const signerBalanceBefore = await ethers.provider.getBalance(signer.address); - const tx = await gateway - .connect(signer) - ["sendTransaction(address,uint256,uint256,bytes)"](deployer.address, 0, 1000000, "0x", { value: fee + 100n }); - await expect(tx) - .to.emit(queue, "QueueTransaction") - .withArgs(signer.address, deployer.address, 0, 0, 1000000, "0x"); - const receipt = await tx.wait(); - const feeVaultBalanceAfter = await ethers.provider.getBalance(feeVault.address); - const signerBalanceAfter = await ethers.provider.getBalance(signer.address); - expect(feeVaultBalanceAfter - feeVaultBalanceBefore).to.eq(fee); - expect(signerBalanceBefore - signerBalanceAfter).to.eq(receipt!.gasUsed * receipt!.gasPrice + fee); - }); - }); - - context("#sendTransaction, with signatures", async () => { - const getSignature = async ( - signer: SignerWithAddress, - target: string, - value: BigNumberish, - gasLimit: BigNumberish, - data: BytesLike - ) => { - const enforcedTx = { - sender: signer.address, - target, - value, - gasLimit, - data: getBytes(data), - nonce: await gateway.nonces(signer.address), - deadline: MaxUint256, - }; - - const domain = { - name: "EnforcedTxGateway", - version: "1", - chainId: (await ethers.provider.getNetwork()).chainId, - verifyingContract: await gateway.getAddress(), - }; - - const types = { - EnforcedTransaction: [ - { - name: "sender", - type: "address", - }, - { - name: "target", - type: "address", - }, - { - name: "value", - type: "uint256", - }, - { - name: "gasLimit", - type: "uint256", - }, - { - name: "data", - type: "bytes", - }, - { - name: "nonce", - type: "uint256", - }, - { - name: "deadline", - type: "uint256", - }, - ], - }; - - const signature = await signer.signTypedData(domain, types, enforcedTx); - return signature; - }; - - it("should revert, when contract is paused", async () => { - await gateway.setPause(true); - await expect( - gateway - .connect(deployer) - ["sendTransaction(address,address,uint256,uint256,bytes,uint256,bytes,address)"]( - signer.address, - signer.address, - 0, - 0, - "0x", - MaxUint256, - "0x", - ZeroAddress - ) - ).to.revertedWith("Pausable: paused"); - }); - - it("should revert, when signature expired", async () => { - const timestamp = (await ethers.provider.getBlock("latest"))!.timestamp; - await expect( - gateway - .connect(deployer) - ["sendTransaction(address,address,uint256,uint256,bytes,uint256,bytes,address)"]( - signer.address, - signer.address, - 0, - 0, - "0x", - timestamp - 1, - "0x", - ZeroAddress - ) - ).to.revertedWith("signature expired"); - }); - - it("should revert, when signature is wrong", async () => { - const signature = await signer.signMessage("0x00"); - await expect( - gateway - .connect(deployer) - ["sendTransaction(address,address,uint256,uint256,bytes,uint256,bytes,address)"]( - signer.address, - signer.address, - 0, - 0, - "0x", - MaxUint256, - signature, - ZeroAddress - ) - ).to.revertedWith("Incorrect signature"); - }); - - it("should revert, when insufficient value for fee", async () => { - const signature = await getSignature(signer, signer.address, 0, 1000000, "0x"); - const fee = await queue.estimateCrossDomainMessageFee(1000000); - await expect( - gateway - .connect(deployer) - ["sendTransaction(address,address,uint256,uint256,bytes,uint256,bytes,address)"]( - signer.address, - signer.address, - 0, - 1000000, - "0x", - MaxUint256, - signature, - signer.address, - { value: fee - 1n } - ) - ).to.revertedWith("Insufficient value for fee"); - }); - - it("should revert, when failed to deduct the fee", async () => { - await gateway.updateFeeVault(gateway.getAddress()); - const signature = await getSignature(signer, signer.address, 0, 1000000, "0x"); - const fee = await queue.estimateCrossDomainMessageFee(1000000); - await expect( - gateway - .connect(deployer) - ["sendTransaction(address,address,uint256,uint256,bytes,uint256,bytes,address)"]( - signer.address, - signer.address, - 0, - 1000000, - "0x", - MaxUint256, - signature, - signer.address, - { value: fee } - ) - ).to.revertedWith("Failed to deduct the fee"); - }); - - it("should succeed, no refund", async () => { - const signature = await getSignature(signer, deployer.address, 0, 1000000, "0x"); - const fee = await queue.estimateCrossDomainMessageFee(1000000); - const feeVaultBalanceBefore = await ethers.provider.getBalance(feeVault.address); - expect(await gateway.nonces(signer.address)).to.eq(0); - await expect( - gateway - .connect(deployer) - ["sendTransaction(address,address,uint256,uint256,bytes,uint256,bytes,address)"]( - signer.address, - deployer.address, - 0, - 1000000, - "0x", - MaxUint256, - signature, - signer.address, - { value: fee } - ) - ) - .to.emit(queue, "QueueTransaction") - .withArgs(signer.address, deployer.address, 0, 0, 1000000, "0x"); - expect(await gateway.nonces(signer.address)).to.eq(1); - const feeVaultBalanceAfter = await ethers.provider.getBalance(feeVault.address); - expect(feeVaultBalanceAfter - feeVaultBalanceBefore).to.eq(fee); - - // use the same nonce to sign should fail - await expect( - gateway - .connect(deployer) - ["sendTransaction(address,address,uint256,uint256,bytes,uint256,bytes,address)"]( - signer.address, - deployer.address, - 0, - 1000000, - "0x", - MaxUint256, - signature, - signer.address, - { value: fee } - ) - ).to.revertedWith("Incorrect signature"); - }); - - it("should succeed, with refund", async () => { - const signature = await getSignature(signer, deployer.address, 0, 1000000, "0x"); - const fee = await queue.estimateCrossDomainMessageFee(1000000); - const feeVaultBalanceBefore = await ethers.provider.getBalance(feeVault.address); - const signerBalanceBefore = await ethers.provider.getBalance(signer.address); - expect(await gateway.nonces(signer.address)).to.eq(0); - await expect( - gateway - .connect(deployer) - ["sendTransaction(address,address,uint256,uint256,bytes,uint256,bytes,address)"]( - signer.address, - deployer.address, - 0, - 1000000, - "0x", - MaxUint256, - signature, - signer.address, - { value: fee + 100n } - ) - ) - .to.emit(queue, "QueueTransaction") - .withArgs(signer.address, deployer.address, 0, 0, 1000000, "0x"); - expect(await gateway.nonces(signer.address)).to.eq(1); - const feeVaultBalanceAfter = await ethers.provider.getBalance(feeVault.address); - const signerBalanceAfter = await ethers.provider.getBalance(signer.address); - expect(feeVaultBalanceAfter - feeVaultBalanceBefore).to.eq(fee); - expect(signerBalanceAfter - signerBalanceBefore).to.eq(100n); - - // use the same nonce to sign should fail - await expect( - gateway - .connect(deployer) - ["sendTransaction(address,address,uint256,uint256,bytes,uint256,bytes,address)"]( - signer.address, - deployer.address, - 0, - 1000000, - "0x", - MaxUint256, - signature, - signer.address, - { value: fee + 100n } - ) - ).to.revertedWith("Incorrect signature"); - }); - - it("should revert, when refund failed", async () => { - const signature = await getSignature(signer, signer.address, 0, 1000000, "0x1234"); - const fee = await queue.estimateCrossDomainMessageFee(1000000); - await expect( - gateway - .connect(deployer) - ["sendTransaction(address,address,uint256,uint256,bytes,uint256,bytes,address)"]( - signer.address, - signer.address, - 0, - 1000000, - "0x1234", - MaxUint256, - signature, - gateway.getAddress(), - { value: fee + 100n } - ) - ).to.revertedWith("Failed to refund the fee"); - }); - }); -}); diff --git a/contracts/integration-test/GasOptimizationUpgrade.spec.ts b/contracts/integration-test/GasOptimizationUpgrade.spec.ts deleted file mode 100644 index b641bb2ec..000000000 --- a/contracts/integration-test/GasOptimizationUpgrade.spec.ts +++ /dev/null @@ -1,661 +0,0 @@ -/* eslint-disable node/no-missing-import */ -/* eslint-disable node/no-unpublished-import */ -import { HardhatEthersSigner } from "@nomicfoundation/hardhat-ethers/signers"; -import { expect } from "chai"; -import { BigNumberish, ContractTransactionResponse, MaxUint256, keccak256, toQuantity } from "ethers"; -import { ethers, network } from "hardhat"; - -import { - ProxyAdmin, - L1GatewayRouter, - L2ScrollMessenger, - L1ScrollMessenger, - L1MessageQueueWithGasPriceOracle, - L2GatewayRouter, -} from "../typechain"; - -describe("GasOptimizationUpgrade.spec", async () => { - const L1_ROUTER = "0xF8B1378579659D8F7EE5f3C929c2f3E332E41Fd6"; - const L2_ROUTER = "0x4C0926FF5252A435FD19e10ED15e5a249Ba19d79"; - const L1_MESSENGER = "0x6774Bcbd5ceCeF1336b5300fb5186a12DDD8b367"; - const L2_MESSENGER = "0x781e90f1c8Fc4611c9b7497C3B47F99Ef6969CbC"; - const L1_MESSAGE_QUEUE = "0x0d7E906BD9cAFa154b048cFa766Cc1E54E39AF9B"; - const L2_MESSAGE_QUEUE = "0x5300000000000000000000000000000000000000"; - const SCROLL_CHAIN = "0xa13BAF47339d63B743e7Da8741db5456DAc1E556"; - - let deployer: HardhatEthersSigner; - - let proxyAdmin: ProxyAdmin; - - const mockERC20Balance = async (tokenAddress: string, balance: bigint, slot: BigNumberish) => { - const storageSlot = keccak256( - ethers.AbiCoder.defaultAbiCoder().encode(["address", "uint256"], [deployer.address, slot]) - ); - await ethers.provider.send("hardhat_setStorageAt", [tokenAddress, storageSlot, toQuantity(balance)]); - const token = await ethers.getContractAt("MockERC20", tokenAddress, deployer); - expect(await token.balanceOf(deployer.address)).to.eq(balance); - }; - - const mockETHBalance = async (balance: bigint) => { - await network.provider.send("hardhat_setBalance", [deployer.address, toQuantity(balance)]); - expect(await ethers.provider.getBalance(deployer.address)).to.eq(balance); - }; - - const showGasUsage = async (tx: ContractTransactionResponse, desc: string) => { - const receipt = await tx.wait(); - console.log(`${desc}: GasUsed[${receipt!.gasUsed}]`); - }; - - context("L1 upgrade", async () => { - let forkBlock: number; - let router: L1GatewayRouter; - let messenger: L1ScrollMessenger; - let queue: L1MessageQueueWithGasPriceOracle; - - beforeEach(async () => { - // fork network - const provider = new ethers.JsonRpcProvider("https://rpc.ankr.com/eth"); - if (!forkBlock) { - forkBlock = (await provider.getBlockNumber()) - 10; - } - await network.provider.request({ - method: "hardhat_reset", - params: [ - { - forking: { - jsonRpcUrl: "https://rpc.ankr.com/eth", - blockNumber: forkBlock, - }, - }, - ], - }); - await network.provider.request({ - method: "hardhat_impersonateAccount", - params: ["0x1100000000000000000000000000000000000011"], - }); - - // mock eth balance - deployer = await ethers.getSigner("0x1100000000000000000000000000000000000011"); - await mockETHBalance(ethers.parseEther("1000")); - - // mock owner of proxy admin - proxyAdmin = await ethers.getContractAt("ProxyAdmin", "0xEB803eb3F501998126bf37bB823646Ed3D59d072", deployer); - await ethers.provider.send("hardhat_setStorageAt", [ - await proxyAdmin.getAddress(), - "0x0", - ethers.AbiCoder.defaultAbiCoder().encode(["address"], [deployer.address]), - ]); - expect(await proxyAdmin.owner()).to.eq(deployer.address); - - router = await ethers.getContractAt("L1GatewayRouter", L1_ROUTER, deployer); - messenger = await ethers.getContractAt("L1ScrollMessenger", L1_MESSENGER, deployer); - queue = await ethers.getContractAt("L1MessageQueueWithGasPriceOracle", L1_MESSAGE_QUEUE, deployer); - }); - - const upgradeL1 = async (proxy: string, impl: string) => { - await proxyAdmin.upgrade(proxy, impl); - const L1ScrollMessenger = await ethers.getContractFactory("L1ScrollMessenger", deployer); - const L1MessageQueueWithGasPriceOracle = await ethers.getContractFactory( - "L1MessageQueueWithGasPriceOracle", - deployer - ); - const ScrollChain = await ethers.getContractFactory("ScrollChain", deployer); - await proxyAdmin.upgrade( - L1_MESSENGER, - (await L1ScrollMessenger.deploy(L2_MESSENGER, SCROLL_CHAIN, L1_MESSAGE_QUEUE)).getAddress() - ); - await proxyAdmin.upgrade( - L1_MESSAGE_QUEUE, - ( - await L1MessageQueueWithGasPriceOracle.deploy( - L1_MESSENGER, - SCROLL_CHAIN, - "0x72CAcBcfDe2d1e19122F8A36a4d6676cd39d7A5d" - ) - ).getAddress() - ); - await queue.initializeV2(); - await proxyAdmin.upgrade( - SCROLL_CHAIN, - (await ScrollChain.deploy(534352, L1_MESSAGE_QUEUE, "0xA2Ab526e5C5491F10FC05A55F064BF9F7CEf32a0")).getAddress() - ); - }; - - it.skip("should succeed on L1ETHGateway", async () => { - const L1_GATEWAY = "0x7F2b8C31F88B6006c382775eea88297Ec1e3E905"; - const L2_GATEWAY = "0x6EA73e05AdC79974B931123675ea8F78FfdacDF0"; - const L1ETHGateway = await ethers.getContractFactory("L1ETHGateway", deployer); - const impl = await L1ETHGateway.deploy(L2_GATEWAY, L1_ROUTER, L1_MESSENGER); - const gateway = await ethers.getContractAt("L1ETHGateway", L1_GATEWAY, deployer); - const amountIn = ethers.parseEther("1"); - const fee = await queue.estimateCrossDomainMessageFee(1e6); - - // before upgrade - await showGasUsage( - await gateway["depositETH(uint256,uint256)"](amountIn, 1e6, { value: amountIn + fee }), - "L1ETHGateway.depositETH before upgrade" - ); - await showGasUsage( - await router["depositETH(uint256,uint256)"](amountIn, 1e6, { value: amountIn + fee }), - "L1GatewayRouter.depositETH before upgrade" - ); - await showGasUsage( - await messenger["sendMessage(address,uint256,bytes,uint256)"](deployer.address, amountIn, "0x", 1e6, { - value: amountIn + fee, - }), - "L1ScrollMessenger.sendMessage before upgrade" - ); - - // do upgrade - await upgradeL1(L1_GATEWAY, await impl.getAddress()); - - // after upgrade - await showGasUsage( - await gateway["depositETH(uint256,uint256)"](amountIn, 1e6, { value: amountIn + fee }), - "L1ETHGateway.depositETH after upgrade" - ); - await showGasUsage( - await router["depositETH(uint256,uint256)"](amountIn, 1e6, { value: amountIn + fee }), - "L1GatewayRouter.depositETH after upgrade" - ); - await showGasUsage( - await messenger["sendMessage(address,uint256,bytes,uint256)"](deployer.address, amountIn, "0x", 1e6, { - value: amountIn + fee, - }), - "L1ScrollMessenger.sendMessage after upgrade" - ); - }); - - it.skip("should succeed on L1WETHGateway", async () => { - const L1_WETH = "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"; - const L2_WETH = "0x5300000000000000000000000000000000000004"; - const L1_GATEWAY = "0x7AC440cAe8EB6328de4fA621163a792c1EA9D4fE"; - const L2_GATEWAY = "0x7003E7B7186f0E6601203b99F7B8DECBfA391cf9"; - const L1WETHGateway = await ethers.getContractFactory("L1WETHGateway", deployer); - const impl = await L1WETHGateway.deploy(L1_WETH, L2_WETH, L2_GATEWAY, L1_ROUTER, L1_MESSENGER); - const gateway = await ethers.getContractAt("L1WETHGateway", L1_GATEWAY, deployer); - const amountIn = ethers.parseEther("1"); - const fee = await queue.estimateCrossDomainMessageFee(1e6); - const token = await ethers.getContractAt("MockERC20", L1_WETH, deployer); - await mockERC20Balance(await token.getAddress(), amountIn * 10n, 3); - await token.approve(L1_GATEWAY, MaxUint256); - await token.approve(L1_ROUTER, MaxUint256); - - // before upgrade - await showGasUsage( - await gateway["depositERC20(address,uint256,uint256)"](L1_WETH, amountIn, 1e6, { value: fee }), - "L1WETHGateway.depositERC20 WETH before upgrade" - ); - await showGasUsage( - await router["depositERC20(address,uint256,uint256)"](L1_WETH, amountIn, 1e6, { value: fee }), - "L1GatewayRouter.depositERC20 WETH before upgrade" - ); - - // do upgrade - await upgradeL1(L1_GATEWAY, await impl.getAddress()); - - // after upgrade - await showGasUsage( - await gateway["depositERC20(address,uint256,uint256)"](L1_WETH, amountIn, 1e6, { value: fee }), - "L1WETHGateway.depositERC20 WETH after upgrade" - ); - await showGasUsage( - await router["depositERC20(address,uint256,uint256)"](L1_WETH, amountIn, 1e6, { value: fee }), - "L1GatewayRouter.depositERC20 WETH after upgrade" - ); - }); - - it.skip("should succeed on L1StandardERC20Gateway", async () => { - const L1_USDT = "0xdAC17F958D2ee523a2206206994597C13D831ec7"; - const L1_GATEWAY = "0xD8A791fE2bE73eb6E6cF1eb0cb3F36adC9B3F8f9"; - const L2_GATEWAY = "0xE2b4795039517653c5Ae8C2A9BFdd783b48f447A"; - const L1StandardERC20Gateway = await ethers.getContractFactory("L1StandardERC20Gateway", deployer); - const impl = await L1StandardERC20Gateway.deploy( - L2_GATEWAY, - L1_ROUTER, - L1_MESSENGER, - "0xC7d86908ccf644Db7C69437D5852CedBC1aD3f69", - "0x66e5312EDeEAef6e80759A0F789e7914Fb401484" - ); - const gateway = await ethers.getContractAt("L1StandardERC20Gateway", L1_GATEWAY, deployer); - const amountIn = ethers.parseUnits("1", 6); - const fee = await queue.estimateCrossDomainMessageFee(1e6); - const token = await ethers.getContractAt("MockERC20", L1_USDT, deployer); - await mockERC20Balance(await token.getAddress(), amountIn * 10n, 2); - await token.approve(L1_GATEWAY, MaxUint256); - await token.approve(L1_ROUTER, MaxUint256); - - // before upgrade - await showGasUsage( - await gateway["depositERC20(address,uint256,uint256)"](L1_USDT, amountIn, 1e6, { value: fee }), - "L1StandardERC20Gateway.depositERC20 USDT before upgrade" - ); - await showGasUsage( - await router["depositERC20(address,uint256,uint256)"](L1_USDT, amountIn, 1e6, { value: fee }), - "L1GatewayRouter.depositERC20 USDT before upgrade" - ); - - // do upgrade - await upgradeL1(L1_GATEWAY, await impl.getAddress()); - - // after upgrade - await showGasUsage( - await gateway["depositERC20(address,uint256,uint256)"](L1_USDT, amountIn, 1e6, { value: fee }), - "L1StandardERC20Gateway.depositERC20 USDT after upgrade" - ); - await showGasUsage( - await router["depositERC20(address,uint256,uint256)"](L1_USDT, amountIn, 1e6, { value: fee }), - "L1GatewayRouter.depositERC20 USDT after upgrade" - ); - }); - - it.skip("should succeed on L1CustomERC20Gateway", async () => { - const L1_DAI = "0x6B175474E89094C44Da98b954EedeAC495271d0F"; - const L1_GATEWAY = "0x67260A8B73C5B77B55c1805218A42A7A6F98F515"; - const L2_GATEWAY = "0xaC78dff3A87b5b534e366A93E785a0ce8fA6Cc62"; - const L1CustomERC20Gateway = await ethers.getContractFactory("L1CustomERC20Gateway", deployer); - const impl = await L1CustomERC20Gateway.deploy(L2_GATEWAY, L1_ROUTER, L1_MESSENGER); - const gateway = await ethers.getContractAt("L1CustomERC20Gateway", L1_GATEWAY, deployer); - const amountIn = ethers.parseUnits("1", 18); - const fee = await queue.estimateCrossDomainMessageFee(1e6); - const token = await ethers.getContractAt("MockERC20", L1_DAI, deployer); - await mockERC20Balance(await token.getAddress(), amountIn * 10n, 2); - await token.approve(L1_GATEWAY, MaxUint256); - await token.approve(L1_ROUTER, MaxUint256); - - // before upgrade - await showGasUsage( - await gateway["depositERC20(address,uint256,uint256)"](L1_DAI, amountIn, 1e6, { value: fee }), - "L1CustomERC20Gateway.depositERC20 DAI before upgrade" - ); - await showGasUsage( - await router["depositERC20(address,uint256,uint256)"](L1_DAI, amountIn, 1e6, { value: fee }), - "L1GatewayRouter.depositERC20 DAI before upgrade" - ); - - // do upgrade - await upgradeL1(L1_GATEWAY, await impl.getAddress()); - - // after upgrade - await showGasUsage( - await gateway["depositERC20(address,uint256,uint256)"](L1_DAI, amountIn, 1e6, { value: fee }), - "L1CustomERC20Gateway.depositERC20 DAI after upgrade" - ); - await showGasUsage( - await router["depositERC20(address,uint256,uint256)"](L1_DAI, amountIn, 1e6, { value: fee }), - "L1GatewayRouter.depositERC20 DAI after upgrade" - ); - }); - - it.skip("should succeed on L1USDCGateway", async () => { - const L1_USDC = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"; - const L2_USDC = "0x06eFdBFf2a14a7c8E15944D1F4A48F9F95F663A4"; - const L1_GATEWAY = "0xf1AF3b23DE0A5Ca3CAb7261cb0061C0D779A5c7B"; - const L2_GATEWAY = "0x33B60d5Dd260d453cAC3782b0bDC01ce84672142"; - const L1USDCGateway = await ethers.getContractFactory("L1USDCGateway", deployer); - const impl = await L1USDCGateway.deploy(L1_USDC, L2_USDC, L2_GATEWAY, L1_ROUTER, L1_MESSENGER); - const gateway = await ethers.getContractAt("L1USDCGateway", L1_GATEWAY, deployer); - const amountIn = ethers.parseUnits("1", 6); - const fee = await queue.estimateCrossDomainMessageFee(1e6); - const token = await ethers.getContractAt("MockERC20", L1_USDC, deployer); - await mockERC20Balance(await token.getAddress(), amountIn * 10n, 9); - await token.approve(L1_GATEWAY, MaxUint256); - await token.approve(L1_ROUTER, MaxUint256); - - // before upgrade - await showGasUsage( - await gateway["depositERC20(address,uint256,uint256)"](L1_USDC, amountIn, 1e6, { value: fee }), - "L1USDCGateway.depositERC20 USDC before upgrade" - ); - await showGasUsage( - await router["depositERC20(address,uint256,uint256)"](L1_USDC, amountIn, 1e6, { value: fee }), - "L1GatewayRouter.depositERC20 USDC before upgrade" - ); - - // do upgrade - await upgradeL1(L1_GATEWAY, await impl.getAddress()); - - // after upgrade - await showGasUsage( - await gateway["depositERC20(address,uint256,uint256)"](L1_USDC, amountIn, 1e6, { value: fee }), - "L1USDCGateway.depositERC20 USDC after upgrade" - ); - await showGasUsage( - await router["depositERC20(address,uint256,uint256)"](L1_USDC, amountIn, 1e6, { value: fee }), - "L1GatewayRouter.depositERC20 USDC after upgrade" - ); - }); - - it.skip("should succeed on L1LidoGateway", async () => { - const L1_WSTETH = "0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0"; - const L2_WSTETH = "0xf610A9dfB7C89644979b4A0f27063E9e7d7Cda32"; - const L1_GATEWAY = "0x6625C6332c9F91F2D27c304E729B86db87A3f504"; - const L2_GATEWAY = "0x8aE8f22226B9d789A36AC81474e633f8bE2856c9"; - const L1LidoGateway = await ethers.getContractFactory("L1LidoGateway", deployer); - const impl = await L1LidoGateway.deploy(L1_WSTETH, L2_WSTETH, L2_GATEWAY, L1_ROUTER, L1_MESSENGER); - const gateway = await ethers.getContractAt("L1LidoGateway", L1_GATEWAY, deployer); - const amountIn = ethers.parseUnits("1", 6); - const fee = await queue.estimateCrossDomainMessageFee(1e6); - const token = await ethers.getContractAt("MockERC20", L1_WSTETH, deployer); - await mockERC20Balance(await token.getAddress(), amountIn * 10n, 0); - await token.approve(L1_GATEWAY, MaxUint256); - await token.approve(L1_ROUTER, MaxUint256); - - // before upgrade - await showGasUsage( - await gateway["depositERC20(address,uint256,uint256)"](L1_WSTETH, amountIn, 1e6, { value: fee }), - "L1LidoGateway.depositERC20 wstETH before upgrade" - ); - await showGasUsage( - await router["depositERC20(address,uint256,uint256)"](L1_WSTETH, amountIn, 1e6, { value: fee }), - "L1GatewayRouter.depositERC20 wstETH before upgrade" - ); - - // do upgrade - await upgradeL1(L1_GATEWAY, await impl.getAddress()); - await gateway.initializeV2(deployer.address, deployer.address, deployer.address, deployer.address); - - // after upgrade - await showGasUsage( - await gateway["depositERC20(address,uint256,uint256)"](L1_WSTETH, amountIn, 1e6, { value: fee }), - "L1LidoGateway.depositERC20 wstETH after upgrade" - ); - await showGasUsage( - await router["depositERC20(address,uint256,uint256)"](L1_WSTETH, amountIn, 1e6, { value: fee }), - "L1GatewayRouter.depositERC20 wstETH after upgrade" - ); - }); - }); - - context("L2 upgrade", async () => { - let forkBlock: number; - let router: L2GatewayRouter; - let messenger: L2ScrollMessenger; - - beforeEach(async () => { - // fork network - const provider = new ethers.JsonRpcProvider("https://rpc.scroll.io"); - if (!forkBlock) { - forkBlock = (await provider.getBlockNumber()) - 31; - } - await network.provider.request({ - method: "hardhat_reset", - params: [ - { - forking: { - jsonRpcUrl: "https://rpc.scroll.io", - blockNumber: forkBlock, - }, - }, - ], - }); - await network.provider.request({ - method: "hardhat_impersonateAccount", - params: ["0x1100000000000000000000000000000000000011"], - }); - - // mock eth balance - deployer = await ethers.getSigner("0x1100000000000000000000000000000000000011"); - await mockETHBalance(ethers.parseEther("1000")); - - // mock owner of proxy admin - proxyAdmin = await ethers.getContractAt("ProxyAdmin", "0xA76acF000C890b0DD7AEEf57627d9899F955d026", deployer); - await ethers.provider.send("hardhat_setStorageAt", [ - await proxyAdmin.getAddress(), - "0x0", - ethers.AbiCoder.defaultAbiCoder().encode(["address"], [deployer.address]), - ]); - expect(await proxyAdmin.owner()).to.eq(deployer.address); - - router = await ethers.getContractAt("L2GatewayRouter", L2_ROUTER, deployer); - messenger = await ethers.getContractAt("L2ScrollMessenger", L2_MESSENGER, deployer); - }); - - const upgradeL2 = async (proxy: string, impl: string) => { - await proxyAdmin.upgrade(proxy, impl); - const L2ScrollMessenger = await ethers.getContractFactory("L2ScrollMessenger", deployer); - await proxyAdmin.upgrade( - L2_MESSENGER, - (await L2ScrollMessenger.deploy(L1_MESSENGER, L2_MESSAGE_QUEUE)).getAddress() - ); - }; - - it.skip("should succeed on L2ETHGateway", async () => { - const L1_GATEWAY = "0x7F2b8C31F88B6006c382775eea88297Ec1e3E905"; - const L2_GATEWAY = "0x6EA73e05AdC79974B931123675ea8F78FfdacDF0"; - const L2ETHGateway = await ethers.getContractFactory("L2ETHGateway", deployer); - const impl = await L2ETHGateway.deploy(L1_GATEWAY, L2_ROUTER, L2_MESSENGER); - const gateway = await ethers.getContractAt("L2ETHGateway", L2_GATEWAY, deployer); - const amountIn = ethers.parseEther("1"); - - // before upgrade - await showGasUsage( - await gateway["withdrawETH(uint256,uint256)"](amountIn, 1e6, { value: amountIn }), - "L2ETHGateway.withdrawETH before upgrade" - ); - await showGasUsage( - await router["withdrawETH(uint256,uint256)"](amountIn, 1e6, { value: amountIn }), - "L2GatewayRouter.withdrawETH before upgrade" - ); - await showGasUsage( - await messenger["sendMessage(address,uint256,bytes,uint256)"](deployer.address, amountIn, "0x", 1e6, { - value: amountIn, - }), - "L2ScrollMessenger.sendMessage before upgrade" - ); - - // do upgrade - await upgradeL2(L2_GATEWAY, await impl.getAddress()); - - // after upgrade - await showGasUsage( - await gateway["withdrawETH(uint256,uint256)"](amountIn, 1e6, { value: amountIn }), - "L2ETHGateway.withdrawETH after upgrade" - ); - await showGasUsage( - await router["withdrawETH(uint256,uint256)"](amountIn, 1e6, { value: amountIn }), - "L2GatewayRouter.withdrawETH after upgrade" - ); - await showGasUsage( - await messenger["sendMessage(address,uint256,bytes,uint256)"](deployer.address, amountIn, "0x", 1e6, { - value: amountIn, - }), - "L2ScrollMessenger.sendMessage after upgrade" - ); - }); - - it.skip("should succeed on L2WETHGateway", async () => { - const L1_WETH = "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"; - const L2_WETH = "0x5300000000000000000000000000000000000004"; - const L1_GATEWAY = "0x7AC440cAe8EB6328de4fA621163a792c1EA9D4fE"; - const L2_GATEWAY = "0x7003E7B7186f0E6601203b99F7B8DECBfA391cf9"; - const L2WETHGateway = await ethers.getContractFactory("L2WETHGateway", deployer); - const impl = await L2WETHGateway.deploy(L2_WETH, L1_WETH, L1_GATEWAY, L2_ROUTER, L2_MESSENGER); - const gateway = await ethers.getContractAt("L2WETHGateway", L2_GATEWAY, deployer); - const amountIn = ethers.parseEther("1"); - const token = await ethers.getContractAt("MockERC20", L2_WETH, deployer); - await mockERC20Balance(await token.getAddress(), amountIn * 10n, 0); - await token.approve(L2_GATEWAY, MaxUint256); - await token.approve(L2_ROUTER, MaxUint256); - - // before upgrade - await showGasUsage( - await gateway["withdrawERC20(address,uint256,uint256)"](L2_WETH, amountIn, 1e6), - "L2WETHGateway.withdrawERC20 WETH before upgrade" - ); - await showGasUsage( - await router["withdrawERC20(address,uint256,uint256)"](L2_WETH, amountIn, 1e6), - "L2GatewayRouter.withdrawERC20 WETH before upgrade" - ); - - // do upgrade - await upgradeL2(L2_GATEWAY, await impl.getAddress()); - - // after upgrade - await showGasUsage( - await gateway["withdrawERC20(address,uint256,uint256)"](L2_WETH, amountIn, 1e6), - "L2WETHGateway.withdrawERC20 WETH after upgrade" - ); - await showGasUsage( - await router["withdrawERC20(address,uint256,uint256)"](L2_WETH, amountIn, 1e6), - "L2GatewayRouter.withdrawERC20 WETH after upgrade" - ); - }); - - it.skip("should succeed on L2StandardERC20Gateway", async () => { - const L2_USDT = "0xf55BEC9cafDbE8730f096Aa55dad6D22d44099Df"; - const L1_GATEWAY = "0xD8A791fE2bE73eb6E6cF1eb0cb3F36adC9B3F8f9"; - const L2_GATEWAY = "0xE2b4795039517653c5Ae8C2A9BFdd783b48f447A"; - const L2StandardERC20Gateway = await ethers.getContractFactory("L2StandardERC20Gateway", deployer); - const impl = await L2StandardERC20Gateway.deploy( - L1_GATEWAY, - L2_ROUTER, - L2_MESSENGER, - "0x66e5312EDeEAef6e80759A0F789e7914Fb401484" - ); - const gateway = await ethers.getContractAt("L2StandardERC20Gateway", L2_GATEWAY, deployer); - const amountIn = ethers.parseUnits("1", 6); - const token = await ethers.getContractAt("MockERC20", L2_USDT, deployer); - await mockERC20Balance(await token.getAddress(), amountIn * 10n, 51); - await token.approve(L2_GATEWAY, MaxUint256); - await token.approve(L2_ROUTER, MaxUint256); - - // before upgrade - await showGasUsage( - await gateway["withdrawERC20(address,uint256,uint256)"](L2_USDT, amountIn, 1e6), - "L2StandardERC20Gateway.withdrawERC20 USDT before upgrade" - ); - await showGasUsage( - await router["withdrawERC20(address,uint256,uint256)"](L2_USDT, amountIn, 1e6), - "L2GatewayRouter.withdrawERC20 USDT before upgrade" - ); - - // do upgrade - await upgradeL2(L2_GATEWAY, await impl.getAddress()); - - // after upgrade - await showGasUsage( - await gateway["withdrawERC20(address,uint256,uint256)"](L2_USDT, amountIn, 1e6), - "L2StandardERC20Gateway.withdrawERC20 USDT after upgrade" - ); - await showGasUsage( - await router["withdrawERC20(address,uint256,uint256)"](L2_USDT, amountIn, 1e6), - "L2GatewayRouter.withdrawERC20 USDT after upgrade" - ); - }); - - it.skip("should succeed on L2CustomERC20Gateway", async () => { - const L2_DAI = "0xcA77eB3fEFe3725Dc33bccB54eDEFc3D9f764f97"; - const L1_GATEWAY = "0x67260A8B73C5B77B55c1805218A42A7A6F98F515"; - const L2_GATEWAY = "0xaC78dff3A87b5b534e366A93E785a0ce8fA6Cc62"; - const L2CustomERC20Gateway = await ethers.getContractFactory("L2CustomERC20Gateway", deployer); - const impl = await L2CustomERC20Gateway.deploy(L1_GATEWAY, L2_ROUTER, L2_MESSENGER); - const gateway = await ethers.getContractAt("L2CustomERC20Gateway", L2_GATEWAY, deployer); - const amountIn = ethers.parseUnits("1", 18); - const token = await ethers.getContractAt("MockERC20", L2_DAI, deployer); - await mockERC20Balance(await token.getAddress(), amountIn * 10n, 51); - await token.approve(L1_GATEWAY, MaxUint256); - await token.approve(L1_ROUTER, MaxUint256); - - // before upgrade - await showGasUsage( - await gateway["withdrawERC20(address,uint256,uint256)"](L2_DAI, amountIn, 1e6), - "L2CustomERC20Gateway.withdrawERC20 DAI before upgrade" - ); - await showGasUsage( - await router["withdrawERC20(address,uint256,uint256)"](L2_DAI, amountIn, 1e6), - "L2GatewayRouter.withdrawERC20 DAI before upgrade" - ); - - // do upgrade - await upgradeL2(L2_GATEWAY, await impl.getAddress()); - - // after upgrade - await showGasUsage( - await gateway["withdrawERC20(address,uint256,uint256)"](L2_DAI, amountIn, 1e6), - "L2CustomERC20Gateway.withdrawERC20 DAI after upgrade" - ); - await showGasUsage( - await router["withdrawERC20(address,uint256,uint256)"](L2_DAI, amountIn, 1e6), - "L2GatewayRouter.withdrawERC20 DAI after upgrade" - ); - }); - - it.skip("should succeed on L2USDCGateway", async () => { - const L1_USDC = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"; - const L2_USDC = "0x06eFdBFf2a14a7c8E15944D1F4A48F9F95F663A4"; - const L1_GATEWAY = "0xf1AF3b23DE0A5Ca3CAb7261cb0061C0D779A5c7B"; - const L2_GATEWAY = "0x33B60d5Dd260d453cAC3782b0bDC01ce84672142"; - const L2USDCGateway = await ethers.getContractFactory("L2USDCGateway", deployer); - const impl = await L2USDCGateway.deploy(L1_USDC, L2_USDC, L1_GATEWAY, L2_ROUTER, L2_MESSENGER); - const gateway = await ethers.getContractAt("L2USDCGateway", L2_GATEWAY, deployer); - const amountIn = ethers.parseUnits("1", 6); - const token = await ethers.getContractAt("MockERC20", L2_USDC, deployer); - await mockERC20Balance(await token.getAddress(), amountIn * 10n, 9); - await token.approve(L2_GATEWAY, MaxUint256); - await token.approve(L2_ROUTER, MaxUint256); - - // before upgrade - await showGasUsage( - await gateway["withdrawERC20(address,uint256,uint256)"](L2_USDC, amountIn, 1e6), - "L2USDCGateway.withdrawERC20 USDC before upgrade" - ); - await showGasUsage( - await router["withdrawERC20(address,uint256,uint256)"](L2_USDC, amountIn, 1e6), - "L2GatewayRouter.withdrawERC20 USDC before upgrade" - ); - - // do upgrade - await upgradeL2(L2_GATEWAY, await impl.getAddress()); - - // after upgrade - await showGasUsage( - await gateway["withdrawERC20(address,uint256,uint256)"](L2_USDC, amountIn, 1e6), - "L2USDCGateway.withdrawERC20 USDC after upgrade" - ); - await showGasUsage( - await router["withdrawERC20(address,uint256,uint256)"](L2_USDC, amountIn, 1e6), - "L2GatewayRouter.withdrawERC20 USDC after upgrade" - ); - }); - - it.skip("should succeed on L2LidoGateway", async () => { - const L1_WSTETH = "0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0"; - const L2_WSTETH = "0xf610A9dfB7C89644979b4A0f27063E9e7d7Cda32"; - const L1_GATEWAY = "0x6625C6332c9F91F2D27c304E729B86db87A3f504"; - const L2_GATEWAY = "0x8aE8f22226B9d789A36AC81474e633f8bE2856c9"; - const L2LidoGateway = await ethers.getContractFactory("L2LidoGateway", deployer); - const impl = await L2LidoGateway.deploy(L1_WSTETH, L2_WSTETH, L1_GATEWAY, L2_ROUTER, L2_MESSENGER); - const gateway = await ethers.getContractAt("L2LidoGateway", L2_GATEWAY, deployer); - const amountIn = ethers.parseUnits("1", 6); - const token = await ethers.getContractAt("MockERC20", L2_WSTETH, deployer); - await mockERC20Balance(await token.getAddress(), amountIn * 10n, 51); - await token.approve(L2_GATEWAY, MaxUint256); - await token.approve(L2_ROUTER, MaxUint256); - - // before upgrade - await showGasUsage( - await gateway["withdrawERC20(address,uint256,uint256)"](L2_WSTETH, amountIn, 1e6), - "L2LidoGateway.withdrawERC20 wstETH before upgrade" - ); - await showGasUsage( - await router["withdrawERC20(address,uint256,uint256)"](L2_WSTETH, amountIn, 1e6), - "L2GatewayRouter.withdrawERC20 wstETH before upgrade" - ); - - // do upgrade - await upgradeL2(L2_GATEWAY, await impl.getAddress()); - await gateway.initializeV2(deployer.address, deployer.address, deployer.address, deployer.address); - - // after upgrade - await showGasUsage( - await gateway["withdrawERC20(address,uint256,uint256)"](L2_WSTETH, amountIn, 1e6), - "L2LidoGateway.withdrawERC20 wstETH after upgrade" - ); - await showGasUsage( - await router["withdrawERC20(address,uint256,uint256)"](L2_WSTETH, amountIn, 1e6), - "L2GatewayRouter.withdrawERC20 wstETH after upgrade" - ); - }); - }); -}); diff --git a/contracts/integration-test/GasSwap.spec.ts b/contracts/integration-test/GasSwap.spec.ts deleted file mode 100644 index 4c98ab4ab..000000000 --- a/contracts/integration-test/GasSwap.spec.ts +++ /dev/null @@ -1,329 +0,0 @@ -/* eslint-disable node/no-unpublished-import */ -/* eslint-disable node/no-missing-import */ -import { HardhatEthersSigner } from "@nomicfoundation/hardhat-ethers/signers"; -import { expect } from "chai"; -import { MaxUint256, Signature, ZeroAddress, ZeroHash, toBigInt } from "ethers"; -import { ethers } from "hardhat"; - -import { GasSwap, ERC2771Forwarder, MockERC20, MockGasSwapTarget } from "../typechain"; - -describe("GasSwap.spec", async () => { - let deployer: HardhatEthersSigner; - let signer: HardhatEthersSigner; - - let forwarder: ERC2771Forwarder; - let swap: GasSwap; - let target: MockGasSwapTarget; - let token: MockERC20; - - beforeEach(async () => { - [deployer, signer] = await ethers.getSigners(); - - const ERC2771Forwarder = await ethers.getContractFactory("ERC2771Forwarder", deployer); - forwarder = await ERC2771Forwarder.deploy("ERC2771Forwarder"); - - const GasSwap = await ethers.getContractFactory("GasSwap", deployer); - swap = await GasSwap.deploy(forwarder.getAddress()); - - const MockGasSwapTarget = await ethers.getContractFactory("MockGasSwapTarget", deployer); - target = await MockGasSwapTarget.deploy(); - - const MockERC20 = await ethers.getContractFactory("MockERC20", deployer); - token = await MockERC20.deploy("x", "y", 18); - }); - - context("auth", async () => { - it("should initialize correctly", async () => { - expect(await swap.owner()).to.eq(deployer.address); - }); - - context("#updateFeeRatio", async () => { - it("should revert, when non-owner call", async () => { - await expect(swap.connect(signer).updateFeeRatio(1)).to.revertedWith("Ownable: caller is not the owner"); - }); - - it("should succeed", async () => { - expect(await swap.feeRatio()).to.eq(ZeroAddress); - await expect(swap.updateFeeRatio(100)).to.emit(swap, "UpdateFeeRatio").withArgs(100); - expect(await swap.feeRatio()).to.eq(100); - }); - }); - - context("#updateApprovedTarget", async () => { - it("should revert, when non-owner call", async () => { - await expect(swap.connect(signer).updateApprovedTarget(target.getAddress(), false)).to.revertedWith( - "Ownable: caller is not the owner" - ); - }); - - it("should succeed", async () => { - expect(await swap.approvedTargets(target.getAddress())).to.eq(false); - await expect(swap.updateApprovedTarget(target.getAddress(), true)) - .to.emit(swap, "UpdateApprovedTarget") - .withArgs(await target.getAddress(), true); - expect(await swap.approvedTargets(target.getAddress())).to.eq(true); - await expect(swap.updateApprovedTarget(target.getAddress(), false)) - .to.emit(swap, "UpdateApprovedTarget") - .withArgs(await target.getAddress(), false); - expect(await swap.approvedTargets(target.getAddress())).to.eq(false); - }); - }); - - context("#withdraw", async () => { - it("should revert, when non-owner call", async () => { - await expect(swap.connect(signer).withdraw(ZeroAddress, 0)).to.revertedWith("Ownable: caller is not the owner"); - }); - - it("should succeed, when withdraw ETH", async () => { - await deployer.sendTransaction({ to: swap.getAddress(), value: ethers.parseEther("1") }); - const balanceBefore = await ethers.provider.getBalance(deployer.address); - const tx = await swap.withdraw(ZeroAddress, ethers.parseEther("1")); - const receipt = await tx.wait(); - const balanceAfter = await ethers.provider.getBalance(deployer.address); - expect(balanceAfter - balanceBefore).to.eq(ethers.parseEther("1") - receipt!.gasUsed * receipt!.gasPrice); - }); - - it("should succeed, when withdraw token", async () => { - await token.mint(swap.getAddress(), ethers.parseEther("1")); - const balanceBefore = await token.balanceOf(deployer.address); - await swap.withdraw(token.getAddress(), ethers.parseEther("1")); - const balanceAfter = await token.balanceOf(deployer.address); - expect(balanceAfter - balanceBefore).to.eq(ethers.parseEther("1")); - }); - }); - }); - - const permit = async (amount: bigint) => { - const value = { - owner: signer.address, - spender: await swap.getAddress(), - value: amount, - nonce: await token.nonces(signer.address), - deadline: MaxUint256, - }; - - const domain = { - name: await token.name(), - version: "1", - chainId: (await ethers.provider.getNetwork()).chainId, - verifyingContract: await token.getAddress(), - }; - - const types = { - Permit: [ - { - name: "owner", - type: "address", - }, - { - name: "spender", - type: "address", - }, - { - name: "value", - type: "uint256", - }, - { - name: "nonce", - type: "uint256", - }, - { - name: "deadline", - type: "uint256", - }, - ], - }; - - const signature = Signature.from(await signer.signTypedData(domain, types, value)); - return signature; - }; - - context("swap", async () => { - it("should revert, when target not approved", async () => { - await expect( - swap.swap( - { - token: token.getAddress(), - value: 0, - deadline: 0, - r: ZeroHash, - s: ZeroHash, - v: 0, - }, - { - target: target.getAddress(), - data: "0x", - minOutput: 0, - } - ) - ).to.revertedWith("target not approved"); - }); - - it("should revert, when insufficient output amount", async () => { - const amountIn = ethers.parseEther("1"); - const amountOut = ethers.parseEther("2"); - await token.mint(signer.address, amountIn); - await deployer.sendTransaction({ to: target.getAddress(), value: amountOut }); - const signature = await permit(amountIn); - - await target.setToken(token.getAddress()); - await target.setAmountIn(amountIn); - - await swap.updateApprovedTarget(target.getAddress(), true); - await expect( - swap.connect(signer).swap( - { - token: await token.getAddress(), - value: amountIn, - deadline: MaxUint256, - r: signature.r, - s: signature.s, - v: signature.v, - }, - { - target: target.getAddress(), - data: "0x8119c065", - minOutput: amountOut + 1n, - } - ) - ).to.revertedWith("insufficient output amount"); - }); - - for (const refundRatio of [0n, 1n, 5n]) { - for (const feeRatio of ["0", "5", "50"]) { - it(`should succeed, when swap by signer directly, with feeRatio[${feeRatio}%] refundRatio[${refundRatio}%]`, async () => { - const amountIn = ethers.parseEther("1"); - const amountOut = ethers.parseEther("2"); - await token.mint(signer.address, amountIn); - await deployer.sendTransaction({ to: target.getAddress(), value: amountOut }); - const signature = await permit(amountIn); - - await target.setToken(token.getAddress()); - await target.setAmountIn(amountIn); - await target.setRefund((amountIn * refundRatio) / 100n); - - await swap.updateApprovedTarget(target.getAddress(), true); - await swap.updateFeeRatio(ethers.parseEther(feeRatio) / 100n); - const fee = (amountOut * toBigInt(feeRatio)) / 100n; - - const balanceBefore = await ethers.provider.getBalance(signer.address); - const tx = await swap.connect(signer).swap( - { - token: await token.getAddress(), - value: amountIn, - deadline: MaxUint256, - r: signature.r, - s: signature.s, - v: signature.v, - }, - { - target: target.getAddress(), - data: "0x8119c065", - minOutput: amountOut - fee, - } - ); - const receipt = await tx.wait(); - const balanceAfter = await ethers.provider.getBalance(signer.address); - expect(balanceAfter - balanceBefore).to.eq(amountOut - fee - receipt!.gasUsed * receipt!.gasPrice); - expect(await token.balanceOf(signer.address)).to.eq((amountIn * refundRatio) / 100n); - }); - - it(`should succeed, when swap by signer with forwarder, with feeRatio[${feeRatio}%] refundRatio[${refundRatio}%]`, async () => { - const amountIn = ethers.parseEther("1"); - const amountOut = ethers.parseEther("2"); - await token.mint(signer.address, amountIn); - await deployer.sendTransaction({ to: await target.getAddress(), value: amountOut }); - const permitSignature = await permit(amountIn); - - await target.setToken(token.getAddress()); - await target.setAmountIn(amountIn); - await target.setRefund((amountIn * refundRatio) / 100n); - - await swap.updateApprovedTarget(target.getAddress(), true); - await swap.updateFeeRatio(ethers.parseEther(feeRatio) / 100n); - const fee = (amountOut * toBigInt(feeRatio)) / 100n; - - const reqWithoutSignature = { - from: signer.address, - to: await swap.getAddress(), - value: 0n, - gas: 1000000, - nonce: await forwarder.nonces(signer.address), - deadline: 2000000000, - data: swap.interface.encodeFunctionData("swap", [ - { - token: await token.getAddress(), - value: amountIn, - deadline: MaxUint256, - r: permitSignature.r, - s: permitSignature.s, - v: permitSignature.v, - }, - { - target: await target.getAddress(), - data: "0x8119c065", - minOutput: amountOut - fee, - }, - ]), - }; - - const signature = await signer.signTypedData( - { - name: "ERC2771Forwarder", - version: "1", - chainId: (await ethers.provider.getNetwork()).chainId, - verifyingContract: await forwarder.getAddress(), - }, - { - ForwardRequest: [ - { - name: "from", - type: "address", - }, - { - name: "to", - type: "address", - }, - { - name: "value", - type: "uint256", - }, - { - name: "gas", - type: "uint256", - }, - { - name: "nonce", - type: "uint256", - }, - { - name: "deadline", - type: "uint48", - }, - { - name: "data", - type: "bytes", - }, - ], - }, - reqWithoutSignature - ); - - const balanceBefore = await ethers.provider.getBalance(signer.address); - await forwarder.execute({ - from: reqWithoutSignature.from, - to: reqWithoutSignature.to, - value: reqWithoutSignature.value, - gas: reqWithoutSignature.gas, - deadline: reqWithoutSignature.deadline, - data: reqWithoutSignature.data, - signature, - }); - const balanceAfter = await ethers.provider.getBalance(signer.address); - expect(balanceAfter - balanceBefore).to.eq(amountOut - fee); - expect(await token.balanceOf(signer.address)).to.eq((amountIn * refundRatio) / 100n); - }); - } - } - }); -}); diff --git a/contracts/integration-test/L1BlockContainer.spec.ts b/contracts/integration-test/L1BlockContainer.spec.ts deleted file mode 100644 index 257a7a850..000000000 --- a/contracts/integration-test/L1BlockContainer.spec.ts +++ /dev/null @@ -1,233 +0,0 @@ -/* eslint-disable node/no-unpublished-import */ -/* eslint-disable node/no-missing-import */ -import { expect } from "chai"; -import { BigNumberish, ZeroHash, concat, encodeRlp, toBeHex, toBigInt } from "ethers"; -import { ethers } from "hardhat"; - -import { L1BlockContainer } from "../typechain"; - -interface IImportTestConfig { - hash: string; - parentHash: string; - uncleHash: string; - coinbase: string; - stateRoot: string; - transactionsRoot: string; - receiptsRoot: string; - logsBloom: string; - difficulty: BigNumberish; - blockHeight: number; - gasLimit: BigNumberish; - gasUsed: BigNumberish; - blockTimestamp: number; - extraData: string; - mixHash: string; - blockNonce: string; - baseFee: BigNumberish; -} - -const testcases: Array = [ - { - hash: "0x02250e97ef862444dd1d70acbe925c289bb2acf20a808cb8f4d1409d3adcfa1b", - parentHash: "0x95e612b2a734f5a8c6aad3f6662b18f983ce8b653854d7c307bf999d9be323af", - uncleHash: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", - coinbase: "0x690b9a9e9aa1c9db991c7721a92d351db4fac990", - stateRoot: "0x8d77db2a63cee63ae6d793f839a7513dfc50194f325b96a5326d724f5dc16320", - transactionsRoot: "0xe4ce5f0e2fc5fd8a7ad55c2a31c522ded4054b89065c627d26230b45cd585fed", - receiptsRoot: "0x10b2f34da3e6a1db9498ab36bb17b063763b8eb33492ccc621491b33bcb62bdd", - logsBloom: - "0x18b80159addab073ac340045c4ef982442653840c8074a50159bd9626ae0590740d07273d0c859005b634059c8ca9bb18364573e7ebe79a40aa08225942370c3dc6c0af2ea33cba07900961de2b011aabb8024270d4626d1028a2f0dcd780c60ce933b169b02c8c329c18b000aaf08c98245d8ad949e7d61102d5516489fa924f390c3a71642d7e6044c85a20952568d60cf24c38baff04c244b10eac87a6da8bb32c1535ea2613064a246d598c02444624a8d5a1b201a4270a7868a97aa4530838c2e7a192a88e329daf0334c728b7c057f684f1d28c07d0d2c1dc63868a1088010ae0b661073142e468ae062151e00e5108400e1a99c4111153828610874bb", - difficulty: "0x0", - blockHeight: 0xf766a8, - gasLimit: "0x1c9c380", - gasUsed: "0xe6f194", - blockTimestamp: 0x639f69e3, - extraData: "0x406275696c64657230783639", - mixHash: "0xc1e37ce2b7ece4556ec87ea6d420a1a3610d49c58dfccec6998222fbf9cd64a2", - blockNonce: "0x0000000000000000", - baseFee: "0x2b96fa5cc", - }, - { - hash: "0x2da4bf7cef55d6207af2095db5543df16acbd95dc66eef02d9764277c5b0895d", - parentHash: "0xde18012932b21820fbb48ef85b46774873383e75b062bc0c6a4761fbe87bad13", - uncleHash: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", - coinbase: "0x690b9a9e9aa1c9db991c7721a92d351db4fac990", - stateRoot: "0x1f101f54c3df5630c9d45224c95d71a57479992e174cdbda0c4ada30e657a465", - transactionsRoot: "0xc2b29438a5f55998879356cbc8006a90d2ba88a9841b3894c8da5840dd797f19", - receiptsRoot: "0xbd3608b6af5464b446db44fd289a980f417447b31ff15dd6d48c72fc8f4fef8d", - logsBloom: - "0xd9e5f4f1e559388eb8193295ab2d3aab30c588d31e381c4060715d0a7ce607360b15d7a0d88e406c60135e0abcecd1d816c11f8cbbb2a80a9b4a00375d6cf356cb78f2934261ab09ea03df29dab5dbe4aefea506f7fd0eaa1a8b1fc8db5079613a49d80ca7e7997a20c7158399022c1dc9853f5b401b86587249fc96ca6fbc2dab1fdeb203ca258c94dd0bc821b38f9f60128591f3cd224c5c207b76b754e537bef8ebe731effae356235dd71bd7b5494bead124a8b5bb0ba02e46721d3ec3c20608880b1d35a17f6a1027d20c7b902e5d7b2ec8177b1aff9dcfbb4729d1e3201e78fa1b3c30e66a590cb5a7cac7afe0b0b1a6c94d5e39c9a20908358b805c81", - difficulty: "0x0", - blockHeight: 0xf766d8, - gasLimit: "0x1c9c380", - gasUsed: "0xf8adad", - blockTimestamp: 0x639f6c23, - extraData: "0x6275696c64657230783639", - mixHash: "0x6066061b78b385483d960faa29ee40e79ea67769f5e697ecb70a0fce677804af", - blockNonce: "0x0000000000000000", - baseFee: "0x2aca8b608", - }, - { - hash: "0x4ddeee3e8d62e961080711e48d8083f164789e78cc90e4362c133063b566d64a", - parentHash: "0x9d190c6d49352d628e321853967dd499d78c521daad73652ed1978db5652f58a", - uncleHash: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", - coinbase: "0xcd458d7f11023556cc9058f729831a038cb8df9c", - stateRoot: "0x3620665f9d094aac16e0762b733e814f4e09177a232f85d406271b60e4f2b58f", - transactionsRoot: "0x200f5acb65631c48c32c94ae95afe095134132939a01422da5c7c6d0e7f62cb3", - receiptsRoot: "0xc140420782bc76ff326d18b13427c991e9434a554b9ae82bbf09cca7b6ae4036", - logsBloom: - "0x00a8cd20c1402037d2a51100c0895279410502288134d22313912bb7b42e504f850f417d9000000a41949b284b40210406019c0e28122d462c05c11120ac2c680800c0348066a23e7a9e042a9d20e4e0041114830d443160a46b5e02ec300d41330cf0652602140e1580b4c82d1228c000005be72c900f7152093d93ca4880062185952cacc6c8d1405a0c5823bb4284a04a44c92b41462c2420a870685438809a99850acc936c408c24e882a01517086a20a067a2e4e01a20e106078828706c7c00a0234e6830c80b911900291a134475208a4335ab0018a9048d4628186043303b722a79645a104c0e12a506404f45c428660a105d105010482852540b9a6b", - difficulty: "0x2ae28b0d3154b6", - blockHeight: 0xecb6fc, - gasLimit: "0x1c9c30d", - gasUsed: "0xb93955", - blockTimestamp: 0x631d8207, - extraData: "0x706f6f6c696e2e636f6d2050cabdd319bf3175", - mixHash: "0x18d61005875e902e1bbba1045fd6701df170230c0ffb37f2e77fbc2051b987cf", - blockNonce: "0xe8775f73466671e3", - baseFee: "0x18c9de157", - }, -]; - -function encodeHeader(test: IImportTestConfig): string { - return encodeRlp([ - test.parentHash, - test.uncleHash, - test.coinbase, - test.stateRoot, - test.transactionsRoot, - test.receiptsRoot, - test.logsBloom, - toBigInt(test.difficulty) === 0n ? "0x" : toBeHex(test.difficulty), - toBeHex(test.blockHeight), - toBeHex(test.gasLimit), - toBeHex(test.gasUsed), - toBeHex(test.blockTimestamp), - test.extraData, - test.mixHash, - test.blockNonce, - toBeHex(test.baseFee), - ]); -} - -describe("L1BlockContainer", async () => { - let container: L1BlockContainer; - - for (const test of testcases) { - context(`import block[${test.hash}] height[${test.blockHeight}]`, async () => { - beforeEach(async () => { - const [deployer] = await ethers.getSigners(); - const L1BlockContainer = await ethers.getContractFactory("L1BlockContainer", deployer); - container = await L1BlockContainer.deploy(deployer.address); - - const Whitelist = await ethers.getContractFactory("Whitelist", deployer); - const whitelist = await Whitelist.deploy(deployer.address); - await whitelist.updateWhitelistStatus([deployer.address], true); - - await container.updateWhitelist(whitelist.getAddress()); - }); - - it("should revert, when sender not allowed", async () => { - const [, signer] = await ethers.getSigners(); - await container.initialize( - test.parentHash, - test.blockHeight - 1, - test.blockTimestamp - 1, - test.baseFee, - test.stateRoot - ); - - await expect(container.connect(signer).importBlockHeader(ZeroHash, "0x", false)).to.revertedWith( - "Not whitelisted sender" - ); - }); - - it("should revert, when block hash mismatch", async () => { - await container.initialize( - test.parentHash, - test.blockHeight - 1, - test.blockTimestamp - 1, - test.baseFee, - test.stateRoot - ); - const headerRLP = encodeHeader(test); - await expect(container.importBlockHeader(test.parentHash, headerRLP, false)).to.revertedWith( - "Block hash mismatch" - ); - }); - - it("should revert, when has extra bytes", async () => { - await container.initialize( - test.parentHash, - test.blockHeight - 1, - test.blockTimestamp - 1, - test.baseFee, - test.stateRoot - ); - const headerRLP = encodeHeader(test); - await expect(container.importBlockHeader(test.hash, concat([headerRLP, "0x00"]), false)).to.revertedWith( - "Header RLP length mismatch" - ); - }); - - it("should revert, when parent not imported", async () => { - await container.initialize( - ZeroHash, - test.blockHeight - 1, - test.blockTimestamp - 1, - test.baseFee, - test.stateRoot - ); - const headerRLP = encodeHeader(test); - await expect(container.importBlockHeader(test.hash, headerRLP, false)).to.revertedWith("Parent not imported"); - }); - - it("should revert, when block height mismatch", async () => { - await container.initialize( - test.parentHash, - test.blockHeight, - test.blockTimestamp - 1, - test.baseFee, - test.stateRoot - ); - const headerRLP = encodeHeader(test); - await expect(container.importBlockHeader(test.hash, headerRLP, false)).to.revertedWith("Block height mismatch"); - }); - - it("should revert, when parent block has larger timestamp", async () => { - await container.initialize( - test.parentHash, - test.blockHeight - 1, - test.blockTimestamp + 1, - test.baseFee, - test.stateRoot - ); - const headerRLP = encodeHeader(test); - await expect(container.importBlockHeader(test.hash, headerRLP, false)).to.revertedWith( - "Parent block has larger timestamp" - ); - }); - - it(`should succeed`, async () => { - await container.initialize( - test.parentHash, - test.blockHeight - 1, - test.blockTimestamp - 1, - test.baseFee, - test.stateRoot - ); - expect(await container.latestBlockHash()).to.eq(test.parentHash); - const headerRLP = encodeHeader(test); - await expect(container.importBlockHeader(test.hash, headerRLP, false)) - .to.emit(container, "ImportBlock") - .withArgs(test.hash, test.blockHeight, test.blockTimestamp, test.baseFee, test.stateRoot); - expect(await container.getStateRoot(test.hash)).to.eq(test.stateRoot); - expect(await container.getBlockTimestamp(test.hash)).to.eq(test.blockTimestamp); - expect(await container.latestBlockHash()).to.eq(test.hash); - expect(await container.latestBaseFee()).to.eq(test.baseFee); - expect(await container.latestBlockNumber()).to.eq(test.blockHeight); - expect(await container.latestBlockTimestamp()).to.eq(test.blockTimestamp); - }); - }); - } -}); diff --git a/contracts/integration-test/L1MessageQueue.spec.ts b/contracts/integration-test/L1MessageQueue.spec.ts deleted file mode 100644 index 33109a2d0..000000000 --- a/contracts/integration-test/L1MessageQueue.spec.ts +++ /dev/null @@ -1,393 +0,0 @@ -/* eslint-disable node/no-unpublished-import */ -/* eslint-disable node/no-missing-import */ -import { HardhatEthersSigner } from "@nomicfoundation/hardhat-ethers/signers"; -import { expect } from "chai"; -import { ethers } from "hardhat"; - -import { L1MessageQueue, L2GasPriceOracle } from "../typechain"; -import { - MaxUint256, - ZeroAddress, - concat, - encodeRlp, - getAddress, - hexlify, - keccak256, - randomBytes, - toBeHex, - toBigInt, -} from "ethers"; - -describe("L1MessageQueue", async () => { - let deployer: HardhatEthersSigner; - let scrollChain: HardhatEthersSigner; - let messenger: HardhatEthersSigner; - let gateway: HardhatEthersSigner; - let signer: HardhatEthersSigner; - - let oracle: L2GasPriceOracle; - let queue: L1MessageQueue; - - const deployProxy = async (name: string, admin: string, args: any[]): Promise => { - const TransparentUpgradeableProxy = await ethers.getContractFactory("TransparentUpgradeableProxy", deployer); - const Factory = await ethers.getContractFactory(name, deployer); - const impl = args.length > 0 ? await Factory.deploy(...args) : await Factory.deploy(); - const proxy = await TransparentUpgradeableProxy.deploy(impl.getAddress(), admin, "0x"); - return proxy.getAddress(); - }; - - beforeEach(async () => { - [deployer, scrollChain, messenger, gateway, signer] = await ethers.getSigners(); - - const ProxyAdmin = await ethers.getContractFactory("ProxyAdmin", deployer); - const admin = await ProxyAdmin.deploy(); - - queue = await ethers.getContractAt( - "L1MessageQueue", - await deployProxy("L1MessageQueue", await admin.getAddress(), [ - messenger.address, - scrollChain.address, - gateway.address, - ]), - deployer - ); - - oracle = await ethers.getContractAt( - "L2GasPriceOracle", - await deployProxy("L2GasPriceOracle", await admin.getAddress(), []), - deployer - ); - - await oracle.initialize(21000, 50000, 8, 16); - await queue.initialize(messenger.address, scrollChain.address, ZeroAddress, oracle.getAddress(), 10000000); - }); - - context("auth", async () => { - it("should initialize correctly", async () => { - expect(await queue.owner()).to.eq(deployer.address); - expect(await queue.messenger()).to.eq(messenger.address); - expect(await queue.scrollChain()).to.eq(scrollChain.address); - expect(await queue.enforcedTxGateway()).to.eq(gateway.address); - expect(await queue.gasOracle()).to.eq(await oracle.getAddress()); - expect(await queue.maxGasLimit()).to.eq(10000000); - }); - - it("should revert, when initialize again", async () => { - await expect(queue.initialize(ZeroAddress, ZeroAddress, ZeroAddress, ZeroAddress, 0)).to.revertedWith( - "Initializable: contract is already initialized" - ); - }); - - context("#updateGasOracle", async () => { - it("should revert, when non-owner call", async () => { - await expect(queue.connect(signer).updateGasOracle(ZeroAddress)).to.revertedWith( - "Ownable: caller is not the owner" - ); - }); - - it("should succeed", async () => { - expect(await queue.gasOracle()).to.eq(await oracle.getAddress()); - await expect(queue.updateGasOracle(deployer.address)) - .to.emit(queue, "UpdateGasOracle") - .withArgs(await oracle.getAddress(), deployer.address); - expect(await queue.gasOracle()).to.eq(deployer.address); - }); - }); - - context("#updateMaxGasLimit", async () => { - it("should revert, when non-owner call", async () => { - await expect(queue.connect(signer).updateMaxGasLimit(0)).to.revertedWith("Ownable: caller is not the owner"); - }); - - it("should succeed", async () => { - expect(await queue.maxGasLimit()).to.eq(10000000); - await expect(queue.updateMaxGasLimit(0)).to.emit(queue, "UpdateMaxGasLimit").withArgs(10000000, 0); - expect(await queue.maxGasLimit()).to.eq(0); - }); - }); - }); - - context("#computeTransactionHash", async () => { - it("should succeed", async () => { - const sender = "0xb2a70fab1a45b1b9be443b6567849a1702bc1232"; - const target = "0xcb18150e4efefb6786130e289a5f61a82a5b86d7"; - const transactionType = "0x7E"; - - for (const nonce of [0n, 1n, 127n, 128n, 22334455n, MaxUint256]) { - for (const value of [0n, 1n, 127n, 128n, 22334455n, MaxUint256]) { - for (const gasLimit of [0n, 1n, 127n, 128n, 22334455n, MaxUint256]) { - for (const dataLen of [0, 1, 2, 3, 4, 55, 56, 100]) { - const tests = [randomBytes(dataLen)]; - if (dataLen === 1) { - for (const byte of [0, 1, 127, 128]) { - tests.push(Uint8Array.from([byte])); - } - } - for (const data of tests) { - const transactionPayload = encodeRlp([ - nonce === 0n ? "0x" : toBeHex(nonce), - gasLimit === 0n ? "0x" : toBeHex(gasLimit), - target, - value === 0n ? "0x" : toBeHex(value), - data, - sender, - ]); - const payload = concat([transactionType, transactionPayload]); - const expectedHash = keccak256(payload); - const computedHash = await queue.computeTransactionHash(sender, nonce, value, target, gasLimit, data); - if (computedHash !== expectedHash) { - console.log(hexlify(transactionPayload)); - console.log(nonce, gasLimit, target, value, data, sender); - } - expect(expectedHash).to.eq(computedHash); - } - } - } - } - } - }); - }); - - context("#appendCrossDomainMessage", async () => { - it("should revert, when non-messenger call", async () => { - await expect(queue.connect(signer).appendCrossDomainMessage(ZeroAddress, 0, "0x")).to.revertedWith( - "Only callable by the L1ScrollMessenger" - ); - }); - - it("should revert, when exceed maxGasLimit", async () => { - await expect(queue.connect(messenger).appendCrossDomainMessage(ZeroAddress, 10000001, "0x")).to.revertedWith( - "Gas limit must not exceed maxGasLimit" - ); - }); - - it("should revert, when below intrinsic gas", async () => { - await expect(queue.connect(messenger).appendCrossDomainMessage(ZeroAddress, 0, "0x")).to.revertedWith( - "Insufficient gas limit, must be above intrinsic gas" - ); - }); - - it("should succeed", async () => { - expect(await queue.nextCrossDomainMessageIndex()).to.eq(0n); - const sender = getAddress( - toBeHex((toBigInt(messenger.address) + toBigInt("0x1111000000000000000000000000000000001111")) % 2n ** 160n) - .slice(2) - .padStart(40, "0") - ); - const hash = await queue.computeTransactionHash(sender, 0, 0, signer.address, 100000, "0x01"); - await expect(queue.connect(messenger).appendCrossDomainMessage(signer.address, 100000, "0x01")) - .to.emit(queue, "QueueTransaction") - .withArgs(sender, signer.address, 0, 0, 100000, "0x01"); - expect(await queue.nextCrossDomainMessageIndex()).to.eq(1n); - expect(await queue.getCrossDomainMessage(0)).to.eq(hash); - }); - }); - - context("#appendEnforcedTransaction", async () => { - it("should revert, when non-gateway call", async () => { - await expect( - queue.connect(signer).appendEnforcedTransaction(signer.address, ZeroAddress, 0, 0, "0x") - ).to.revertedWith("Only callable by the EnforcedTxGateway"); - }); - - it("should revert, when sender is not EOA", async () => { - await expect( - queue.connect(gateway).appendEnforcedTransaction(queue.getAddress(), ZeroAddress, 0, 0, "0x") - ).to.revertedWith("only EOA"); - }); - - it("should revert, when exceed maxGasLimit", async () => { - await expect( - queue.connect(gateway).appendEnforcedTransaction(signer.address, ZeroAddress, 0, 10000001, "0x") - ).to.revertedWith("Gas limit must not exceed maxGasLimit"); - }); - - it("should revert, when below intrinsic gas", async () => { - await expect( - queue.connect(gateway).appendEnforcedTransaction(signer.address, ZeroAddress, 0, 0, "0x") - ).to.revertedWith("Insufficient gas limit, must be above intrinsic gas"); - }); - - it("should succeed", async () => { - expect(await queue.nextCrossDomainMessageIndex()).to.eq(0n); - const sender = signer.address; - const hash = await queue.computeTransactionHash(sender, 0, 200, signer.address, 100000, "0x01"); - await expect( - queue.connect(gateway).appendEnforcedTransaction(signer.address, signer.address, 200, 100000, "0x01") - ) - .to.emit(queue, "QueueTransaction") - .withArgs(sender, signer.address, 200, 0, 100000, "0x01"); - expect(await queue.nextCrossDomainMessageIndex()).to.eq(1n); - expect(await queue.getCrossDomainMessage(0)).to.eq(hash); - }); - }); - - context("#popCrossDomainMessage", async () => { - it("should revert, when non-scrollChain call", async () => { - await expect(queue.connect(signer).popCrossDomainMessage(0, 0, 0)).to.revertedWith( - "Only callable by the ScrollChain" - ); - }); - - it("should revert, when pop too many messages", async () => { - await expect(queue.connect(scrollChain).popCrossDomainMessage(0, 257, 0)).to.revertedWith( - "pop too many messages" - ); - }); - - it("should revert, when start index mismatch", async () => { - await expect(queue.connect(scrollChain).popCrossDomainMessage(1, 256, 0)).to.revertedWith("start index mismatch"); - }); - - it("should succeed", async () => { - // append 512 messages - for (let i = 0; i < 256 * 2; i++) { - await queue.connect(messenger).appendCrossDomainMessage(ZeroAddress, 1000000, "0x"); - } - - // pop 50 messages with no skip - await expect(queue.connect(scrollChain).popCrossDomainMessage(0, 50, 0)) - .to.emit(queue, "DequeueTransaction") - .withArgs(0, 50, 0); - for (let i = 0; i < 50; i++) { - expect(await queue.isMessageSkipped(i)).to.eq(false); - expect(await queue.isMessageDropped(i)).to.eq(false); - } - expect(await queue.pendingQueueIndex()).to.eq(50); - - // pop 10 messages all skip - await expect(queue.connect(scrollChain).popCrossDomainMessage(50, 10, 1023)) - .to.emit(queue, "DequeueTransaction") - .withArgs(50, 10, 1023); - expect(await queue.pendingQueueIndex()).to.eq(60); - for (let i = 50; i < 60; i++) { - expect(await queue.isMessageSkipped(i)).to.eq(true); - expect(await queue.isMessageDropped(i)).to.eq(false); - } - - // pop 20 messages, skip first 5 - await expect(queue.connect(scrollChain).popCrossDomainMessage(60, 20, 31)) - .to.emit(queue, "DequeueTransaction") - .withArgs(60, 20, 31); - expect(await queue.pendingQueueIndex()).to.eq(80); - for (let i = 60; i < 65; i++) { - expect(await queue.isMessageSkipped(i)).to.eq(true); - expect(await queue.isMessageDropped(i)).to.eq(false); - } - for (let i = 65; i < 80; i++) { - expect(await queue.isMessageSkipped(i)).to.eq(false); - expect(await queue.isMessageDropped(i)).to.eq(false); - } - - // pop 256 messages with random skip - const bitmap = toBigInt("0x496525059c3f33758d17030403e45afe067b8a0ae1317cda0487fd2932cbea1a"); - const tx = await queue.connect(scrollChain).popCrossDomainMessage(80, 256, bitmap); - await expect(tx).to.emit(queue, "DequeueTransaction").withArgs(80, 256, bitmap); - console.log("gas used:", (await tx.wait())!.gasUsed.toString()); - for (let i = 80; i < 80 + 256; i++) { - expect(await queue.isMessageSkipped(i)).to.eq(((bitmap >> toBigInt(i - 80)) & 1n) === 1n); - expect(await queue.isMessageDropped(i)).to.eq(false); - } - }); - - // @note skip this random benchmark tests - for (const count1 of [1, 2, 128, 129, 256]) { - for (const count2 of [1, 2, 128, 129, 256]) { - for (const count3 of [1, 2, 128, 129, 256]) { - it.skip(`should succeed on random tests, pop three times each with ${count1} ${count2} ${count3} msgs`, async () => { - // append count1 + count2 + count3 messages - for (let i = 0; i < count1 + count2 + count3; i++) { - await queue.connect(messenger).appendCrossDomainMessage(ZeroAddress, 1000000, "0x"); - } - - // first pop `count1` messages - const bitmap1 = toBigInt(randomBytes(32)); - let tx = await queue.connect(scrollChain).popCrossDomainMessage(0, count1, bitmap1); - await expect(tx) - .to.emit(queue, "DequeueTransaction") - .withArgs(0, count1, bitmap1 & ((1n << toBigInt(count1)) - 1n)); - for (let i = 0; i < count1; i++) { - expect(await queue.isMessageSkipped(i)).to.eq(((bitmap1 >> toBigInt(i)) & 1n) === 1n); - expect(await queue.isMessageDropped(i)).to.eq(false); - } - - // then pop `count2` messages - const bitmap2 = toBigInt(randomBytes(32)); - tx = await queue.connect(scrollChain).popCrossDomainMessage(count1, count2, bitmap2); - await expect(tx) - .to.emit(queue, "DequeueTransaction") - .withArgs(count1, count2, bitmap2 & ((1n << toBigInt(count2)) - 1n)); - for (let i = 0; i < count2; i++) { - expect(await queue.isMessageSkipped(i + count1)).to.eq(((bitmap2 >> toBigInt(i)) & 1n) === 1n); - expect(await queue.isMessageDropped(i + count1)).to.eq(false); - } - - // last pop `count3` messages - const bitmap3 = toBigInt(randomBytes(32)); - tx = await queue.connect(scrollChain).popCrossDomainMessage(count1 + count2, count3, bitmap3); - await expect(tx) - .to.emit(queue, "DequeueTransaction") - .withArgs(count1 + count2, count3, bitmap3 & ((1n << toBigInt(count3)) - 1n)); - for (let i = 0; i < count3; i++) { - expect(await queue.isMessageSkipped(i + count1 + count2)).to.eq(((bitmap3 >> toBigInt(i)) & 1n) === 1n); - expect(await queue.isMessageDropped(i + count1 + count2)).to.eq(false); - } - }); - } - } - } - }); - - context("#dropCrossDomainMessage", async () => { - it("should revert, when non-messenger call", async () => { - await expect(queue.connect(signer).dropCrossDomainMessage(0)).to.revertedWith( - "Only callable by the L1ScrollMessenger" - ); - }); - - it("should revert, when drop non-skipped message", async () => { - // append 10 messages - for (let i = 0; i < 10; i++) { - await queue.connect(messenger).appendCrossDomainMessage(ZeroAddress, 1000000, "0x"); - } - // pop 5 messages with no skip - await expect(queue.connect(scrollChain).popCrossDomainMessage(0, 5, 0)) - .to.emit(queue, "DequeueTransaction") - .withArgs(0, 5, 0); - for (let i = 0; i < 5; i++) { - expect(await queue.isMessageSkipped(i)).to.eq(false); - expect(await queue.isMessageDropped(i)).to.eq(false); - } - expect(await queue.pendingQueueIndex()).to.eq(5); - - for (let i = 0; i < 5; i++) { - await expect(queue.connect(messenger).dropCrossDomainMessage(i)).to.revertedWith("drop non-skipped message"); - } - - // drop pending message - for (let i = 6; i < 10; i++) { - await expect(queue.connect(messenger).dropCrossDomainMessage(i)).to.revertedWith("cannot drop pending message"); - } - }); - - it("should succeed", async () => { - // append 10 messages - for (let i = 0; i < 10; i++) { - await queue.connect(messenger).appendCrossDomainMessage(ZeroAddress, 1000000, "0x"); - } - // pop 10 messages, all skipped - await expect(queue.connect(scrollChain).popCrossDomainMessage(0, 10, 0x3ff)) - .to.emit(queue, "DequeueTransaction") - .withArgs(0, 10, 0x3ff); - - for (let i = 0; i < 10; i++) { - expect(await queue.isMessageSkipped(i)).to.eq(true); - expect(await queue.isMessageDropped(i)).to.eq(false); - await expect(queue.connect(messenger).dropCrossDomainMessage(i)).to.emit(queue, "DropTransaction").withArgs(i); - await expect(queue.connect(messenger).dropCrossDomainMessage(i)).to.revertedWith("message already dropped"); - expect(await queue.isMessageSkipped(i)).to.eq(true); - expect(await queue.isMessageDropped(i)).to.eq(true); - } - }); - }); -}); diff --git a/contracts/integration-test/PatriciaMerkleTrieVerifier.spec.ts b/contracts/integration-test/PatriciaMerkleTrieVerifier.spec.ts deleted file mode 100644 index 10750cd1f..000000000 --- a/contracts/integration-test/PatriciaMerkleTrieVerifier.spec.ts +++ /dev/null @@ -1,143 +0,0 @@ -/* eslint-disable node/no-unpublished-import */ -/* eslint-disable node/no-missing-import */ -import { expect } from "chai"; -import { concat } from "ethers"; -import { ethers } from "hardhat"; - -import { MockPatriciaMerkleTrieVerifier } from "../typechain"; - -interface ITestConfig { - block: number; - account: string; - storage: string; - expectedRoot: string; - expectedValue: string; - accountProof: string[]; - storageProof: string[]; -} - -const testcases: Array = [ - { - block: 16212738, - account: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", - storage: "0xb17c5049c06186507ed9d55e735dc0342e08579866e7ed881de010624b3896dd", - expectedRoot: "0x5dd9637058e605949321a683ab1e6c56ae6041a05cdf97355696f93309799391", - expectedValue: "0x00000000000000000000000000000000000000000000000052ab3594ab17a60b", - accountProof: [ - "0xf90211a04cfe239817b200a743356abfc6e5b08d9951e90f3932f57a7c12014d9968b040a02c94e10276ccd6a461e94da963f126e396d12f50a3389966705dbb0ece7f67aca0f28acd17ade90c99e92e3e155a46076ef89f51f22caf45ec8f5affc240073cf6a0f26e26128daf3ecbb7a37eb10afad22741725a1ce43819f1f573da6f1e6fc2c9a020e3325c4125cde3a948d7a68530a8f8979591c17f445bf96b4716d64833f6c8a0def41ac472c300aed57feb95cf7426fcca53d4c0007afabfb0d6c4d3b4ad95fea0a65435daeb1a371b29c3037a01230d19872e2bdb1a97aeafe610df01dd9937c3a0c4d93f1c9037597d4b07388551773f9578203a8abf4f3bfabd6eaf58070f32d5a0d008f86640c7313e00f897b2b9416da54ea2182fa98785e583367e42035fc0baa072981aa04d506601aeb2cf8689ff23dff82a52a29e1d401dfe96baa2550b977ea065a9e75f35c97436334ad2498ea3fe4296829ad7b005e65af34fd10ddb368631a0b326e41a44cadb3e78fd84571f5e0f9da6b5ee5dfcfb1c88a6b1fcdb13fe6beca0e32897d4de5966ed95729c2a68354d1ef7f27a9b8a5cdaec592965bcc5b339d3a0022b816b5afca265766e67427b45682ade004a780e7e3667b41930a1d087230ea0dc0eb205c8cc3642fe2f03252b238891819a8528f30fc0207c2271290e8de9a1a0554966428442b6b9188a4b4945aa550f32615e4b1b1d3776b07c9d18ba0146af80", - "0xf90211a00ee4696104bbdba0094ca30daa4eae871b1dc0c2ccb07d8f24c7c89193904607a080893f1dc4ded5ddfa49eb36a618a0c3525c58890ae7e4be006e6988980cd15ca04ad58fd70d3cabb3d59144f729105997d3f07c0223a41dbc9b1507d1aa7825cba03bbe2d774e64d6577f1e90ef42b20664b4707649b00e957e369e97a1f03dc762a0107ec21d49839dbbb267fe5ca58c615af81df1752b7f49c8ce2da952a132cebba0d4bd3d22a406960040f86aa8fff6c9e29a2337560145730f9e3612844d67dd1ea09b1edb047a63e19ba02f894a19bfe2d4fcb9052e0dddd6d40dfa52351b3e973ea0a397a48dcdbeef118776a2cbd06fa400d1bedc99ed9f61d4f4513cc6aa7c29daa031f5b24b9027eef2c12015db45ef79c6f57681a6818173e00ddb1050567be4aea035748b7d80884cd8ee2d53523e9aa49186091b28dadd09e1a4f94b8ba3e3c995a055f851741c59287e048a908539c348c6555c098ac16fa074395d530b67f076b9a0f189025cd5b04a3b73bcdbdfa0d9637a0ff389f7b9a481efc2cb984484cb106ea0d7e874ea3b71239bbdb6f01287f58508816b270a218293987e42618f6b982777a0447c72ec8a23e35ba10b61462c11c654653556682994de6ea7866a538320fd3ea0d52ef935a9abaa771614224e75c9d06b8d94270a5ab11b95635f3d646bc7f80fa020d93fff55bcd20b764b2a4261b448cac23fa19dd64dbb7d33345a27b1c02dce80", - "0xf90211a0aa579a2bef0815ecbe72dcc7a478494f4ddf6e6a821fed8b8e5e22f96be95fb1a0f7be1171a1b188f0159315731796369ea543043b3f2076ad688f2bda5315d4f6a0ac7901c3cece0eafdb607bf3f6981aac2741804c77b0db674d7bc69c6e0841d5a0c1bf87d0fc7ff63bc43bb453920d13b00ed2e126931fe431206519e47f2aff58a0fbb3f885d4e17a30daad80568b76ca24b70f95ddb3840598c9cbf5499caa13d2a009566520886f90ae776076398c3393585110ea164c8a1e6c47980ec67fbbbf9ea0709eec3f022710443237d2ee3d967abb9fe295b335dbc783768cc2396ba0b28ea02003180468280c9bf5819207be30c9f3176a0cd68a57b43fe353565a5d42b62aa09817a0745b614df9aa5268081c06eaa5d6c057c86e0253ee26f081b9fc5487a1a073265752f6c91428565dab106305f47b8c609522ee518b4f391c7f8951f5394fa03ef7529bb0ee4030c994910ba8d8cd0eafbfcc4d7f7a0fe9b528b09360ab12e0a093330c4eb263124f35f26572747b59957744f1c39cb91e413b599d27e07dcaf6a022dec6cd45c7db6901c364be4226d54fd74552af51d835d605d1efde50a374c0a0007c30f8707814de913a9edd9bf09fe614676b2ed5497ea06bd157e5ec1718c2a0e6d9335dee9c32e74ae736ddccb15bbbe3ca07c347e7d038a6103877d1cefd31a02d5576458404a2e48f2263741a2c5ff181ff03939e1952cd616412c98edacdae80", - "0xf90211a0f10b8f4ec168083a8021ac8201365f45d63ad461fdf4cf8c50342499f197f5f3a02341a492492fa8323462dad1af3ab7094b76ae3666c4d081ec8d24c9e0da451da0017ce2794246eda28f5b1b3fee05dd269dabb29f71799ca7c3dca67764132c82a02b629e4b9b699796651ad13840a0d06721041de42d09f22ddf3e0f7c89ade82aa076d2c3f907c842c8e76454503b7ef1c9f52e93fc3830b4b8cd63dadeefa8fd4da09284abd6431d107e527627dd78d3cc2a655f7e364470ef620fb7fada3fcece73a00afefb47543ea7c9866f274ab4aa14ee261ffcd0c8b7c8c4e66f1ff02eda6ed3a02045ebe244660a6cae3467637f3e0b27c003cefe72681c47acb2e9766c1f17c7a08fc1ee83563261f1104687cefe451fedcff6caf2dae3f3a2a382b1a0bad7109ba00afa5fe38079cb86511e0842b62af452a78ecd43dc6c54351ed3ec923769088ca0a9c36efeb72874a37dd282f309ff318b6e9464ece30c63ba80bfbc5e5f76f163a030b918045e6233a81833658889f54cedef0f1052aa56e673649a955bc8fee94aa0eae7097667819b85f90f7d4a72d9a8147dccf5fbd744050a743f029e0a79c725a0671e20fc1d94cdb487e0a8cb8c752fd3b4c2f759b9a905134f7a880e1dcdc96da0425857c455a0e10c7cae230d3b3a3309ff5732b55ca2186cc9ddaecff5460490a0b10db994f51f52b29f43281c561f2c62f2be921c5f585fb441760ce9aa4d3d1a80", - "0xf90211a0fd942eae2655a391e59dc2779f53209542fcc140b96e4b93cff3d8cb417e6efba0bd3535c9bfa5a7b939c7dff9307610a5958f8a785d2dcf7eeaf84624d0e457cca05ce0a4917922d7b302fca1badd446897f360b11d60be9802c45136166a81dc79a0731d140390c684a63ecf3ba9d392c73b8fb1bf2864d4b90eff813e953f66ac4aa010bb21166ea999880a179d6669704ecf6c50ea9e47eb674d9b077a7d4c4f9baba085dab7106099e19e2c978e8e814a7749af5bbdbe1131333713e612898a8d62c1a012720a68371573fe69f384950b871b09a44af5fe2c4870f231a58e07190c1b36a089e816024bd04ad03ca66e47323feaf5d975b3ec41b46fb124ba9a9299c26da7a0827ecf55875811b3b25696b3737ead4817641d29ed46d5c4892d098357b699e2a06450a823c9feb0adcd77aec2d3156057f2c93f83670da26afed344e2c6a8f5a7a045fd2f25ecd36a65186513e409fa3b3e3f3a0f7f60f5951c76d2ce10235db1bfa06819009da16eeacf224ce65fc7dc8052cc2f4dd32813441801ac3be9e9db98c5a0ae81fa6db4342f607a35aea6a10047c1848c9251d87140efd6c24685ab964b08a0ee867ebe92374b199244599920a3a0fd13ca24030ae6c1d1af1ac8523a8968faa007dcd579f048937f2bb7a388a158f565b3338e35d37f455d2d6861ca208183bea0dbc271c1b2865a38476161513c4a590807f8db6f2a4de8db1e9c142a8a15349580", - "0xf90211a02b207484d2fd6781a1e4ae62c2c4171477bd5b929df2b14904cd4f36c61363cba04cbd3a34c4d4f60bc5590d8b5859da8ac83ea7a8a0197dbbc528434651b0f748a0beafa9a7e0b2073100526355a341de7a1a839c7f7322a594bdc9ed4d73d72283a0249717659c4e7adda14416a804ba5c9b305f9da2531a3ff6e6d74fca6380f4c2a09b5d4bcf5c805d1c38f283bca39ce28077cbe0daed23312d666cde49134a4d2da03930a91cdfb11a85632972832202e0ab4027f78049f828a099327513be660ed0a0ec6a17d51d787c382575d6798093a015e8383bb276b6fb291d529498789ada09a0f54c88077fa118092db43a93d89c86ec879da12d33e6e5dd89b10b7fb115bc54a0e1a3af76bd6a0b1f4419a62bc73439c641c612a912dc8d190e8e81c8c15dd561a097934d75e361d115ea93e2fdc0c91a54d59414f0daa2ac1991b6651ae6571f9ca009abf1666d7d9202849314692d5ce1e51e5629727701044b37532ab3f9be50c0a094561fbec829ff4807911e0169bcb59159bf8d478fe7116cd652c179c28342f1a058ea9466450f42b25cc3298911ebeb081b6bc73f3c414f0d36244d331cc18c5da0697343bd56fce1c2d34ebb3baa06b3f5aba4851e3b60436e545a2616ef47cb73a06ef38fec665b8eb25934622af1112b9a9d52408c94d2c0124d6e24b7ff4296c0a0451066ddc0cd1a63e22d096eab595e74c8e8509616650d76a0eedd35f0c228b180", - "0xf8b1a02a85b6c4adf828a068d39f7bf4115a4544ebf32e007d63957a28ee21eb8dcd57a0344f34e01710ba897da06172844f373b281598b859086cf00c546594b955b870808080a0525e7dd1bf391cf7df9ffaaa07093363a2c7a1c7d467d01403e368bd8c1f4e5680808080808080a0235db60b9fecfc721d53cb6624da22433e765569a8312e86a6f0b47faf4a2a23a06c72cff8105f47b356034e5586745859f6290eb366bde35b9e819af9dcdfdd8d8080", - "0xf8719d3da65bd257638cf8cf09b8238888947cc3c0bea2aa2cc3f1c4ac7a3002b851f84f018b03235ac0b3723f4d6c6f61a0f3ea73ed7d35e887e1b2b8ac13e8645eeec0da8210c16da47b0f3b0894011c3fa0d0a06b12ac47863b5c7be4185c2deaad1c61557033f56c7d4ea74429cbb25e23", - ], - storageProof: [ - "0xf90211a04571622a123ea7cf0d9534115e5e6b2fd058f94306979a373b226979a8c83af3a0293a081f517366f69769840098d809396caf7ff3942c3b16aa641b23723301b4a0605ef8aa3eb98c75406d2781067f9d55804b4cd981614aa09f9f6cb0d87a91b0a09d7f20c3afe36c59119c1308a6d7a3efca7c6588acc14364c0e70b5f7f5ecf97a0ce1729eeec5fb5d9d3fed295e469da960bce62cbbd4540efbb0eaf470b0014a5a0a69bd31a7f4267359dd41b93f03b949bdf4de072651b6929ea4e756bc6f088b6a0801ba6fed2d48d4706569a62678fb93ca48dc159fd8659b7100bc4070e3f24f8a0a58273972230f9ef6f74f1d3d1baa8795f82d0bc2c2313b7522a35cfad25ca7aa0be46e098b427907021d82e9d1d45ca4ef6305e3adacb71683f94e4656718ba14a083808d1c8c0ca4a5668cbe6faba42d927ef8df07f3581d06a9381084f0590defa00b6eaadae4a3d219a0e090a56cfdb17e31326e9d60802cf3a36e8ed0f14490f0a00146a284e0a8245d2c1f51ee97fdf9f4231caee252aab01fcf3c4a619f39663fa00b68dbe3928080b43cfc2533fffee4ed91abff24109f08a3ba26e8aaae18c7cca0345de27acef95642cf996a0485bd0242281c7ed9fddd6bad6f55e6bff04588afa092099ec8d9e6dfea3ee5fe4ce7b18f9e513cd7229f7a8de6ebf93ff5ce757232a0963d3dcfec3a80dc1073eb2292be246d81b4462b8347511d335b4c537f87c29a80", - "0xf90211a089a4ed194eaf9e272c155d2e692b5585c6a38bd04ae96e487bcc231771701f98a07a7de6dadac670c4062757c16976c4fd98c587a47a687b32b640375fd7e825b8a0da765585e24133176d2b38376f362b666800735c46e6358bdb526d03f068f97fa08acba1cd699af52508c374da47250b1d2be1a43a7d25aff247ec717b8a534213a0e74be231dfa53a30bd3157e6f702f14619887946e2a447d31dcac87f391a50c9a0b8448e3cc5dd4e9728c7fff44ec252bdade1618a63d363e86e0e6dc4c77de5f2a0f95aadc2a07fb025f3492fa7d15224bab718a908b1fdecec39900f905273d8fea0b76a4d3edfbf657e6d87e2e3920b478fb8f4bdba7844a7ab23798e1bed4abccba0fd70d97eaebf9d1b9e65dcb960bc1b7e96b03a40dfcd490ebf8bc5bab8c413b6a0fb3fecd1f77557f554c6d22b86e9dfb27fe644d13c8e53c24b64e7b3f3791cd9a039cce3c9632ea42f008bb8fd3412e94dea053d4a2baa41c4a2517b34ba8e4405a066b4b4db0e22d9fa76395494b571b7c0cc1cd18ccd332e8a59bfa03b2be2889aa0a80a5acaeeb595a5740f1844d32eab4d56fffe53176c21a464ff34a8cda84101a0f454d635fa0657c436c5fc2b6a071c62e4c01c139dc2ee544dd8997f2ee9242aa07fa5c3c8e2be0f1255f49383046703291953d29debf61376f862edd3c5b4cf76a0a30f1b5c1c3c4b307a2ac472c81f79283803e88403a5ccee7750ce7175c0b0d380", - "0xf90211a083f3f2d187ac7939ccbb8690863f341b252909afec4dcce275a2e7318e1f15d2a08fdbf9e41ea870a7ec2aa31ce43a682b8e2fffd0988bb934c03dc14e1988952aa04b9e7db219d192320bfdac399670cff992e0aa5dc25d2f3de56f4f53e5373456a07f27f9e5efb3a92a1f2f3e6d8fd4bfaf9015b9fdad8715ba16d30c211aa0530aa07cc6af0533c32fe1af0e5d4b149186970040ac5c69c2db7805774a65532fa064a0f15e9c0dbdd4f935d3aa719506ae1fb7297258d18abe03111d9e5221d6bfb8cda04572757dae6365a28b493c63503809a9dd6927b6e6f11f791e9c2cec92b80513a0d1ac01dd696504ca20c087bea731dac1b8c48d26e5dad36d80e34496ee20b46fa02d879c981e1706e0720b3efa7093308a499d57ccbf9648cba78026b3e7883795a03f007ce733ee8a522776e46bbc5dd28ea33db0ae4702d733926d83b28c4d0181a01b1858a30125abe3a401112f676d6a4b669ac9495b34f89691c075ec7630a45da09d22b122a2fd0db8cc2397c0c8e05fe317e3bc8aa407af8b85ca300d9411dc0da04ad97d66e54c7a2a76bc6729384080115dc3ba5e6a7c5269470372ba6d22eeafa0dcfe09b848078f66db11284e093991436f85ef26ddb3dc2efcf56e4bf05e6101a0e641c7a710a5b8a3b465e05b09e4868d9e54353b50d29eeccc9e829ea314041da063ba309481ffd1118153e75496d66bc7a96d37f32c63f4e731e56abe4fa5f12880", - "0xf90211a00a62828ba9909a92bad0ddff29537a58e176fb8af1d76292813a72f5661ea282a0f037cbce7cbacb3343cdf899fd145917e7cf18deddf5b2d8a94027968f9f1624a064774630a8d992b0888514b5e1dc2fdd37b8a214e6bd39d3689eaf74bf65bf68a0b6ee7661ab782818ac639c03784ab65eecbb06d79d251cd8c25627e51ba5b94da0c1dfabca29a2ae57d88e29f0ea94bb3a825d4b884c7f088ab4261b5900635ecba01bf409b8577e89fe49afa62ec117c32a9beac5f8e8cce54adeb3bd501c15cb80a08d7b60700564e51011a00159786683d707b676f41214b3e538b074fc79484748a08e58472318ad40f9498b98a599d260a80298a2cba39cf45d0bff8d91ae2e4852a04443244bd4654d707e3700d112783b837070111ba8a2f0f11781d623c3990754a0750eac11d5f2be0746f87df3cf9849ccb8f13c831936a745abd37fc464d758eea06311c8c2cbdfc4ff1a7e550477cf38ddc35cf57579d0f842801a9ad6fe50c45da0c6ceee02d855cef0db230d186d9e37b8777b8313a22b3dd6946143da503919d4a08669ea1760b9551901c57fd56411368ed8de861bb4602d26f93005d0101fd195a0285993aee29c28d2239022fbda7df02d06082e0246431b7671edda601c6e5cc6a047bfd76124562bb812ec81f5b286e09907eba7e9b1efa72d4ac7a49b82eed957a054bf6597873bf09bfd3df04d4fdff771c02f9d728d51ed1ef00f6b053f3282f280", - "0xf901f1a0c5a1504268a750c1c90b7841d99e6934f977193c72d44ba456fc9a263fb3ea45a0924bbfcbd6d2e7a3f9bb5ec1898a1ec0b98880f747991e96696bd0b565e1f83aa07ccd4b2cea9ff079bea41f9d704c21e7f9d3fbaa83895f34970585873d5bd9e2a0b2e313a02508e8a0dfa115612c1400f8cf9d5cc23369b6aefd7c1fceca7dc943a0e19964c5618fe9f1f590eaddc17787071442649385109b9324beb8bf51a0d2d4a0b022d54d33a1c62278d7784996fddb4c7dcab2fc3c2287c6840edc3762e3d034a0a8381f53de80c0d06ca7288457d82fc1cef37af3e08abbed93a61d48d7c9ca1ba03f916faed29b999d16e22fcc2ad463681a42339b24fdca5a1323b5e55d5650f3a0eb6adbd0b998ec882b91b44ab6ccf20050962c45b68d4e42d2f0e3e1c9384952a009190c615b4dab60e7c1940f2b3b87e3636a655b29dd8b65b99f497ab4fbc395a0156deb01c2c14daf7c043555c077b4af3c5aac031d75cf9e4f704280983c67c8a09dd3b43b4514cfa57218538527defb69638f108383a9d95ad07a296d30bd5bbf80a01316d876cd6803dd122538f308cf116b79278393d979769a121f8354c925cda0a0324232c83f8194263838f7105b67fb93b805c027d6419a98f3c40937b9502132a0cf19102ca5c74f4e088ca39ded150e7a9d5d1bc5d9263012c7e843dfdec8386580", - "0xf8718080808080a0795b2bc0fec80623a0785ed76761d1e9abbf37b806b4b1664a22c1dac557d79080a09831b7f896628cd55e9cec00f168d92c748a1dae2fc55774f0fdc80ae64294a08080808080a020edc6edb75de3cfde19500957b220fffbfc581e93b5b6e307fac078a8b14783808080", - "0xe99e20e18d2fc45a3ea90621b218552f932e0a2a920a290d1c6bda98db9ab133898852ab3594ab17a60b", - ], - }, - { - block: 16212787, - account: "0x9467a2d9c07cebce3708ca32eeb2b9219aeb31b8", - storage: "0x000000000000000000000000000000000000000000000000000000000000000a", - expectedRoot: "0x16b9e5246ca2dad361d440d5524cb431ca30d0575fc21f4e4242f7611fa2a212", - expectedValue: "0x639f404f0000000000031d02a5d2b33515ec000000000000072629ee1252f3a0", - accountProof: [ - "0xf90211a0aa686b484fd06fd6a76b4b37cbf3965553120d61b93dc354e1e32e3442fff947a0c8401b3aaef041fd79bcf69bc8eae7220b1932973d088c368422b43e7fa99d3ea03d14c01a86a93d483dae0f088ccd5f64ee3346bba6590bedcc6ed4975d36c0c6a0c64f3e49789294f22c3cb3bfdc78406933b8a47f743de5c999599f814cd8d166a080205a023284e4f9905946076d9dc0c029fca1452743becfba43ae49b0c09d18a04e13c9c6719f3519cb7828514f1b0e393398c7dfb0d703980062e52a3faffad1a0e806c685e60d3b312f1e740422728358f9992e4b7cf62c904c8c01265e88fac0a0f21e7ee12a407fe11cb0950f63ef5dcf62d26fa599f40136ec057c684ccaef73a0bde4594be3b1be7c4312c6ecf81ba8cd8057331563feddd4fdbabf3c67385fbba008ff9a89a68d8a8f6cec81a8553ff72043c4dcdc1ce784874c3fa5e76916f4eca01c5e489af3e55abfdee369a10075b761f58be65d5d589742ca8c6098db88e9c5a05b212b9a9b393541dec0d34c4908a194ccd8c6a21063429521308840c8b66d32a031052338c42361d910eee1c3ec4b7be3400c5cd97a7f8aabd3f5ac81da0c8395a0850317a18f8494eeab20c8015e5d863b43587a7dd3a7efd41a921ff62de926dda09e6e76b343415cf3105ecbd67e99f004b31eb7123f3e3a614ad808557d78c34fa030915874eb78ae682f3d74a727227fa86b204fa367256fd4a50767ed4c35bebb80", - "0xf90211a0122c3b5a88702fe6bc3d3464e903d0d1aababc35f259eac6b9111e5b753de6a0a0bf670757a4652ae24e5bd2fe9cacbdda79924bd6091330b950b1473dfec103f3a090ee1dba46441ba0126608d28b0023f0ae8401eda749e90d8550f2d3ca4ccf1ca0deb3887fd765e1c5db19b353dca2ece691dfc2f2c7c0a1c298635e3264d8a05ba06af91d067bdae7d64e34b2d654b08815fc43bdc4193482e9aa58e1fd852841e2a02518d875bdeea78fc832724ad33bbc66a654a1670c6bdf544a060941f90a31d1a0d7e69dfbfc026a105ec5ec68062c6affc1115ae3ad7a70e4ab854f9c914f2cfba0611e45cb73f473325c3d0ad494927e1d1053614c17cec3dd04161248305b3c9ca09767470f4299e3dbea4978fc989ca44abdef26602e3351cea0ef2885dc0e66baa060176e7f197f28205684e6b5ccbb83c5494ac86ef5483094fa3480728b11bf63a0c038f27c7e94887708465bf77ff37de506f5cb29e9a355d4b16d426e12f2bf59a080a4b6849ca41469ec77dba2d4d3ba0b0da9a36e5a6c0451e588a31af5981179a0b7fc37446eafbe040ba963a25e907af5a5d1c584d31198c12e28499a8377b249a0550e5984cd4ee2beb3b1d2af589e0a4954d8da7167896ac12985e1d781e3e98da098ea9d1574fc5431dd7342ea8467c5369ddee70b33ca37f30230e21d9a995d7da06cece45972cba1083ea30c7563c9639d398749575ec229e634f79e1ab637dd6c80", - "0xf90211a0a3afae41153cd80f43b9b413b8fb57481fac6882c1f6097117cde8f8aaed059ea0730760d301e2b18a9cd4b3f777d91bfff8424bf64c05adceb8160532728cb699a074588c944add6aba03154d7bd8b543f149dd9629f46d8da52abc9e41be988a74a0b8ae67ef514d0dad520cdc9103c2702ad40a7b0c343aab9be74d72d568902540a0345dfe1d6b3fbb5c9d0aa731fb083d5db76b4dfe22d5b1a789c78a921589082ea0cc5c0989644c549f573ead05887340e201e92f7a5bd9cfe7b57e3bb46d47613ba0002ae2795f3286b54b45e25fd66ed6173ba4bbe56393f7f27407cd559a2d259ea018cce2547825efce8cf5e6fe14d88cb7899a1d8768dae861c0e263a06640e5e0a05a6a075ccc448ab78a34ed3ee7d56a1b179a046be98a1831db18f43637638d04a0fe2b2ac494af3af2c28198dc97bfd165288108e0d2eff941cc5d115461c799fda02d1de5eb58ae72173353aa94335766bb360eef79b6925fe5f254f0e3caa8941ba0b63901c2fd1c61292d32f049dd699bf39c4019b1ac7ab12907804a1633d288b8a0071290317e54993ff32e0ab04d28b920105eeadc917e44449c4ca2fd80adf9aba0fd86afbc5d8ac6357d6ba6f13f0d08737d1f95d49bc1ef1d19ddee3dbc4188ffa0b1cf7db5488cd60ae077821f0aec741b51f8e8c553eaeed4524159373aa98d7fa0c695f9be60487243c29023e469d7af9e37661e325a577247516475e51d6757de80", - "0xf90211a090b58facddd3e83bdf8b1553a2c42b07fac5c1da069c73be25f30619088cb480a03867abbc8789869f4b7b5cc4799980299cc3012ec7fce70fb7dea2e5995a9a2ca00c3948797fbbfd4879bc72b5ec1eeba993bdbf4f8b39ae8f63c94cb2dfb89916a00796ca2b7894372e41a3331413a5e776eaaffad05ec03e240966e7ba8330f045a0713935c0c8cfc67afb8a35c948b4239710a5e7d61b5bf9d4e3d6e88e4e7aa28ca036caba99dee8e52ccd1ed12972e6c3ce4a28e160bd7542349338b692c27b5a51a02d1d87889d5e1c16690ac8b7ff3642f6814e42fe6cd6e00e108b759555f2cca0a0cc4be174afaf83b4b1d4fa64374817759956315fb684326fafeb238a41fb0ec8a09dabf40050d9ed69f994f8b82f14e037dec59c6a2a24a9879e184b546ea71448a0c77815db0d8d7eda3df1b8354ac007fd93f6190f20616e7b93259d89f1b0ac6ca09c105e9c25f2f480ef8a50c31bfdd0eef120741c9a1caa6f2278ab7fff0e4651a045ef65a0c419433050e6cc57892fac712cd3cb835da30f2f8cc249b872d6274ea0a457eef99c7beaf2b365cfac520db40b375a0707a0aa7bf234a04ec5746e7daea0e4d2b13f79715813fafb715534ed0d1474e044c7521694ae3bb1475e7d570f42a034143e125fb181ec980641ba63a9d19a005eca2081bf1e1e77572c172c8481cca04747c648752a28511842c2d63410bc6a554ca6d13aa3541edd6e7759ed62b2ac80", - "0xf90211a02cf6e48c3852fd7b3a31e6922cb756425da526a164faa2b32f19b21187503ce3a093f0f615e47ec246a5cae41dd6236374287e3efaa9c17611bed4f2621f5ea7e5a0d6c55b3818c48f66570964ab6f184094948ea1d808d26a66a6d0e8195674d143a0ac7dc18dead02fbd3763e5d5fee4d2c032ea207df6bdc26900f0d10ff2c47f8fa0c037ea2e7608348529093c9b9fec3b32d8288bd0b6ac3ae242443f4bda8e9eefa028ead29005c86ca93d969b2963b3eed06ec81dbe7c7c3064d79c6aa033de3246a0f24e9a73c866d6e7f1d411e98da53c76020db588f4b214d44ad6e536d2b7f1e7a0207fd73036d92ceddc5da5c0504448c6c2704735bc6470d10193861e15530708a020f669676f97c6585f7cbe5e405c4f9a4964fad36fe4dd6aa13c6b80a60d901ba061b56b1bcd12005d252197b44f28f611d2cf4448ca57784a8f17ac2b23cfd519a0aad0bfda854bfaef052cc6659d84e69e4b0325e6b8fa394961694e2c3b758203a09da958cb8bc74373e66cf40708a152f31d2c6ac305fcd1af07a25e3e34801227a0edfef4c130b1198a28da1ae2fd66c33d2d1e98725424b9383dee7136360c7036a04c64086b040c6a3701a1b2bedead55797c95c5d635699e66950fcf9c6215ee02a00320a92427efbd2cbe8f70c7c74aa5db0c145b75148808a317a2ccab2cf437f9a0884d942adaa313a922d0883e8139fc6a92acf16e95d2c7d06b4e53a08fdab69280", - "0xf90211a037049228c0254f0105b8f461536b772d38df8e4b8bd7f908be72982a86a35961a0d23d1b2a16afe975ac636a8720e5d9fe14dd999e47f5d9e43fe86b2907134705a086cf6044b7e6be2a9c312cf4bf438d464f111fc19fc0abf80c8ab31644bebd06a05bc25ec41da09b0c76b897525589bd03dc90b482ec59e6a1ff14102217f2cd6ea086e9e5952917cf0e054e0e00e0085d7d3bb6a704e55ec5739b6705e4e6539d9fa0148e465f1f1f6095bbcb2feafc49ffd5f604b7439f9b4ab0437f8cd7acf1adf6a0bd2bb1bb25bf43758ed57d63ead3a619cc3a94d47be1b84b4208b24f5b80094ca037ad5b50e846bb85482548cc5a99a03e1db02aadbf61f1380f61bd9ad7ac4704a0a0967620f115f194f7a0c16c7e13492646507ac7dd8553e97b7ebf416228e1f0a0f42e67ae7d57f618596858a5a7239a6039b0dc751d42dbf47bfad47a36a5a59da0efbe74b7c05b343f3e29d1fbfcaab58789c99cd301b87442363efa0a2c7a395ba0c8b4d32dce4b607dc21e9c4ac3ed9757640c760582cc1ffa4679c4dbc2b2e0bfa057addd95ffe7c0de9774f2e3790a52f262515fa6a2a65a9fb785451a6e3ad2f4a094d55a6f5ae979bfc6c6f59928f2850206c5af3caedf39386939a053a2c7b79ea075b8f0a832023c355b067f3786edbea9547211d8cf2dca5f89f9a413b9b525c0a0757df921602607a9115e97c1ca0e4acbf0a2d4ff3bc6e7ae2b151b88359f190c80", - "0xf9017180a051c6427ab0bc0d3b0db47b82e69a31fec1670e8ffe2ec57356a512c82083a6a5a0dd0af4a616a626aea8529e07f9017ae356087c45c92ef851aedd845987cccc46a0457441ca9402fb91326638832a9a169e021608db12c58d0e7778c1b13add1afea0db1a3351b7f76cb3170ecc91fd0c687ad46378dd392944612f4c68bb9fbe1050a000c1cb0f8f7bd89d04fe5ed1da96fc769c67a27b3c822a8653397e7da6a04730a0b63f0c4914683ae30b031264fef21806ac7a1a32ccfd05c011ddd0202e06b275a0ac66fa130cd31b0e4b15b08965686162a3efb93e3a07ce45859b34e9a2b4112e80a0dfbd89ded3590a54e3b47e540457b06c754b7b0d22cab361a79adbde4e3d96c980a0cb72d7bbf7aab515231c32e9399359c91aff95accd474e39a091fa2b9e71259b80a04a2be13b00b2032cc0c7112be04907d8d0fa0968932abe8dfdda6c6bb07813a680a010d29a9d3186ad1e4ad1c518be391c44180ba8ce1db0f09a2c9ed23ea017733980", - "0xf8669d33239d97e43f5062453663ffd198f40e6120b1057a77480a17b59f8d8cb846f8440180a07a5f002403d62f9d1ab5b4684459d1a2e5170075efb41f51f94fdb30b5e6d46aa073f5b0f762a0557ec4b135108e719884532887167fa14c0d6b7807943d70d96d", - ], - storageProof: [ - "0xf90171a0b5a85440d5fc74ec55facadb9dbc0cbf35ae1eacdb841b17d6943721a7028fe680a073d52ce999835ee363c087004b4de88b619f66f3dc94d35be5e0b17869d7ece2a042bf377671e60c1d6aad75c93a25c72f0a0c7c2fdaf732b1ae508dc937ebc0be8080a0a32f55598dbc06e6742074f3ad6812f923f9a9f991e597763520cb939c5440df80a01a7798f0e3bd3bcf90d8150e03e9220c1547aa70037856b2961b5fa8dcaaf974a0fed5524862371f728f0e99114f0a09685044436cf34c22cfe4401ec4ec03ffcda06bf06cedf7b90669bac0f199b18bceca612452bb315f1386645bfbd52205a476a04d2c61e0aa8cffbb121715c333a6289570d450cd77f44d327212f404bdc932b6a0af144ae5e9f31fe6da35eac694185fdf07aefb9da7f4c652645bd7f0c7253e85a014f49d31860c00b7dcc901e44c39f3050b2e3f3b8013c0af887778813da9b97b80a0ce3ae4b74569ec95d0d116928f28245839a0c0629d2ec86081ee4896f9a2785880", - "0xf8518080a08bafc792d182fe0cac5c7dfb236bbc88dfd0ecf5505b681d1c256d75aa6858fa808080a03315f891bf9433a5415e982ba0f5b3d4497a2a44cb9a958d0830fe301fecae4d80808080808080808080", - "0xf843a0205a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a8a1a0639f404f0000000000031d02a5d2b33515ec000000000000072629ee1252f3a0", - ], - }, - { - block: 16212808, - account: "0x55e617b7456abc2545cbb547e0102279a6c430c3", - storage: "0xa6bcd7cfb5e938d75f4330a273812b53f809408efd4332627beb0285fa4a8732", - expectedRoot: "0xcb31a10f1562c0c36bd4ceadaa95dd6234fdc02e8cb9357339e507e6b24584bf", - expectedValue: "0x0000000000000000000000000000000000000000000000000000000000000001", - accountProof: [ - "0xf90211a000cc1eab958a3f1de15398fa2b27750166c045e8eceb809b9d4501b4e02b7ddfa04da48723172332e782e1bf0e4fd8b1e5f98401d48596abd9a9705496167d7027a0dac4dba16da7ed6cfcca82063ccfc4f47b6fc53451538f7d0d1c7938f038940ea046d8e39429c81dd993f99d3b11ff4cda11bb8c8696b9d93472e71356b8041832a00b940d003e8cf026d1ada0202aa2abcae53098c85486eb7a534af6b3004f8443a090045c5a2ffd3bd39f80bdfa1d6e5fcf75105c81484ddfbc5dd4b4d73f6b66a6a0e4832a0fde78437c8fbedb522d2910e707bd1cf80f2e10b9c6040da0b05105d6a0a0e93dc2989f5868d5cbdd62ec70157cfc4b2064daff79586208e60d68221aa4a0fc7fb69a47e3d6b002c776b83f17fe0c9afbd922544e49bc69118d4912f814d4a0521e58e73a9dbcef30b0c02af1283b7907abadad2531687321fe8ab200027879a04d23897e8ec61a693cab8d2252fa69ac45731de79e47e40711c363b1e7062fcea0290185b97c0ee9f00882f0c50b493205d1a22128338dbb6bc7aa6770c7badb8fa090b9f84dc7ffe1e953274bd3076e5ac2c6faa2ffe8335a394eafad186f9491a3a07e8faa0688cfc77a7cf1011832d69385499ece50ca53ed08fefcd4aa07ce4409a0dfc42b6dac4d479a49a3d2d18ccbc5bd9f98f055294ad62cab84cbc6267f85d8a0b2f0f894b7cfd6834f2c9b58cd5941c8477961169ff6579dbf026a28a871ae6080", - "0xf90211a0cc88a0d04fc4367ca945630ce6266a93178092ce38ebd0d3976125c80d9e638ca0110ac16b660ba8dfc12258f9ade49be6245e7d229c4b40ad947c2bfe584a5ddca0b7884a63fdd62c909b9325f29ba55203c8368eb48c420e950354387594c4667ea01079982e5d8a202ed036f8bdd6ddc48b2eaa7c3e8c6efe8ac3369b997ddf2179a0210f2400b4faac315689001a789a6db9313cd835cdcd31df96eb65c433b115e6a089bb0553166bcb16346053be885e361d2d67cab44f7b959aa9cd826dd45ac61aa03b87244622f87055fd869434afd48c8b3ad5a9607b747f6c0d2a5f294e362ff8a06fc34c186c23de6726ff12f731925d0c022b1e28099c6ef1fa3f19423e974396a074eb379a4d71fa80108c16d71c9c9987bfe618f2f9c46dc42db411aa42984b78a01c679db1c89150fdf004859b6a69bed2045f4b8731b221e4a07eecf35539eb5aa0e5d137fd960b8cbb20606bf9e7e9fafbde54c409d1c4613dd80a17de5b47bc5ca037f5902b0eefe2f4d3a498af280683cbb6e24a257548f49c8a5541269da4960aa03ea41d2be7cbacac4f8ca44bf03d0bcd589a01c10a0bffafb8fb1da5a70e3068a0bb980af567ae4b71f44121bc9041c5e32d971511629ab7a40609a36f45981ccea0ff394894d8deeda5f8548486bb5feb71b870a8a431c0841886a38de9914bf188a05afa6d271d39956efa0b6a37f849587fc9ffdd0b21b0f03a7475075f3db941be80", - "0xf90211a0074eb00b4c1e2c7113935bee95ed4348415dc85b368967d4d5c4d76196af424ca0813772f3b53979306c3b6099563da22debe31524b46c489b304f5dd00e38790aa06c3522ff7176e7802c0565d7c0861d3b3d84bd4cdc335af7515cff8d08ca7fb7a0c768ae9e22fa57009ecc980b0550fdc1c0b1b4347a505cc4f2305681480cc792a06163dac89c2f3a035f43a559f71c94c2ef275974bb653c51db896c3326c460e1a06c56dbb2e85d467a81935889edc1e1fbda078896de4e9c4ffd33ff780137ce24a0e0da97eccfc2ad11d6489af5e6c646bbe8fae20c85fd1614e84589ac69b7b110a03eb954e27f07ead9cc4013f091b2b3fca8163d3ff052c6a4741d7b652161e4b8a0d1318e44803ed8fb732a840a9cd71eb2d0dadf601f8b8b77251b6de06776513da0a14970d414825f655862751df3bbd7fcbe9903adb663690cee115b4fe880a7c2a02cbead1eab47e6575d0d9d488311b4f16199fb8acabc3bac662c698d471649bba06acca947c81f7bf0b05c8218e615ed3642d1e812c3c696b76d19d9e95207ff89a0486a337786d2e2c7b3e963a9efb9216a79ee5cf61675b9aacc9cf3f35c403559a0e3743c73438b616f23323e8722d90afed16956be9d9763d35968619ef644d893a0437723f6d8ed5906cfc7f1254f80504c15f394db51148357f4c7ef0ad01833cfa032e215e323cfca2dbdbcf7056012ddadaaf9f8b9a4269f451ec28a19018fc76d80", - "0xf90211a079d20a2fe4ae7cb0a24db95f0cbb8a32bee53ee9910a9fe8959cea9d6d584993a01a486e762c0b7f5e99f02596a5250acb7d6d54d2626b7ba6c23d97931cbe3296a07b56e82ab24b02849378030bdca3ae3bfa19af23363c731537da3b47dc64c299a0a3c947fac18c8907db5321a2cf28e6fa0205d074db959c12e25fd0c9c64f64a1a09f658920397018751aa15e1feec3ec81dfd19988e590b663c6efefde407e2a3da0e5dcbae4c0fc4c9a050afb5ab81b71a76cd201d9ad724894518aecb7ae557079a02eedf89c6286ad0d5a8f24ead4c300646452191765d86b7217b7c503c9d93bdfa006d8c0bbf530c40ed8bcd89dcdb4cba927d3363c4eeb3fd7452c82f986506630a0fe7850edfeabfb584ab06d0a1599d64ae60b143cfb3bd8bd1cecd8e918b0c7f2a0d09c9c7f8b8280ec01c8fabdc75a5abfb9600e5961b3f1a2e62313e81bac9d26a03c5944032432601c395a4a4c31c3feed3606881df80407e7c6e45a82455f85b2a02dea3f595f1b07648456f39b39a6b337d5903373c5c194da04ecdbde82b40b41a08cff9a982b8e0fff7d588cf0fa0116f039db921c13fae79a5f7e8333ad4d3a18a043dac2f48ff878530faf63341dbe6baef3faddfd049f7db4c183079c77916b17a05e15585f071142178813285614aa8abd4c65a95f516df528ae2d3c6ee08521d6a0b0dfa07c70efbcc57f2b6cb7f77a7a20fc9537c0d984a676ec9926e55f71c77880", - "0xf90211a0fb721ad628030689ef65168ed001f566cd190e9c4d0219c02afdaeb004d4e214a051531d55c79e21f006c4741486cce4d8a6e613d761b3bde9ae2c8040a76b307ea02213a6ad7395c88dbdf89f0b29acf67c6aa1dc0e374cc6a7d9b6ec3d9fb5f373a0686884cfda50455fdff45f4170feee963de6d591770c269f4241e34563d70f37a0bb97314a2c0642f5abc066b8d53634887234dc37d3f9538124fcd27225b75733a01a296ff7ac3bd812e706959caa4748f04cc0729fdfb14388e244347b4a3cb685a0888eadb1b0d48cf03e73398f2aaef32bb4ac265f10f76c504db269250e88fd55a0b9a2aca21bcd60c94c2a80fdade417a56fabd041b6c0379159f02ff2fec8ab87a0db49371306dcf9e9d4ae471429c2bd4affe09cfc065792ba6410595f8beea2c7a0bba4db70589218f90ea48d1f870db783f8aae6cda9dbf72235e1284b97313dc7a023658240a8e60035480607bd2e2c780d0a305909fb06e9c6befe7701e78b596fa0d6f93b95c1fe2238e73c72e96cece7d21189e5c8e839bf0d42bf226a105c08ada08ccf4640a918ae9ea713e739e62f7b5c5bee3864b57c32e29065593cc8457171a0ad5dd98fe06ccf15db195de3aa8d071be23965c64839e10d1e9721cd64f26382a0e5a987a544eac0a3abc6ef9ddd12d8450b3e11f36d6239cd799595535ea0431ea054db8f7995108a2c8bf8976723682ce513241f75da97518991c6b77c050d398280", - "0xf90211a00dffb8e3f1d162560bd7fa2851c9475cd30bf41c78017372b8f5d40360831308a03348160896064725af3bb64dcf86a8fab726fdf442007fd3825c689553a314f8a0794309daeb0692594a7bdd16e884ebd75d598db16cd1005a9176fce869b3580aa01150f6cb195cd24622f9440d2ea824b33601d7d7983db0d925d39daa1695c950a04b61b2cd4bf2ec97550c27656b784df083bac7653352920b3bb0404bb09f1971a040e09010e7c233361e66eefeba4c03cd551580bf394ed6fb6cb8f921184a9f95a05ba6ce8c14236c7b63aedcf3f85603846062c43d165c207cb5418cb7f06dfafca0fb016acbbd9d14aa6bdb9b01e802ffe495032e97d124c9a0b65d10d4e715f39ca039c0a367372d7a14a34ecdc997bf67bc72755b4c7270effee6d90824aa15b087a0c7ddc7fc8c0341c56fc7e6228469b25f7af926b3fd099530c6097a02c869c41fa0ad11f0c6cad46f32f1ce178820941063777e2871fa38d5adfbd91672479213afa03b11a8fbd61e8e0f3f18a7c3573ec7a792edd83d3a6b8efac10ebb8b157ac17ea0ab266aa84b02ef61bc71faf1d261e2bb90cc21d6cbdf951b122f596f5eb3d90ba069b80832c46cf88b0ca1e64054d87f2e33f27df1f322c70af89f4ec909313bcea075068d344e56b3eada6312fb613925c3c9de369b328ee666121dae6c052103c4a0c3b65e68859146733573b921e8fb036ca7c9434b0f52412ac0cd169950f95a5580", - "0xf8d1a0db401bdef3bd74dec5338135194e69ab43e15aa891e5de20ef3e57cde5366ab5808080a0621c1fbbb026eddb70a4c645e152dcf9b3f1b40b9a1bdc4398a22bee4a46aca380a05528de70186525019cdf0880afb77b33ae4871fbfaad3e8bccd7dcb6402d746580808080a020fa8ae1091998f03c979f94e94ff6c011427da2834f1dffaec815fd3c5fa6e080a0611ff1f45d926197480694e690227d603e84e7c44b520473b9786cd4fafaf613a012dfcd444d4948c86a3dbad8f4f1dad09c313a63e6f8bf0ecb7bd799908aa3248080", - "0xf8518080808080a0cf86ad50e7ed35be6080c4cd74d835e58867b2e2ec03198baf29962de46a8cbe808080808080a03a5ec92acf98ebef8eeb621707a501ed0fd95186282ab1dcf8e7286a9142b90480808080", - "0xf86e9d2019df8705960e4a0a7ac52ab662c57cddd5f60a7f75f0c117ae2e073fb84ef84c0188067eab853ae20000a0724a8bd0aaa1c991a445a1e974deecd8cfe4ba2040de2578e98238b9f963ba8aa01717795a0fbfac056a8306e5cb0ac160c3ad752357e0360a408e59acd35ebb1c", - ], - storageProof: [ - "0xf90211a06a128b938cf5a3be9f5c7a8944945258db0b7a939cab65a4bda8fc4a8a2bf16aa0c61e8e76eede0e8a446743dde629574cd69dfe612aa0d30c6c8cafdb7f445214a084c1c16c0f4fae18501251afbc28ef21caf9b2f1b5a8f2f0b6b87d076f44f7bfa04ace3470f520e28ebdfa4e98a5ef51af05f647a3d1585f0d98f3393098839f17a0d0628e1db39bef70e79ceb5860a14b34b78eca696ec7910f3bfc91631a0abd50a0b718050b33452d627f87f02ba8b05f976e7eeb2c81cdd445770eeeefba236fa9a0f0a8fb4ce1456839b267d76b94838113ea18600fefa3617733888b1ce7da7ef7a034dd7e5a07aff6c7d141c66b4aab81f3f31363a92d48a9bc1fe072b94d69bf63a049c1f246035c714f4d6e8d81e7a20aef93140d067012314b37489a66f4e19db4a070279280c8be3e03684124acd488d9611ea5dbf62512280eb352980ec8334436a04e7d88090f29162b58e6fdd44446f90c5bc1c39c377d7c757c6010e9a63c738ca05eaab99620fe77019cac5ea6854f3efda933ea60f1326ecd03a32494850556a4a06b4116e3177b3012c5e06ab564d1a0611140ee2b81d50c8fd8c5aef333296965a00874454cb37dd61c28f8bb7da5d905f5dacf0b813914099244b65f536561e22aa073f2018c86cfe905a5bb8f69b43395c949714183a829990e0e33630431af8f86a03f36076859c730c0f5851ea263b5650dab7235f3c8ce258f74a3ae3b7d38add780", - "0xf90211a036c69f765a83b393b27f21eeb941b8a2965ec7d436b3965a5bc40953a32884c9a04fd94c2ff0df3a8453b14a36a55ee9a15096180c12feaddb7c904016e0250491a00b3973a34de7950e6eed8e413dacd2414ef22a90ff9fd322501301e159a2c081a0f6926e67b5dbe04b3991297ca0bd8f1fe63b1f193e16621c901ac81ad9c25a85a023776d17051b8899483fa00c050cc50eae159dbbd7b59a35290b6d6b272e07c9a00900c56dcf2ae9bc0d19ec918cbd7fe63e7afb8aa2d962d1d5cf5886c763a7dfa01e52f9000865a4df376396fac674f061a61603647923a3a577387c54e1b32826a02373c893c5feb4c772f345f6609f9f9a6032c068f2453aad191626ce6a2d625ca09fdcde9e12f55bd9b3bfb323f1c9a7488f573e0b01d829d6f0ee716e92f0f248a0353975fd758f23275ce22c485c939c781ba31aa8c6026688931ac61d0f0d8013a04f0352b630e3ae315c64d02f85c4cfc255524b445046426c3e67f6608a9689f7a0d3b728caecb48e019db5f0144aa081ce5954c8acadeadd3df36d25b6e24a7e0fa0758800b10d88e8b477fc17a2094b5a41aa69c37740305e1956ed558dd5dcd86ba09f51f4aeb641e8c068dc1370a71942792b4d30a572ad0c09eeff206f7dbe3355a0c5d5fa6fa22f56ac27c0f6538f94615e0e7bb49243d888ec6b0c86f61dc6922ca03b7be4e1038893b7cfeab5a172995ac07e1e90142cc566ddc2b613e3b2a08c3880", - "0xf901d1a086ece613a3028576c5e26a4ff50a9c3311c3bb3ca3751b8e52d2667b18917f4f80a0c54874707f838e0a2abf666fd3c50f900c9c0c38e9a69b37551b1711acef7eb1a0b7e0dc7b68d45f0f52e17301906d038323861fdb60583c6f505f76d304c73ea5a061a5e1481d528ed55ed1dafcbbbecc99276220ccce4ce56f50a05853638a3c4da08db8ab11699112f1f4cebece052af297997fcd361f5ceb88db4a7168e0366cdda0b1c641b80c0e5642b33866b899afc25070277d24665b6d73bc542543592c6eb2a069ae6c87a4a8692ea804b51379521e3856a6a980a1f6143f19ffaaa397c1699fa005e0523d440c3fb4654841a3d8ccce6e5eec4cd5f145668c0e95e847c9c4c39fa06c86477d3592a33fea0e7e425cef6b79610cd32b3bd17fa1318a5e20c9feb02fa0fae05cf440cf5cbb96e83bdd1828f5a582aec03edbb87e5035fd08660f09691980a0d91b6dc415a8c148823a7f865963d2b527c6a93bf882cd29da46f9a9594b4c41a03537d0ab40aa8b56059d99680365cc017a26fdf155fd6f2a7788311723b80738a0e38ba0e1b4f98b4b9f1925ca952a6a9076eda1bad2e36dbc80bc5135372a3feca086f2109580fb4d1a26bb9101b88c407eb13fade29243d68b83764716dd450e3980", - "0xe19f36c2516eb411c7c89f75dcf98d8ff95555585215a5f6242b4f24adbcb7424901", - ], - }, - { - block: 17654287, - account: "0x0068cf6ef4fdf5a95d0e2546dab76f679969f3f5", - storage: "0x0000000000000000000000000000000000000000000000000000000000000000", - expectedRoot: "0x6e0dbf614f46a7d99f42bb19b8d077852fe794a040ae62a4468810e3f0948bca", - expectedValue: "0x0000000000000000000000000000000000000000000000000000000000000002", - accountProof: [ - "0xf90211a01d16453323b30ed0475ac6e0d8498b3defee9b0a2a273208a37ddceb5e41f69ea09173547e094231c109ca45892dd38e73edeecbde5f89585c981ee7c6ac038a24a01980107b929796de0e9cc55bb7505c7adfd297758a257cb43b9af152d596856da00db006c2271b90391c0a1290bdba55f2b615eeb5307a8bbb4c8faeb15b8b7ce3a0b3ff04cb4685f72483f12c93de3354d621695c59a324e72e09f353af209888a9a0ba895b778ace696ec60b09f295ed885afaa027bd104e3fe58cf106471c71697ca0b8521df9c6de45143d29a6a1e1f855ea11d62a30ebf601914d3524bcdee2d6fda0515cd9a8cbcb46a715fb7ff67fcf72bb433a4c2bbe53c64d0d92d83d7e4bfb68a05a12f19c558e64b1cf5f404e8ec0fcebc0c3c6b05eb5b12bcd5366fe09107652a00e5b7619cff2463f4c063e6be5d511635cca7cff72c5ec8e2d6ab2feea7700e0a09181d13feeaa190bf4ae88de86b0adf2ad55a94864245c2d9f32ccba082e3d40a00c23af247cc206f2edaa46d98d290c8b49018909d6ed97b7346e7ef69e4fb5c4a03acdc865ba1b65c64f9c495fa01975869eb1472a9e87d321a8ffb8ea4dd53a33a00522f686e138ca2ae2b3063319e01b3caf8447d19a0a00affd567e673f57e3f1a048e346e25a5bba903ff0d73354f0289cd12adecef7a50f1a5e6b77fe840c3216a099820f0f4022552c5439640dfe42f18ac125ae827698341a20fc35fca1c9244680", - "0xf90211a01ec95bbb5cf4dc39f63683626c7b0a773d55160908ec99e59a5326380c73203ea0c5a50a01b607a8d5eef6ab0876a506c461d1c598bc4836516421ed1019d56bfaa01a976d9c6cc14e1f6047cbc492985d4812b7ca2f93cf63a2b34200a8212d7a54a040b68773658d419c60e169a84ff4b45594909c4a5daf2793d4d5356bbf8b0e2fa013167a747e7a5a34c9f207f50c62c44b717818ac25c3fcc0f1ff27d7487c8504a0640b788ab79273cb8b6785d078799e71cecd9c209e26c6f870e757ab9defde6ca0de36a43a3e775e7ee817093b16f423dc995f9444a29c9cd06e2f8232254cb95da03c4820d01e2a9e74f3e6da9db1566f5e94b3a933b9864e1702666fbae3175359a0f65de5b5290317566435b695d805ae983e659c93066b72fa09d34114d7dcbdd8a09b2c0648e974edef55f325dedd496139f35bc377ed3e9be17433ee7e8dba5643a0a720648153362da9c1e5ea94416af5f0a069b493ffacbd1def2efa256ced334aa0c5cb7b88ef6fb88d93301bc182581b5680551d1e6d9c518ccbb78f9da0dbe9e9a08070a83e329446fb9a61cbd358b1a14e8f633b5980ed39018a39e856e29fd7c3a055541ec7a175eb2b357bfc608c8c41a313c0e7432b5db3a45eb332bf39ffc705a074a59d2b10b98d80424671e0fed8b95c02c63f007279c77c8637201c806024b8a0a0dd938f251e9e58f33c56842e54e70f6edaac451cdd4ff908a4a845b8a094e180", - "0xf90211a05791255edb067e389d9230610cf6c0f2b5bdba04c787cc253b4408c0de058380a0f0e14c57af008db14bbd968eeeede1f66a277fbcf33d9d6dc7d7909269d31f69a0d63b643ad254d69b440f854ec3c29d0222093d6ee5c694ae130c9a2f30d750b0a0981b82957b34d3cdfcd9677c5c3e7e51f8907de9d62f4e2c1c7daabd53e98f18a0e1c921639a76503e3499702d6c7880c3dbc49e74e4f4e3145e897382819143dba06451b79e74690762041d77f207ae889e6d0379202f37591479e644dfe7e2ef3fa0d40d43938929bbc1656e2f5ad99476b953bb32ad8c81bc190650a34bad9b8befa0f2869cb5ace3192e29664e44073af68f0cee1c095baec010acba5eb710651841a0eb9cfad4c796fa13ad2692e3036e951480afb3b168fde14b59bd6ad5080a6922a0a7d8e8298485e3f6d2949c11ab2a5e2b5f685edf92e57fff7bbaec2d289fe150a08bb1562017cfe065095f8022e9c09e0e8dca556e37103f643f4ac7aa48ce6fa2a0801236ae1ab97c2ebd3d3d84a3649a70d947190a3bf03ff2e08c9566ccb48e96a0d677f601663075137b9a84af1134527bf8b1df1c7f02de4e6509be3892aad4e4a0b6c4e67c85d79a08878b349e1cce515d64fc28915ea3558053e1248ce70c5286a0d0a428122fb8105e813924660214896ec0851fd4f33e64851452476e817e2097a0727eeb8e9ea4e62815c0f46708a1527a9ff9fac9994c1442f9c118c0be8817b580", - "0xf90211a0969453ccd835ca415f87e7f63eb2a2c3d349616589c9bea36e6d9503b1418aa0a0a73b67797d24c75dd716fe6779f8a462a1671efb1a2d1433089eb0e2a17d105ca042a06440c9d52f7d6ffe8ab7c3c453a05a0243ba5aee609819bd5dacd8363be2a00a70d832a68a496c174ca785ba4bdddd5052ca3fb2410e4b667851fa7fb5272fa0af4e35e3f9b0617d7ff80cb79e1ef0921f21a41279292176d9e117f422595eb8a0a103553baefb54481ff0ea34d75edad63879182dd595e4aa8f85ca185cfa1abba081b203264801d3b0fdbefd7954900b4165dadb47a6ea210b92d8233429501a64a0f8e5f8ae8ac56d69b2e9ab881a0b853277e92833e7067b40651719d7bba31bfda0ebda38384f871cf603a4f5ad2a265e818aa91cbb68b4de1c2e1aadef084f4ceda08fa0b8481c834c6b4cb1a85d49b3509632ae55f5d194a69c821ad9753c3a5500a0aca036de251523a82f8188ef0525cc3d2e776aa786cf3457d8a483c4d1cf88a5a04f817b7b1e70e186f6f9ab7cea8f7437f7efb3aeeed22ba6a6ea380bfcf962a4a0cc6653c620e174f2d3e3e0756cbdeebc2cbcc1aa1c67cbf1c2ff8aaca84823c8a094e265b2c06fa02987213ade5598826a29e1a24bb04df2b102a646cfcede6c90a0f021a62413e90e1e8eaa49dc399a48a9d5ec3f84dfdbaa0a3b4a419dd1bde199a0e79d5f428c71f7435fa18cc01a6484a30dd43c781a3e5f14c95136dddd5901c880", - "0xf90211a05351d3596a31b5813aeed8088aec6f64b64ffb590a9b9a675e3c24917f1bd15ea00a098a769a5627b156bb55ef7d334a364443cbfe28431e2ff28165b44cb95542a01c7661008fe9ca32f0270d302d82979c1495343c9bf25e87dad3612929a5cb36a01f85cb40320b137c49e2ecb5aa3a3db85833c69747a86f2be7f4dc0d745742b2a03aa74296d38eb5c33bca5c94195da9f32a7217349e69575b84144268e6f1b2dca062ecf298a044531b19c8beea544f99197df6e8b54219a0f27dba4d4fa541babaa0b0cd63f95c67f0597165158d09c7c27d7d8202f9be608ae26dd5316433fe7b7ba0bf61c2af584a27b46bef9a14e527e7c0c2000e123d1bf39eccd59db47ecba01da0bf89e2fb3b1941518e2eb35824cdfa1245d6cb7bfbec99f6309a4d18fb9755a6a0a8b9e450a3d15bf70d4f9a6f6a3fd34dbd7eafcff3f0acb1d1ac6d162089b522a0250aa8ab557f89ffa83d661e8757f693b0d1315bca13d5bd1fc6897912a0ad45a0a962eba19068192509edcf9adf2b976ad84bd1bcd053bff075ec7ab214a80faaa0110825fe0f439d26bb6270e37fe89e8b9f9fab096420d5cbaddd04a349370209a0c7ff710535da560b7329183cd75aeeb34564ca01447eec54590bbdcfbdc8601ea09ff46c368e03322f356f1c5c863c4cf1aed1967bf39d020fb4bd0c281c68f0baa030a7ae32120f6c0a271f70f5323b5a4b7ec7c9b50eca8e62a9fe50b47b6fe09680", - "0xf90211a005d90b43639d8703b5b46e1a300ee59e21bc329ace56f5fd40a49f8c98c997c4a02634774fbdaf6c1380337541329edb575ca40bdf38f99d22f20c6599fb70a915a02b80f43a33554844dc3ad3b346db70a2edd74985b440c22fe70f51918c6e1464a0a685cffee53f88bfcfdede63aaf73becc1f5621c08390c13b02dc9de8cfc0521a0bbd2a32a4b54ebf626031f190e39c90724ffd91b9474d841b6eb9c0f76bc8ce7a0c860455b9da06b1e69e4aa952c787761acdb1603913b4965fae684cf016bcbdca067e8f57fae01bfed4e1add6a0b9ac5641be21ddf24ef18289e87035d75b871f5a0adabd78fddeaa6c42803f81a23e7991eb611e9ec1c9071a24022aac0a71a8ceea07307279fbc13f2f29a5f6c21add5106efa24f73ccb7ca02d460196e3810c37afa0392aa0794df746a43cb59907b892bf5aa78051b45c7ca1112c5b68a523623295a0a5e09e62e5cfff36c2dd8e738762140f943b6c2c85d8b5385f121f74ae01282ca00943c8def2f6f51ef2e99cbe99c50eb5f599bccb039529a874c6b3de3e5cd2e2a082affeb98e43b37d23515983324bc459bbf503ddcd51e9457acd9b1ee47ce4a1a0a3dc55ef190ed6ba960abae03c755928f46eafd5fec04db7b78345eddc1e16d0a0d8e9e0f89f9729526f4ba732797d9bb81e6eccfcf5778cde7e99545a313c8697a097c3d5a698982821f3354cf5a20a6673b5300019af36518f85e4759e554e4def80", - "0xf90171a0d346d1b6b8da1dfb0b97f26625ef03ef5636d748d022ce03898d32c8aeff119f80a0967b15d622a02ad2992db69e49b0460151757bf3b360df5fea408bea63c026cda09c6b26a5217537924d8783f57eaca4b17d0cf7bd2803ff372ca9e4c7c54bc29fa0cebf14dcf1027078e6c58277f932e1caa306aa29d12ebb690c54c5738124ae8880a05b45f21d20b4391a22b68e2d164a58c2a80d356968dfee8650c5e2516398ab8880a0e4b87f12645c511bcb763c404a18b754ee4644ae30097302385298a3f98aae10a056cf6e6079e53f30b464df39a4df44ef33d032009b46e60ad2204fdd5ea9033fa0fe4c7e738646adc940b306191f948c0c5cc7bd694d954c945d8c766d7ef34c92a0e8c65be6abb26a472102fc89faebc972b38d2badc20e7d7b16206d4b22f3462580a080b20dc002a994c21508d73e79464af914fa6d746bbba02477b512ad0eb7ea7f80a0c80aadfec76857d1cceeeec3cbd04f6923e36334fa394d20c0fa8e0da078e9e280", - "0xe58313f4a7a02023e131c23f3ffcfdc667ddfb152602a5584a3bc89d5fc721273d06280756c4", - "0xf851a0d19a48e137ace64957841715dac64aca2b13b67dcc281c40a5d0952ac474a61380808080808080808080808080a07028d519df1e68348cc0597fe6fa3335b181a3f0ddab251792916634c9d2ed9e8080", - "0xf8639a3252ed22ad4e036cb1f5cf3d262d5438ece2fc3097ed10fb737bb846f8448080a011de7f0b3b50bbe96191c2bb22b22933a18739348bc469ef3f995cfaf66c2352a0c2d83c5e1e5dcb9487d2b2b5689520b4377d503cc54d63b144f88cb21835595c", - ], - storageProof: [ - "0xf90111a0845a58d6992ac45fa0bcc607366bf7f88e0d03dc3dbce12a1cc4015c4d8abdeba0c26c8ac66961c484cbf850ff321be32b5ba99620fe480648db12d6783a17078aa04e918b76be51be2f02df0ac6191ec2765d401d2229e47291806815da755f5b5e80a06d7d944d988655e1fdc697223d3c3e115d005968e289f141c94f105d86c74196808080a0dc97b79c03ff591103b4961835f65de82a94c7166fc1e390f35deaa11b158c408080a057a2faf89e4b43c431600b5b6c687cdb6cbe5af08f9380158806b7e603da7b78a0f45cd6b758f905463cb8d116e78e191d983f7c26f98460306a7d6217c62da9778080a0a334cfbd70c0bfdfdce3d0aa560293be9cd496c2d47c8508c82f210b01dfc58680", - "0xe2a0390decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e56302", - ], - }, -]; - -describe("PatriciaMerkleTrieVerifier", async () => { - let verifier: MockPatriciaMerkleTrieVerifier; - - beforeEach(async () => { - const [deployer] = await ethers.getSigners(); - - const MockPatriciaMerkleTrieVerifier = await ethers.getContractFactory("MockPatriciaMerkleTrieVerifier", deployer); - verifier = await MockPatriciaMerkleTrieVerifier.deploy(); - }); - - for (const test of testcases) { - it(`should succeed for block[${test.block}] account[${test.account}] storage[${test.storage}]`, async () => { - const proof = concat([ - `0x0${test.accountProof.length.toString(16)}`, - ...test.accountProof, - `0x0${test.storageProof.length.toString(16)}`, - ...test.storageProof, - ]); - const [root, value, gasUsed] = await verifier.verifyPatriciaProof(test.account, test.storage, proof); - expect(test.expectedRoot).to.eq(root); - expect(test.expectedValue).to.eq(value); - console.log("gas usage:", gasUsed.toString()); - }); - } - - // @todo add tests with invalid inputs -}); diff --git a/contracts/integration-test/PoseidonHash.spec.ts b/contracts/integration-test/PoseidonHash.spec.ts deleted file mode 100644 index 21382580d..000000000 --- a/contracts/integration-test/PoseidonHash.spec.ts +++ /dev/null @@ -1,84 +0,0 @@ -/* eslint-disable node/no-missing-import */ -/* eslint-disable node/no-unpublished-import */ -import { expect } from "chai"; -import { randomBytes } from "crypto"; -import { Contract, toBigInt } from "ethers"; -import fs from "fs"; -import { ethers } from "hardhat"; - -import PoseidonWithoutDomain from "circomlib/src/poseidon_gencontract"; -import { generateABI, createCode } from "../scripts/poseidon"; - -describe("PoseidonHash.spec", async () => { - // test against with circomlib's implementation. - context("domain = zero", async () => { - let poseidonCircom: Contract; - let poseidon: Contract; - - beforeEach(async () => { - const [deployer] = await ethers.getSigners(); - - const PoseidonWithoutDomainFactory = new ethers.ContractFactory( - PoseidonWithoutDomain.generateABI(2), - PoseidonWithoutDomain.createCode(2), - deployer - ); - poseidonCircom = (await PoseidonWithoutDomainFactory.deploy()) as Contract; - - const PoseidonWithDomainFactory = new ethers.ContractFactory(generateABI(2), createCode(2), deployer); - poseidon = (await PoseidonWithDomainFactory.deploy()) as Contract; - }); - - it("should succeed on zero inputs", async () => { - expect(await poseidonCircom["poseidon(uint256[2])"]([0, 0])).to.eq( - await poseidon["poseidon(uint256[2],uint256)"]([0, 0], 0) - ); - }); - - it("should succeed on random inputs", async () => { - for (let bytes = 1; bytes <= 32; ++bytes) { - for (let i = 0; i < 5; ++i) { - const a = toBigInt(randomBytes(bytes)); - const b = toBigInt(randomBytes(bytes)); - expect(await poseidonCircom["poseidon(uint256[2])"]([a, b])).to.eq( - await poseidon["poseidon(uint256[2],uint256)"]([a, b], 0) - ); - expect(await poseidonCircom["poseidon(uint256[2])"]([a, 0])).to.eq( - await poseidon["poseidon(uint256[2],uint256)"]([a, 0], 0) - ); - expect(await poseidonCircom["poseidon(uint256[2])"]([0, b])).to.eq( - await poseidon["poseidon(uint256[2],uint256)"]([0, b], 0) - ); - } - } - }); - }); - - // test against with scroll's go implementation. - context("domain = nonzero", async () => { - let poseidon: Contract; - - beforeEach(async () => { - const [deployer] = await ethers.getSigners(); - const PoseidonWithDomainFactory = new ethers.ContractFactory(generateABI(2), createCode(2), deployer); - poseidon = (await PoseidonWithDomainFactory.deploy()) as Contract; - }); - - it("should succeed on zero inputs", async () => { - expect(await poseidon["poseidon(uint256[2],uint256)"]([0, 0], 6)).to.eq( - toBigInt("17848312925884193353134534408113064827548730776291701343555436351962284922129") - ); - expect(await poseidon["poseidon(uint256[2],uint256)"]([0, 0], 7)).to.eq( - toBigInt("20994231331856095272861976502721128670019193481895476667943874333621461724676") - ); - }); - - it("should succeed on random inputs", async () => { - const lines = String(fs.readFileSync("./integration-test/testdata/poseidon_hash_with_domain.data")).split("\n"); - for (const line of lines) { - const [domain, a, b, hash] = line.split(" "); - expect(await poseidon["poseidon(uint256[2],uint256)"]([a, b], domain)).to.eq(toBigInt(hash)); - } - }); - }); -}); diff --git a/contracts/integration-test/ScrollChain.blob.spec.ts b/contracts/integration-test/ScrollChain.blob.spec.ts deleted file mode 100644 index 4f6689c6c..000000000 --- a/contracts/integration-test/ScrollChain.blob.spec.ts +++ /dev/null @@ -1,149 +0,0 @@ -/* eslint-disable node/no-unpublished-import */ -/* eslint-disable node/no-missing-import */ -import { ZeroAddress } from "ethers"; -import { ethers } from "hardhat"; - -import { ScrollChain, L1MessageQueue } from "../typechain"; -import { HardhatEthersSigner } from "@nomicfoundation/hardhat-ethers/signers"; -import { randomBytes } from "crypto"; -import { expect } from "chai"; - -describe("ScrollChain.blob", async () => { - let deployer: HardhatEthersSigner; - let signer: HardhatEthersSigner; - - let queue: L1MessageQueue; - let chain: ScrollChain; - - beforeEach(async () => { - [deployer, signer] = await ethers.getSigners(); - - const EmptyContract = await ethers.getContractFactory("EmptyContract", deployer); - const empty = await EmptyContract.deploy(); - - const ProxyAdmin = await ethers.getContractFactory("ProxyAdmin", deployer); - const admin = await ProxyAdmin.deploy(); - - const TransparentUpgradeableProxy = await ethers.getContractFactory("TransparentUpgradeableProxy", deployer); - const queueProxy = await TransparentUpgradeableProxy.deploy(empty.getAddress(), admin.getAddress(), "0x"); - const chainProxy = await TransparentUpgradeableProxy.deploy(empty.getAddress(), admin.getAddress(), "0x"); - - const L1MessageQueue = await ethers.getContractFactory("L1MessageQueue", deployer); - const queueImpl = await L1MessageQueue.deploy(deployer.address, chainProxy.getAddress(), deployer.address); - await admin.upgrade(queueProxy.getAddress(), queueImpl.getAddress()); - - const ScrollChain = await ethers.getContractFactory("ScrollChain", deployer); - const chainImpl = await ScrollChain.deploy(0, queueProxy.getAddress(), deployer.address); - await admin.upgrade(chainProxy.getAddress(), chainImpl.getAddress()); - - queue = await ethers.getContractAt("L1MessageQueue", await queueProxy.getAddress(), deployer); - chain = await ethers.getContractAt("ScrollChain", await chainProxy.getAddress(), deployer); - - await chain.initialize(queue.getAddress(), ZeroAddress, 100); - await chain.addSequencer(deployer.address); - await chain.addProver(deployer.address); - await queue.initialize(deployer.address, chain.getAddress(), deployer.address, deployer.address, 10000000); - }); - - context("commit batch", async () => { - let batchHeader0: Uint8Array; - - beforeEach(async () => { - // import 10 L1 messages - for (let i = 0; i < 10; i++) { - queue.appendCrossDomainMessage(deployer.address, 1000000, "0x"); - } - - // import genesis batch first - batchHeader0 = new Uint8Array(89); - batchHeader0[25] = 1; - await chain.importGenesisBatch(batchHeader0, randomBytes(32)); - }); - - it("should revert when caller is not sequencer", async () => { - await expect(chain.connect(signer).commitBatch(1, batchHeader0, [], "0x")).to.revertedWithCustomError( - chain, - "ErrorCallerIsNotSequencer" - ); - }); - - it("should revert when batch is empty", async () => { - await expect(chain.commitBatch(1, batchHeader0, [], "0x")).to.revertedWithCustomError(chain, "ErrorBatchIsEmpty"); - }); - - it("should revert when batch header length too small", async () => { - const header = new Uint8Array(120); - header[0] = 1; - await expect(chain.commitBatch(1, header, ["0x"], "0x")).to.revertedWithCustomError( - chain, - "ErrorBatchHeaderLengthTooSmall" - ); - }); - - it("should revert when wrong bitmap length", async () => { - const header = new Uint8Array(122); - header[0] = 1; - await expect(chain.commitBatch(1, header, ["0x"], "0x")).to.revertedWithCustomError( - chain, - "ErrorIncorrectBitmapLength" - ); - }); - - it("should revert when incorrect parent batch hash", async () => { - batchHeader0[25] = 2; - await expect(chain.commitBatch(1, batchHeader0, ["0x"], "0x")).to.revertedWithCustomError( - chain, - "ErrorIncorrectBatchHash" - ); - batchHeader0[25] = 1; - }); - - it("should revert when ErrorNoBlobFound", async () => { - await expect(chain.commitBatch(1, batchHeader0, ["0x"], "0x")).to.revertedWithCustomError( - chain, - "ErrorNoBlobFound" - ); - }); - - /* Hardhat doesn't have support for EIP4844 yet. - const makeTransaction = async (data: string, value: bigint, blobVersionedHashes: Array) => { - const tx = new Transaction(); - tx.type = 3; - tx.to = await chain.getAddress(); - tx.data = data; - tx.nonce = await deployer.getNonce(); - tx.gasLimit = 1000000; - tx.maxPriorityFeePerGas = (await ethers.provider.getFeeData()).maxPriorityFeePerGas; - tx.maxFeePerGas = (await ethers.provider.getFeeData()).maxFeePerGas; - tx.value = value; - tx.chainId = (await ethers.provider.getNetwork()).chainId; - tx.maxFeePerBlobGas = ethers.parseUnits("1", "gwei"); - tx.blobVersionedHashes = blobVersionedHashes; - return tx; - }; - - it("should revert when ErrorFoundMultipleBlob", async () => { - const data = chain.interface.encodeFunctionData("commitBatch", [1, batchHeader0, ["0x"], "0x"]); - const tx = await makeTransaction(data, 0n, [ZeroHash, ZeroHash]); - const signature = await deployer.signMessage(tx.unsignedHash); - tx.signature = Signature.from(signature); - const r = await ethers.provider.broadcastTransaction(tx.serialized); - await expect(r).to.revertedWithCustomError(chain, "ErrorFoundMultipleBlob"); - }); - - it("should revert when ErrorNoBlockInChunk", async () => {}); - - it("should revert when ErrorIncorrectChunkLength", async () => {}); - - it("should revert when ErrorLastL1MessageSkipped", async () => {}); - - it("should revert when ErrorNumTxsLessThanNumL1Msgs", async () => {}); - - it("should revert when ErrorTooManyTxsInOneChunk", async () => {}); - - it("should revert when ErrorIncorrectBitmapLength", async () => {}); - - it("should succeed", async () => {}); - */ - }); -}); diff --git a/contracts/integration-test/ScrollChain.spec.ts b/contracts/integration-test/ScrollChain.spec.ts deleted file mode 100644 index 256a41017..000000000 --- a/contracts/integration-test/ScrollChain.spec.ts +++ /dev/null @@ -1,92 +0,0 @@ -/* eslint-disable node/no-unpublished-import */ -/* eslint-disable node/no-missing-import */ -import { ZeroAddress, concat, getBytes } from "ethers"; -import { ethers } from "hardhat"; - -import { ScrollChain, L1MessageQueue } from "../typechain"; - -describe("ScrollChain", async () => { - let queue: L1MessageQueue; - let chain: ScrollChain; - - beforeEach(async () => { - const [deployer] = await ethers.getSigners(); - - const EmptyContract = await ethers.getContractFactory("EmptyContract", deployer); - const empty = await EmptyContract.deploy(); - - const ProxyAdmin = await ethers.getContractFactory("ProxyAdmin", deployer); - const admin = await ProxyAdmin.deploy(); - - const TransparentUpgradeableProxy = await ethers.getContractFactory("TransparentUpgradeableProxy", deployer); - const queueProxy = await TransparentUpgradeableProxy.deploy(empty.getAddress(), admin.getAddress(), "0x"); - const chainProxy = await TransparentUpgradeableProxy.deploy(empty.getAddress(), admin.getAddress(), "0x"); - - const L1MessageQueue = await ethers.getContractFactory("L1MessageQueue", deployer); - const queueImpl = await L1MessageQueue.deploy(ZeroAddress, chainProxy.getAddress(), deployer.address); - await admin.upgrade(queueProxy.getAddress(), queueImpl.getAddress()); - - const ScrollChain = await ethers.getContractFactory("ScrollChain", deployer); - const chainImpl = await ScrollChain.deploy(0, queueProxy.getAddress(), deployer.address); - await admin.upgrade(chainProxy.getAddress(), chainImpl.getAddress()); - - queue = await ethers.getContractAt("L1MessageQueue", await queueProxy.getAddress(), deployer); - chain = await ethers.getContractAt("ScrollChain", await chainProxy.getAddress(), deployer); - - await chain.initialize(queue.getAddress(), ZeroAddress, 100); - await chain.addSequencer(deployer.address); - await queue.initialize(ZeroAddress, chain.getAddress(), ZeroAddress, ZeroAddress, 10000000); - }); - - // @note skip this benchmark tests - it.skip("should succeed", async () => { - const batchHeader0 = new Uint8Array(89); - batchHeader0[25] = 1; - await chain.importGenesisBatch(batchHeader0, "0x0000000000000000000000000000000000000000000000000000000000000001"); - const parentBatchHash = await chain.committedBatches(0); - console.log("genesis batch hash:", parentBatchHash); - console.log(`ChunkPerBatch`, `BlockPerChunk`, `TxPerBlock`, `BytesPerTx`, `TotalBytes`, `EstimateGas`); - for (let numChunks = 3; numChunks <= 6; ++numChunks) { - for (let numBlocks = 1; numBlocks <= 5; ++numBlocks) { - for (let numTx = 20; numTx <= Math.min(30, 100 / numBlocks); ++numTx) { - for (let txLength = 800; txLength <= 1000; txLength += 100) { - const txs: Array = []; - for (let i = 0; i < numTx; i++) { - const tx = new Uint8Array(4 + txLength); - let offset = 3; - for (let x = txLength; x > 0; x = Math.floor(x / 256)) { - tx[offset] = x % 256; - offset -= 1; - } - tx.fill(1, 4); - txs.push(tx); - } - const chunk = new Uint8Array(1 + 60 * numBlocks); - chunk[0] = numBlocks; - for (let i = 0; i < numBlocks; i++) { - chunk[1 + i * 60 + 57] = numTx; - } - const chunks: Array = []; - for (let i = 0; i < numChunks; i++) { - const txsInChunk: Array = []; - for (let j = 0; j < numBlocks; j++) { - txsInChunk.push(getBytes(concat(txs))); - } - chunks.push(getBytes(concat([chunk, concat(txsInChunk)]))); - } - - const estimateGas = await chain.commitBatch.estimateGas(0, batchHeader0, chunks, "0x"); - console.log( - `${numChunks}`, - `${numBlocks}`, - `${numTx}`, - `${txLength}`, - `${numChunks * numBlocks * numTx * (txLength + 1)}`, - `${estimateGas.toString()}` - ); - } - } - } - } - }); -}); diff --git a/contracts/integration-test/ZkEvmVerifierV1.spec.ts b/contracts/integration-test/ZkEvmVerifierV1.spec.ts deleted file mode 100644 index f20ffa85a..000000000 --- a/contracts/integration-test/ZkEvmVerifierV1.spec.ts +++ /dev/null @@ -1,45 +0,0 @@ -/* eslint-disable node/no-unpublished-import */ -/* eslint-disable node/no-missing-import */ -import { HardhatEthersSigner } from "@nomicfoundation/hardhat-ethers/signers"; -import { expect } from "chai"; -import { hexlify } from "ethers"; -import fs from "fs"; -import { ethers } from "hardhat"; - -import { ZkEvmVerifierV1 } from "../typechain"; - -describe("ZkEvmVerifierV1", async () => { - let deployer: HardhatEthersSigner; - - let zkEvmVerifier: ZkEvmVerifierV1; - - beforeEach(async () => { - [deployer] = await ethers.getSigners(); - - const bytecode = hexlify(fs.readFileSync("./src/libraries/verifier/plonk-verifier/plonk_verifier_0.9.8.bin")); - const tx = await deployer.sendTransaction({ data: bytecode }); - const receipt = await tx.wait(); - - const ZkEvmVerifierV1 = await ethers.getContractFactory("ZkEvmVerifierV1", deployer); - zkEvmVerifier = await ZkEvmVerifierV1.deploy(receipt!.contractAddress!); - }); - - it("should succeed", async () => { - const proof = hexlify(fs.readFileSync("./integration-test/testdata/plonk_verifier_0.9.8_proof.data")); - const instances = fs.readFileSync("./integration-test/testdata/plonk_verifier_0.9.8_pi.data"); - - const publicInputHash = new Uint8Array(32); - for (let i = 0; i < 32; i++) { - publicInputHash[i] = instances[i * 32 + 31]; - } - - expect(hexlify(publicInputHash)).to.eq("0x31b430667bc9e8a8b7eda5e5c76f2250c64023f5f8e0689ac9f4e53f5362da66"); - - // verify ok - await zkEvmVerifier.verify(proof, publicInputHash); - console.log("Gas Usage:", (await zkEvmVerifier.verify.estimateGas(proof, publicInputHash)).toString()); - - // verify failed - await expect(zkEvmVerifier.verify(proof, publicInputHash.reverse())).to.reverted; - }); -}); diff --git a/contracts/integration-test/ZkTrieVerifier.spec.ts b/contracts/integration-test/ZkTrieVerifier.spec.ts deleted file mode 100644 index c76724af0..000000000 --- a/contracts/integration-test/ZkTrieVerifier.spec.ts +++ /dev/null @@ -1,604 +0,0 @@ -/* eslint-disable node/no-unpublished-import */ -/* eslint-disable node/no-missing-import */ -import { expect } from "chai"; -import { ethers } from "hardhat"; - -import { generateABI, createCode } from "../scripts/poseidon"; -import { MockZkTrieVerifier } from "../typechain"; -import { concat } from "ethers"; - -const chars = "0123456789abcdef"; - -interface ITestConfig { - block: number; - desc: string; - account: string; - storage: string; - expectedRoot: string; - expectedValue: string; - accountProof: string[]; - storageProof: string[]; -} - -const testcases: Array = [ - { - // curl -H "content-type: application/json" -X POST --data '{"id":0,"jsonrpc":"2.0","method":"eth_getProof","params":["0x5300000000000000000000000000000000000004", ["0x8391082587ea494a8beba02cc40273f27e5477a967cd400736ac46950da0b378"], "0x1111ad"]}' https://rpc.scroll.io - block: 1118637, - desc: "WETH.balance[0xa7994f02237aed2c116a702a8f5322a1fb325b31]", - account: "0x5300000000000000000000000000000000000004", - storage: "0x8391082587ea494a8beba02cc40273f27e5477a967cd400736ac46950da0b378", - expectedRoot: "0x1334a21a74914182745c1f5142e70b487262096784ae7669186657462c01b103", - expectedValue: "0x00000000000000000000000000000000000000000000000000006239b5a2c000", - accountProof: [ - "0x0907d980105678a2007eb5683d850f36a9caafe6e7fd3279987d7a94a13a360d3a1478f9a4c1f8c755227ee3544929bb0d7cfa2d999a48493d048ff0250bb002ab", - "0x092b59a024f142555555c767842c4fcc3996686c57699791fcb10013f69ffd9b2507360087cb303767fd43f2650960621246a8d205d086e03d9c1626e4aaa5b143", - "0x091f876342916ac1d5a14ef40cfc5644452170b16d1b045877f303cd52322ba1e00ba09f36443c2a63fbd7ff8feeb2c84e99fde6db08fd8e4c67ad061c482ff276", - "0x09277b3069a4b944a45df222366aae727ec64efaf0a8ecb000645d0eea3a3fa93609b925158cc04f610f8c616369094683ca7a86239f49e97852aa286d148a3913", - "0x092fb789200a7324067934da8be91c48f86c4e6f35fed6d1ce8ae4d7051f480bc0074019222c788b139b6919dfbc9d0b51f274e0ed3ea03553b8db30392ac05ce4", - "0x092f79da8f9f2c3a3a3813580ff18d4619b95f54026b2f16ccbcca684d5e25e1f52912fa319d9a7ba537a52cc6571844b4d1aa99b8a78cea6f686a6279ade5dcae", - "0x09249d249bcf92a369bd7715ec63a4b29d706a5dbb304efd678a2e5d7982e7fa9b202e3225c1031d83ab62d78516a4cbdbf2b22842c57182e7cb0dbb4303ac38c5", - "0x0904837ebb85ceccab225d4d826fe57edca4b00862199b91082f65dfffa7669b90039c710273b02e60c2e74eb8b243721e852e0e56fa51668b6362fd920f817cb7", - "0x090a36f6aabc3768a05dd8f93667a0eb2e5b63d94b5ce27132fb38d13c56d49cb4249c2013daee90184ae285226271f150f6a8f74f2c85dbd0721c5f583e620b10", - "0x091b82f139a06af573e871fdd5f5ac18f17c568ffe1c9e271505b371ad7f0603e716b187804a49d2456a0baa7c2317c14d9aa7e58ad64df38bc6c1c7b86b072333", - "0x0929668e59dfc2e2aef10194f5d287d8396e1a897d68f106bdb12b9541c0bab71d2bf910dea11e3209b3feff88d630af46006e402e935bc84c559694d88c117733", - "0x0914231c92f09f56628c10603dc2d2120d9d11b27fa23753a14171127c3a1ee3dd0d6b9cbd11d031fe6e1b650023edc58aa580fa4f4aa1b30bf82e0e4c7a308bb9", - "0x0914c1dd24c520d96aac93b7ef3062526067f1b15a080c482abf449d3c2cde781b195eb63b5e328572090319310914d81b2ca8350b6e15dc9d13e878f8c28c9d52", - "0x0927cb93e3d9c144a5a3653c5cf2ed5940d64f461dd588cd192516ae7d855e9408166e85986d4c9836cd6cd822174ba9db9c7a043d73e86b5b2cfc0a2e082894c3", - "0x090858bf8a0119626fe9339bd92116a070ba1a66423b0f7d3f4666b6851fdea01400f7f51eb22df168c41162d7f18f9d97155d87da523b05a1dde54e7a30a98c31", - "0x0902776c1f5f93a95baea2e209ddb4a5e49dd1112a7f7d755a45addffe4a233dad0d8cc62b957d9b254fdc8199c720fcf8d5c65d14899911e991b4530710aca75e", - "0x091d7fde5c78c88bbf6082a20a185cde96a203ea0d29c829c1ab9322fc3ca0ae3100ef7cba868cac216d365a0232ad6227ab1ef3290166bc6c19b719b79dbc17fc", - "0x091690160269c53c6b74337a00d02cb40a88ea5eba06e1942088b619baee83279e12d96d62dda9c4b5897d58fea40b5825d87a5526dec37361ec7c93a3256ea76d", - "0x091bccb091cde3f8ca7cfda1df379c9bfa412908c41037ae4ec0a20ce984e2c9a51d02c109d2e6e25dc60f10b1bc3b3f97ca1ce1aa025ce4f3146de3979403b99e", - "0x0927083540af95e57acba69671a4a596f721432549b8760941f4251e0dd7a013a917cee0f60d333cf88e40ae8710fb1fd6e3920346a376b3ba6686a4b2020a043e", - "0x082170b57b8f05f6990eec62e74cdb303741f6c464a85d68582c19c51e53f490000a5029a62ddc14c9c07c549db300bd308b6367454966c94b8526f4ceed5693b2", - "0x0827a0b16ef333dcfe00610d19dc468b9e856f544c9b5e9b046357e0a38aedaeb90000000000000000000000000000000000000000000000000000000000000000", - "0x06126f891e8753e67c5cbfa2a67e9d71942eab3a88cde86e97a4af94ea0dde497821fb69ccdb00e6eaeaf7fc1e73630f39f846970b72ac801e396da0033fb0c247", - "0x0420e9fb498ff9c35246d527da24aa1710d2cc9b055ecf9a95a8a2a11d3d836cdf050800000000000000000000000000000000000000000000000016ef00000000000000000000000000000000000000000000000000000000000000600058d1a5ce14104d0dedcaecaab39b6e22c2608e40af67a71908e6e97bbf4a43c59c4537140c25a9e8c4073351c26b9831c1e5af153b9be4713a4af9edfdf32b58077b735e120f14136a7980da529d9e8d3a71433fc9dc5aa8c01e3a4eb60cb3a4f9cf9ca5c8e0be205300000000000000000000000000000000000004000000000000000000000000", - "0x5448495320495320534f4d45204d4147494320425954455320464f5220534d54206d3172525867503278704449", - ], - storageProof: [ - "0x09240ea2601c34d792a0a5a8a84d8e501cfdfdf2c10ef13ea560acac58661882dd1b3644d1d4f3e32fc78498a7ebeffac8c6a494ac6f36923ef1be476444c0d564", - "0x0912af3ac8f8ea443e6d89d071fccaa2b3c8462220c1c2921234f613b41594f08f2a170e61f5f436b536c155b438044cf0d0f24b94b4c034ad22b3eae824998243", - "0x0916011d547d7a54929c3515078f4f672c6b390ccdd4119f0776376910bc5a38da1a059ed9c504fadcc9f77e8a402175743bee1f5be27b7002b0f6c5b51070452c", - "0x09017285edc268d979eb410b46627e541afda16cdb3577ce04c15dc14cc6609c60143f0c01e71e99b2efbe3d8e62a2c812889aa9fd88dd4b0ed8eadcf1ec9b096a", - "0x0922901e65200b007ad8e1b972e90403b336e459e0cf9b9d68732da345b1b0f6872c9e3f3edacbd857b26d0a66a80aa56c6ebaa9849e9ea5a2b17fd59cabe138e4", - "0x091b77a00164a72880eec6c18fc043fa99f922e20bbee156e1ebfd3a358bee6bbb24d97cfaa234befe197a567476cade91b7d97a1017b8d5286dae4dddadffe1cd", - "0x09216f1c4d67a9a428885bb8d978ad369d2d69d4dcc1692c3a0c3ea05da7d6f0ac2d6dda722e76eb513c67718e7be0478851758be5547322473a53b5b2b67faf95", - "0x091f56c6f18ceb7077125df1ed17a42a85956090594125c1b182161de20f8af6aa2e36977412f9ea2ad2c0951153969eca8408317558ff1b6b4ad731726235f606", - "0x092ca197dda6c519d80296f4fcda2933df9608ec684ad000133259024041d070812d29b058a998cf7ffc647b2739041725d77889f58953799c6aba6d9e5b981fc8", - "0x091c25a87d321a09ad2a149d1a7eaa77727c7feffb4c39caf44f8edd4377f7bd0c16d1091494d3c90d301c1cb4596692798e78e4cc3d53c3a08e2641de43f9da18", - "0x092166058c98245eb85b08da1c569df11f86b00cc44212a9a8ee0d60556d05a8030942c68b535651e11af38264ecc89e5f79b66c3d9ce87233ad65d4894a3d1c3d", - "0x0908c3b13b7400630170baec7448c7ec99fa9100cad373e189e42aca121e2c8f450f9e40d92d98bb0b1286a18581591fddfa8637fc941c1630237293d69e5cb98f", - "0x091362d251bbd8b255d63cd91bcfc257b8fb3ea608ce652784e3db11b22ca86c0122a0068fa1f1d54f313bed9fd9209212af3f366e4ff28092bf42c4abebffe10a", - "0x081d67961bb431a9da78eb976fabd641e20fbf4b7e32eb3faac7dfb5abb50f1faf1438d77000c1cf96c9d61347e1351eb0200260ebe523e69f6e9f334ec86e6b58", - "0x0819324d2488778bdef23319a6832001ee85f578cc920670c81f3645f898a46ec62e00385c4416ca4ccbab237b13396e5e25e5da12101021c6a6f9ecfe7c7fed19", - "0x041421380c36ea8ef65a9bdb0202b06d1e03f52857cdfea3795463653eaa3dd7d80101000000000000000000000000000000000000000000000000000000006239b5a2c000208391082587ea494a8beba02cc40273f27e5477a967cd400736ac46950da0b378", - "0x5448495320495320534f4d45204d4147494320425954455320464f5220534d54206d3172525867503278704449", - ], - }, - { - // curl -H "content-type: application/json" -X POST --data '{"id":0,"jsonrpc":"2.0","method":"eth_getProof","params":["0x5300000000000000000000000000000000000004", ["0x0000000000000000000000000000000000000000000000000000000000000002"], "0x1111ad"]}' https://rpc.scroll.io - block: 1118637, - desc: "WETH.totalSupply", - account: "0x5300000000000000000000000000000000000004", - storage: "0x0000000000000000000000000000000000000000000000000000000000000002", - expectedRoot: "0x1334a21a74914182745c1f5142e70b487262096784ae7669186657462c01b103", - expectedValue: "0x0000000000000000000000000000000000000000000000600058d1a5ce14104d", - accountProof: [ - "0x0907d980105678a2007eb5683d850f36a9caafe6e7fd3279987d7a94a13a360d3a1478f9a4c1f8c755227ee3544929bb0d7cfa2d999a48493d048ff0250bb002ab", - "0x092b59a024f142555555c767842c4fcc3996686c57699791fcb10013f69ffd9b2507360087cb303767fd43f2650960621246a8d205d086e03d9c1626e4aaa5b143", - "0x091f876342916ac1d5a14ef40cfc5644452170b16d1b045877f303cd52322ba1e00ba09f36443c2a63fbd7ff8feeb2c84e99fde6db08fd8e4c67ad061c482ff276", - "0x09277b3069a4b944a45df222366aae727ec64efaf0a8ecb000645d0eea3a3fa93609b925158cc04f610f8c616369094683ca7a86239f49e97852aa286d148a3913", - "0x092fb789200a7324067934da8be91c48f86c4e6f35fed6d1ce8ae4d7051f480bc0074019222c788b139b6919dfbc9d0b51f274e0ed3ea03553b8db30392ac05ce4", - "0x092f79da8f9f2c3a3a3813580ff18d4619b95f54026b2f16ccbcca684d5e25e1f52912fa319d9a7ba537a52cc6571844b4d1aa99b8a78cea6f686a6279ade5dcae", - "0x09249d249bcf92a369bd7715ec63a4b29d706a5dbb304efd678a2e5d7982e7fa9b202e3225c1031d83ab62d78516a4cbdbf2b22842c57182e7cb0dbb4303ac38c5", - "0x0904837ebb85ceccab225d4d826fe57edca4b00862199b91082f65dfffa7669b90039c710273b02e60c2e74eb8b243721e852e0e56fa51668b6362fd920f817cb7", - "0x090a36f6aabc3768a05dd8f93667a0eb2e5b63d94b5ce27132fb38d13c56d49cb4249c2013daee90184ae285226271f150f6a8f74f2c85dbd0721c5f583e620b10", - "0x091b82f139a06af573e871fdd5f5ac18f17c568ffe1c9e271505b371ad7f0603e716b187804a49d2456a0baa7c2317c14d9aa7e58ad64df38bc6c1c7b86b072333", - "0x0929668e59dfc2e2aef10194f5d287d8396e1a897d68f106bdb12b9541c0bab71d2bf910dea11e3209b3feff88d630af46006e402e935bc84c559694d88c117733", - "0x0914231c92f09f56628c10603dc2d2120d9d11b27fa23753a14171127c3a1ee3dd0d6b9cbd11d031fe6e1b650023edc58aa580fa4f4aa1b30bf82e0e4c7a308bb9", - "0x0914c1dd24c520d96aac93b7ef3062526067f1b15a080c482abf449d3c2cde781b195eb63b5e328572090319310914d81b2ca8350b6e15dc9d13e878f8c28c9d52", - "0x0927cb93e3d9c144a5a3653c5cf2ed5940d64f461dd588cd192516ae7d855e9408166e85986d4c9836cd6cd822174ba9db9c7a043d73e86b5b2cfc0a2e082894c3", - "0x090858bf8a0119626fe9339bd92116a070ba1a66423b0f7d3f4666b6851fdea01400f7f51eb22df168c41162d7f18f9d97155d87da523b05a1dde54e7a30a98c31", - "0x0902776c1f5f93a95baea2e209ddb4a5e49dd1112a7f7d755a45addffe4a233dad0d8cc62b957d9b254fdc8199c720fcf8d5c65d14899911e991b4530710aca75e", - "0x091d7fde5c78c88bbf6082a20a185cde96a203ea0d29c829c1ab9322fc3ca0ae3100ef7cba868cac216d365a0232ad6227ab1ef3290166bc6c19b719b79dbc17fc", - "0x091690160269c53c6b74337a00d02cb40a88ea5eba06e1942088b619baee83279e12d96d62dda9c4b5897d58fea40b5825d87a5526dec37361ec7c93a3256ea76d", - "0x091bccb091cde3f8ca7cfda1df379c9bfa412908c41037ae4ec0a20ce984e2c9a51d02c109d2e6e25dc60f10b1bc3b3f97ca1ce1aa025ce4f3146de3979403b99e", - "0x0927083540af95e57acba69671a4a596f721432549b8760941f4251e0dd7a013a917cee0f60d333cf88e40ae8710fb1fd6e3920346a376b3ba6686a4b2020a043e", - "0x082170b57b8f05f6990eec62e74cdb303741f6c464a85d68582c19c51e53f490000a5029a62ddc14c9c07c549db300bd308b6367454966c94b8526f4ceed5693b2", - "0x0827a0b16ef333dcfe00610d19dc468b9e856f544c9b5e9b046357e0a38aedaeb90000000000000000000000000000000000000000000000000000000000000000", - "0x06126f891e8753e67c5cbfa2a67e9d71942eab3a88cde86e97a4af94ea0dde497821fb69ccdb00e6eaeaf7fc1e73630f39f846970b72ac801e396da0033fb0c247", - "0x0420e9fb498ff9c35246d527da24aa1710d2cc9b055ecf9a95a8a2a11d3d836cdf050800000000000000000000000000000000000000000000000016ef00000000000000000000000000000000000000000000000000000000000000600058d1a5ce14104d0dedcaecaab39b6e22c2608e40af67a71908e6e97bbf4a43c59c4537140c25a9e8c4073351c26b9831c1e5af153b9be4713a4af9edfdf32b58077b735e120f14136a7980da529d9e8d3a71433fc9dc5aa8c01e3a4eb60cb3a4f9cf9ca5c8e0be205300000000000000000000000000000000000004000000000000000000000000", - "0x5448495320495320534f4d45204d4147494320425954455320464f5220534d54206d3172525867503278704449", - ], - storageProof: [ - "0x09240ea2601c34d792a0a5a8a84d8e501cfdfdf2c10ef13ea560acac58661882dd1b3644d1d4f3e32fc78498a7ebeffac8c6a494ac6f36923ef1be476444c0d564", - "0x0912af3ac8f8ea443e6d89d071fccaa2b3c8462220c1c2921234f613b41594f08f2a170e61f5f436b536c155b438044cf0d0f24b94b4c034ad22b3eae824998243", - "0x0916011d547d7a54929c3515078f4f672c6b390ccdd4119f0776376910bc5a38da1a059ed9c504fadcc9f77e8a402175743bee1f5be27b7002b0f6c5b51070452c", - "0x092293af71b7b9315c32d08f06e291b85e3b3dbba786dd31952369f666281aa21125ab35feae70aaca9349f6af48f7dcf2dee0324e4eae03e929963e7728b633a3", - "0x090607033a4b976c1e4683298d66b88a95ed45033ff43dea0670d84a8c42d35bf12562869385c0e70f561f18be4b78e7276b837f140a45ab12ffef1ba4ad5faecb", - "0x090abc5f713c2f58583114bb5081d00cbd01789d8efbd95e471b151c71c475142f0f52ad30f8a63288eb9dd12aca2a670de08c03f8384f55d730c943e1c472625b", - "0x0905156e8704d6195f6ae562aed2072f4e32422c6dfd4840ca354b9c4d2de5ce760fca52b1e0689ad374bae9fbea262a929f919695149a083fe6bacb806dc02fca", - "0x0917078d4c193a3fdbfe8ce3a235a0e1df89e626b5e91636097e299883fc2447892ad46eefbb27909544fe02c05e29760315749f6ce21c17c52158f5f5616c2dad", - "0x0917d02e5da8bdb969149c9327b247a6aaa479bcda4a03665da5103c10e616d2f40ccabdacdd25b34235d26e50e7af5d8d312a2cafdcadd41cc589a71a322f254c", - "0x090c62f5c476c1def8ed8a8c25ae54581690b39dfab4b0f3f78b93df96f626714328ea922a76a058087563bb5370664e9a1cebe3062f2d904bf5e3a018219d6563", - "0x091e481971f770e587b1f62f1da9ac4687abc5b2a23097fc38332e15ab957ca0ab0ec0a95c15313887e0d2f166c100deaf17f2ce50767680e6e5b2e3068801c0cd", - "0x0911799e186f1bd299dfa08c07404b9d28e2b179fb6ad523f1846872537b6db85f198b573ac1397048258de38b391fcc5e0c86a0f81f4ca607785fb37041ab8b4d", - "0x092053a028cf3bfcdabcb58985efc39f078cb0bcae4439528a0b6fe4b24bbdbd2c019a04a54e9e96077f3c2c39c1602a83387018b6357ea4c28e96764865d1c8f3", - "0x07303fad3e4628ccae4de1adb41996c9f38b22445b6525ff163b4c68cbde275b1a06111cae9b4d17b730d94f589e20c6ae2cb59bf0b40ad05bf58703ee6d46eac4", - "0x0606bc3fca1f1b3c877aa01a765c18db8b0d7f0bc50bd99f21223055bf1595c84d04fdc0fd416d8402fde743d908d032a20af6f2e65cdc6cc289f72c04f1c2476f", - "0x04020953ad52de135367a1ba2629636216ed5174cce5629d11b5d97fe733f07dcc010100000000000000000000000000000000000000000000000000600058d1a5ce14104d200000000000000000000000000000000000000000000000000000000000000002", - "0x5448495320495320534f4d45204d4147494320425954455320464f5220534d54206d3172525867503278704449", - ], - }, - { - // curl -H "content-type: application/json" -X POST --data '{"id":0,"jsonrpc":"2.0","method":"eth_getProof","params":["0x5300000000000000000000000000000000000004", ["0x0000000000000000000000000000000000000000000000000000000000002222"], "0x1111ad"]}' https://rpc.scroll.io - block: 1118637, - desc: "random empty storage in WETH", - account: "0x5300000000000000000000000000000000000004", - storage: "0x0000000000000000000000000000000000000000000000000000000000002222", - expectedRoot: "0x1334a21a74914182745c1f5142e70b487262096784ae7669186657462c01b103", - expectedValue: "0x0000000000000000000000000000000000000000000000000000000000000000", - accountProof: [ - "0x0907d980105678a2007eb5683d850f36a9caafe6e7fd3279987d7a94a13a360d3a1478f9a4c1f8c755227ee3544929bb0d7cfa2d999a48493d048ff0250bb002ab", - "0x092b59a024f142555555c767842c4fcc3996686c57699791fcb10013f69ffd9b2507360087cb303767fd43f2650960621246a8d205d086e03d9c1626e4aaa5b143", - "0x091f876342916ac1d5a14ef40cfc5644452170b16d1b045877f303cd52322ba1e00ba09f36443c2a63fbd7ff8feeb2c84e99fde6db08fd8e4c67ad061c482ff276", - "0x09277b3069a4b944a45df222366aae727ec64efaf0a8ecb000645d0eea3a3fa93609b925158cc04f610f8c616369094683ca7a86239f49e97852aa286d148a3913", - "0x092fb789200a7324067934da8be91c48f86c4e6f35fed6d1ce8ae4d7051f480bc0074019222c788b139b6919dfbc9d0b51f274e0ed3ea03553b8db30392ac05ce4", - "0x092f79da8f9f2c3a3a3813580ff18d4619b95f54026b2f16ccbcca684d5e25e1f52912fa319d9a7ba537a52cc6571844b4d1aa99b8a78cea6f686a6279ade5dcae", - "0x09249d249bcf92a369bd7715ec63a4b29d706a5dbb304efd678a2e5d7982e7fa9b202e3225c1031d83ab62d78516a4cbdbf2b22842c57182e7cb0dbb4303ac38c5", - "0x0904837ebb85ceccab225d4d826fe57edca4b00862199b91082f65dfffa7669b90039c710273b02e60c2e74eb8b243721e852e0e56fa51668b6362fd920f817cb7", - "0x090a36f6aabc3768a05dd8f93667a0eb2e5b63d94b5ce27132fb38d13c56d49cb4249c2013daee90184ae285226271f150f6a8f74f2c85dbd0721c5f583e620b10", - "0x091b82f139a06af573e871fdd5f5ac18f17c568ffe1c9e271505b371ad7f0603e716b187804a49d2456a0baa7c2317c14d9aa7e58ad64df38bc6c1c7b86b072333", - "0x0929668e59dfc2e2aef10194f5d287d8396e1a897d68f106bdb12b9541c0bab71d2bf910dea11e3209b3feff88d630af46006e402e935bc84c559694d88c117733", - "0x0914231c92f09f56628c10603dc2d2120d9d11b27fa23753a14171127c3a1ee3dd0d6b9cbd11d031fe6e1b650023edc58aa580fa4f4aa1b30bf82e0e4c7a308bb9", - "0x0914c1dd24c520d96aac93b7ef3062526067f1b15a080c482abf449d3c2cde781b195eb63b5e328572090319310914d81b2ca8350b6e15dc9d13e878f8c28c9d52", - "0x0927cb93e3d9c144a5a3653c5cf2ed5940d64f461dd588cd192516ae7d855e9408166e85986d4c9836cd6cd822174ba9db9c7a043d73e86b5b2cfc0a2e082894c3", - "0x090858bf8a0119626fe9339bd92116a070ba1a66423b0f7d3f4666b6851fdea01400f7f51eb22df168c41162d7f18f9d97155d87da523b05a1dde54e7a30a98c31", - "0x0902776c1f5f93a95baea2e209ddb4a5e49dd1112a7f7d755a45addffe4a233dad0d8cc62b957d9b254fdc8199c720fcf8d5c65d14899911e991b4530710aca75e", - "0x091d7fde5c78c88bbf6082a20a185cde96a203ea0d29c829c1ab9322fc3ca0ae3100ef7cba868cac216d365a0232ad6227ab1ef3290166bc6c19b719b79dbc17fc", - "0x091690160269c53c6b74337a00d02cb40a88ea5eba06e1942088b619baee83279e12d96d62dda9c4b5897d58fea40b5825d87a5526dec37361ec7c93a3256ea76d", - "0x091bccb091cde3f8ca7cfda1df379c9bfa412908c41037ae4ec0a20ce984e2c9a51d02c109d2e6e25dc60f10b1bc3b3f97ca1ce1aa025ce4f3146de3979403b99e", - "0x0927083540af95e57acba69671a4a596f721432549b8760941f4251e0dd7a013a917cee0f60d333cf88e40ae8710fb1fd6e3920346a376b3ba6686a4b2020a043e", - "0x082170b57b8f05f6990eec62e74cdb303741f6c464a85d68582c19c51e53f490000a5029a62ddc14c9c07c549db300bd308b6367454966c94b8526f4ceed5693b2", - "0x0827a0b16ef333dcfe00610d19dc468b9e856f544c9b5e9b046357e0a38aedaeb90000000000000000000000000000000000000000000000000000000000000000", - "0x06126f891e8753e67c5cbfa2a67e9d71942eab3a88cde86e97a4af94ea0dde497821fb69ccdb00e6eaeaf7fc1e73630f39f846970b72ac801e396da0033fb0c247", - "0x0420e9fb498ff9c35246d527da24aa1710d2cc9b055ecf9a95a8a2a11d3d836cdf050800000000000000000000000000000000000000000000000016ef00000000000000000000000000000000000000000000000000000000000000600058d1a5ce14104d0dedcaecaab39b6e22c2608e40af67a71908e6e97bbf4a43c59c4537140c25a9e8c4073351c26b9831c1e5af153b9be4713a4af9edfdf32b58077b735e120f14136a7980da529d9e8d3a71433fc9dc5aa8c01e3a4eb60cb3a4f9cf9ca5c8e0be205300000000000000000000000000000000000004000000000000000000000000", - "0x5448495320495320534f4d45204d4147494320425954455320464f5220534d54206d3172525867503278704449", - ], - storageProof: [ - "0x09240ea2601c34d792a0a5a8a84d8e501cfdfdf2c10ef13ea560acac58661882dd1b3644d1d4f3e32fc78498a7ebeffac8c6a494ac6f36923ef1be476444c0d564", - "0x092fa31ba6c9b8f291512a582ab446daf7aa3787e68f9628d08ec0db329027d9001af83d361b481ed4b943d988cb0191c350b8efc85cfceba74afb60783488d441", - "0x092c2ec2d967208cb5088400d826b52113d606435be011b6c9f721f293fb12242515681c9016eb1c222dcdbeeeb9fd3a504caba892f4c1832741a2b17a7305598a", - "0x090c7fe825c29bf5df80c7101ff8a372ba4f7b2ac37c16a3bbda38cc1e38e682460499b7e5d21d3784f496e747140f465eb1a39a019d2be8baf13a5e39f359a4ed", - "0x092bb11ebbc7cd1e565b86498aecab16842ab3fa852c7943cfbc49ee4bc593b2f308a78e1bc555e07d36d5c812af57c18f67199197a52ff74bc4e32ca6b7fadf32", - "0x092fd1e042080801034c6d6c79d462016c74b97dfbb1272cf606e638911a08f21c02434541eeed6d66002c69042f9354211e40518316a2d98cc0da0f19fb1ea013", - "0x09024bd491ec707bc3e8bea6b2754f37b1e85903061aefabd945537eef2f4d38b4136b925b004d29603c5e6195e073322d27f0c6ea3fa1ea5c5b248ff60dda594c", - "0x09269e1f468bd9bbde77a13562645a80a77d26d801781ca95d385bd59ee1b0890b03694bf9043190620265bf0bc3baa4d82cc82302ae0bbf33cfa48b0ec9d5ab25", - "0x0924d8bf62b2a725684847208dc021d5aee9f3c8f14c14786bc9f93232dfd3e068120bb7d022bbb159b4b84bb9e36cd2fcd89d761e265c1b88c8bdb9745a51cb22", - "0x092680f932920fd86de0b417cfdbeb2836a470213097ed5abb1a2b4deba8437f6825fd0ec614b97e6cfa4d50b08ad1e0fd8a5cd72db3a468128d1045d6a54e5e6e", - "0x0909e630914cee4db538057a0218a72288b88b2603aee0f805254b865a03de87c92ce46c1aa77ee8c42bb60c4175826f4dbb89d6282c01ff3de654c961599e66c3", - "0x091a17302d53ad1b7a4472d111fd27b35720d49ce27259b5e42f46339dddf235e82b973c29f44cf69b589f724d7d2fa54bf38b37bde3fc66c0d965a8c10df80caa", - "0x0916572156ae22ae2b0bc84ff41d16668be7163da26db2b13b86c218e0516c97a4131b584b7192464dde26060f66f678b03c8db8f64f1cd7a1f98a22a90cce5850", - "0x092c6ee2ca598c123445bbbd403ca3ab8a95ce2443f941ebdcf7bb035e2a3e38e22e8d5b222a1019b126f0ecf277c7fed881413e879cd4dc5df66634b6e9fb688d", - "0x0700000000000000000000000000000000000000000000000000000000000000002822301c27c0bd26a8f361545a09d509a2feed981accf780de30244f0300321d", - "0x05", - "0x5448495320495320534f4d45204d4147494320425954455320464f5220534d54206d3172525867503278704449", - ], - }, - { - // curl -H "content-type: application/json" -X POST --data '{"id":0,"jsonrpc":"2.0","method":"eth_getProof","params":["0x5300000000000000000000000000000000000044", ["0x0000000000000000000000000000000000000000000000000000000000000000"], "0x1111ad"]}' https://rpc.scroll.io - block: 1154766, - desc: "random empty storage in some contract", - account: "0x226D078166C78e00ce5E97d8f18CDc408512bb0F", - storage: "0x0000000000000000000000000000000000000000000000000000000000000001", - expectedRoot: "0x1e5cf13822e052084c315e944ca84f1ef375583e85e1508055123a182e415fab", - expectedValue: "0x0000000000000000000000000000000000000000000000000000000000000000", - accountProof: [ - "0x09062c633f6d7c7a157025fef8ab1c313a7caadda3a64b23664741f9de3b0478fe27571cf9b45d5f4deddf5f0b5354a613998fdcbe9249bb7cde92fd45513c5a99", - "0x0920d6877efe14060018278754e91682430401880981fec1cd1b63610bed0c1e332a63aca7a8898b01983e2c53a7257310318da444fd6c8b705e488943205301a8", - "0x090f6dadd53bbc0f5fa4fa03961aff0bf252ae335e11c1836253b6bc214d66759010b10d80991219a66f1eb7e07169b4cec4fa74b04edbdc08c3f238dfdf1d2fac", - "0x0921ea10af71b5f3587ff9d42178a151427cbcde37b8bee6575463bf6b83110cca0520d5f97b44e7015453ec16d9c28980d2cec3df5c860eb8a455f49dcfa339be", - "0x092d19cf96a7c129aac6f72f780703a9ef3233fc5124d592baee751a3550dd692a02c962b87efbba5aeea4856c3df29c1ea540e1fbc7a74529d5dc793fe8e490d8", - "0x0922e20a087e600560007189ccc1a159e4fffeb1876a6de3772b7f450793a1c6620ada74791f3ecd25a650701578ef9661c64e75d836c681503e96228974a53903", - "0x0924839671b636ebb56cb9a2860a3edf2a2875774e84dfcf8546135189f808d724260ac8be541ff088a9a1d2468c4c6e2faa793009be553a3cbca003649ee511db", - "0x090cd8140d844f62e44ffe820c1b2b0d4aa8f0518c15ff61759d93d805cb017cb628d5b46a4c4ec0a10eb00155808890925050f7af2279b512c25005d963283262", - "0x0913c0698673b0be011485eba05c61ac41bf14fc960ce5dbb6f5a021809eabbb0e18adaf85a3724e1a644268b845f5014b39e574928b9a01bfcd25d6fe1cf03e8f", - "0x0912c2e7da4b091c52e0012e5c13baf07d9d9daed10a558262d2e700a7c823300e054dce1849561bbeede4368a3be06f5a2bae06bdb1bc2bcefdba84634fd1991c", - "0x090b3e9c665497a0f9c1d3f1448c6d9144a287eb0accf86fea6f443f51986df7130392814f078a19643081787478ec3a010e2757a574877a194136c529813cf7ae", - "0x09249a0e273abe79a0b99a55516e19213191b7f77ef34f8815edc4e1ede8711f7920615adbac1983d844c8a6ed50922562432c13d030069d8b3e92611b4fe39531", - "0x09199575893e55d92fafb3b067130b9b6b5a46e7f6fb2d0af412d12591632dfe961adffb9dd1e7490095aac94bc1fcaeb591f4ba907fe2b882c9f6d8f7ab3a1809", - "0x09259308e9398f029ebbe31a4b353f474622b4c96995b7365c3b13c392fcc3e7001be60286a497a3886aa9cff3ad6a5dc71504078eb7a44c43530b7b33eef4743f", - "0x090709a21aaf18a1eaea3b925ab36f47a82095aa3e9ddbc4f01463005c4b64f6af0554d854637fcbfd9b1a4c2474de343950569e4f855d66f2ee14fcfb19ee17f5", - "0x092d7319be75a70b8ea5f0acc6ab4a96971ec546f72b18bdc3e905ad6ea8a288f70626499aee389335559b1dd3cc8b6711f9fde0c517236190cba24fa87993877a", - "0x09081b165a51e3081fc2e3e27d6fdb81134b65284851798de62899db3065a8c1fc040c8dce92508a510c2c34fc2949910dd41247c9f247cd216c03d9bb9d2881b4", - "0x092a27c5be32e1ab6e85d1ac094bc1509d92285f45c63fca6dba9b14d485a94af326d44c1ff85666a4790182ddd7e51cbbe06af81d62082e6d79faec29a4501369", - "0x091a46df6ffd6b439ffcd1b57e9548f5c4db26ade9e984efc8a91a01ab22134d3c1617b504ac2015793c5dac16d379b5ca6cb70c14243491bb68535ee686a3a553", - "0x08180e90f9f9a4fd8065a5849539793bd9e9340b69770eff1716a733241e454c341641f913f1c32e2c652b876f902e5c2c8d51c482411ec44dae969bdc50264c42", - "0x06273c162ecb059cd86ec0a01033dd61c39f59ee0a13eb41a28c0b2d49a45f6f94081be344adea9f54587a832b9efef6fc9ec010d86ec5fb2b53b5ff8dbabc4924", - "0x040b792f5b15327fc37390341af919c991641846d380397e4c73cbb1298921a546050800000000000000000000000000000000000000000000000000fb0000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000be74cc05824041ef286fd08582cdfacec7784a35af72f937acf64ade5073da10889249d61c3649abf8749bf686a73f708d67726fada3e071b03d4541da9156b20226d078166c78e00ce5e97d8f18cdc408512bb0f000000000000000000000000", - "0x5448495320495320534f4d45204d4147494320425954455320464f5220534d54206d3172525867503278704449", - ], - storageProof: [ - "0x05", - "0x5448495320495320534f4d45204d4147494320425954455320464f5220534d54206d3172525867503278704449", - ], - }, - { - // curl -H "content-type: application/json" -X POST --data '{"id":0,"jsonrpc":"2.0","method":"eth_getProof","params":["0xC73BfBD94fb1FD860997D4E76D116BDE0333BeEf", ["0x0000000000000000000000000000000000000000000000000000000000000000"], "0x2a7531"]}' https://sepolia-rpc.scroll.io - block: 2782513, - desc: "contract with only one storage entry", - account: "0xC73BfBD94fb1FD860997D4E76D116BDE0333BeEf", - storage: "0x0000000000000000000000000000000000000000000000000000000000000000", - expectedRoot: "0x13c6008daf17807163a056504e562d4adf13870306814b1a3877cda5297d5ae9", - expectedValue: "0x000000000000000000000000000000000000000000000000000000000000000c", - accountProof: [ - "0x09272d92cb48d19e41ef64be1da3e10026eb87d227132becb4fba0dd1451783de425f66c55ff0bec0b012e11d64aaaa6c322566d58cf45525cb05302132518f23d", - "0x0920908000907fe2260e41f8682510eee0572937459163ea1940c2eae8b2d5862e015e7c84f56f5948bfc9c242506d14f5c3c1b97bba1b262b40b108f5d7e69287", - "0x09078402c38a02e2b3dda819b761ca6448029f3dd42ae7876ac0dba0d762e3ddb818d80485f0a15f54f110aad9a98b00bdf9ccb56bbcb069552c7f6c10be1b9c15", - "0x09123243fe438606648fe3bcef5eb0165920315fb2b9316ce3ec0daac885577f190b84d9901fc150f52ed177f23ec31de4254b293c6eac2088009f3e13e3a08b78", - "0x09053c59663d3eafad212f58c4834090db4bfd0ba2b13d3108e0acade089a5da9229a75e0b30abc41d4fb252faf9f3aa8ef750b780247d83186cdc333635c25038", - "0x09163255ef0b1fdec7ec97c4e002cdeb6c963ca26d9d03ebdf78eb44dfdb57e4bd1fa9f68cc583c1e7019cc62133ede53e5636330de9a2c09e75f03760026e3729", - "0x09296d3cb1c4fd539ed015f2853649d20f5db111ce13c30b7e6efa4c9468741d1e0eea62adcf73aa5bdb4868cd776df429d26787f424beeda38f4ad19aa83e43e4", - "0x0908288df27fa423895de38ec5a52e809d99b683c5b32463501f5dad642b71387f0a3d37ae9df53b5cfdda0ac67765662e8a71a19b05d38f4a464596e129a35570", - "0x091a774fef4e8294fcca57d213846e51bfcf71249680e937e14248e532b47abd762ad72878f07f4abbba8bd13da9b75f681f35a748bb8fc078913e16a91bce783e", - "0x092799a146ba6b2bf4b6a24aef88c9590d9643d53f429438e348518a17af3d6e8d10e3b39898c3795c9386518438465581ca232445532fb549a8bddbdd6f4e0eed", - "0x0914c654d53c9f8656b784709decbd12ba786800a77c929f3b4255d59138b42dff282005f8997b73d64eeb112775885c4c08d2ee4e356cc2db58154dde48a0a1e4", - "0x091c71601a71f28ed0f6aeb59cf8a7bf29ce7dd3203352099920086e02007496260b811e85a0cd244d56f199b357d5c3a54f897fea21637698943679d07b33db8d", - "0x092a66de31cef7b4b195772a2b96edba3ca7d97a5bbe974d071c37f0d0ca0545be0be9ca0dd4c9d62ec3ba0a404713fefe6b62391ba3f6d283a47e83fdb18c3a4e", - "0x09093842042d196ae30784d31ed1526dd5d60cabe292eb5333e42936a2edbbaf1d237998efa424724063547c02cfa835ebfc24131315c34229b363f46fefda33ee", - "0x0911637da97122f89f421a4564d5328893ff4b5de123aecad06e07ea45d9622b87096a296e974b5eda0f2d35cb5531c4a55f3c1e181a8bb4a0b33399e7c93853d4", - "0x0921feeaba62a4ad78791d662737a3fa52a527dcd892f5d3af2cfbed4b6591d50f2fae639afb8ab4640a2d166616a4803442b26b9a8f5148a1c88adda1e2d911da", - "0x090ddbe424e9368f262ef80a144383fc4f518b27200f7a61a996a075b3b84ab5041c755907f230eea27d060fa827a5743c7046cd0dc7487047bc3a7d222d65d2d7", - "0x092d6e65349fd6751353b4b72fdd03d3ee4b1721efb434db76679c1c348b60fdc0177c7d961201138c98f85daf8a49b7a083a41e77dcd819d359b3db55c4a941a9", - "0x090b0d48518cb602b73a86bd7b2294d401e6ad4851e3c7549fc7d23eea017eadd72e3245236b50c7f256de16bae063df6221b8331443c9d3a79e867fd77dd85cee", - "0x07062bf32f202ec2afa65dfa84fffc76b5c05309768078544920f9b56d021606ce0b7371683425d088ad37f063ee847a9accac416314f1308cce69a8beeb2d2ab7", - "0x090ffc989b8556e69159e246cb74cf7a2e30df63e9b7dba76ede73996ab60d9799063ca19e1d436cea189d17c5d93b8da0fa11b3ee88de1030602d1e8087cbb3da", - "0x070000000000000000000000000000000000000000000000000000000000000000084f906a52b7da7bf35f3cc2431b40cfb90884c2ec0b579c9c096aea959509f7", - "0x0620b6c0072d699768c0b52df46b97dae979a14788ed54dad1d7ce67db6e036a07291784b726760c2d728e4084d95df6d1534e27284c8ae2eeb56a80210f37da2b", - "0x041245637ec55bae3c02f990e3cc3bf59cc05f515731cfa59ee55f8164953f8965050800000000000000000000000000000000000000000000000000ac000000000000000100000000000000000000000000000000000000000000000000000000000000000f68a43f5508e9c1f845406d9a507b612f97530746e59b93c8705f1a7cb0b93451e52f95aea13b1bc1f37dfbf797bfe7cea82a8c82da148f507e1ef2036fea8314b9fb07c4311e129d72b858c37b6bbe09c616f78416cb53d6e83360aff7b99c20c73bfbd94fb1fd860997d4e76d116bde0333beef000000000000000000000000", - "0x5448495320495320534f4d45204d4147494320425954455320464f5220534d54206d3172525867503278704449", - ], - storageProof: [ - "0x041d3c5f8c36e5da873d45bfa1d2399a572ac77493ec089cbf88a37b9e9442842201010000000000000000000000000000000000000000000000000000000000000000000c200000000000000000000000000000000000000000000000000000000000000000", - "0x5448495320495320534f4d45204d4147494320425954455320464f5220534d54206d3172525867503278704449", - ], - }, -]; - -describe("ZkTrieVerifier", async () => { - let verifier: MockZkTrieVerifier; - - beforeEach(async () => { - const [deployer] = await ethers.getSigners(); - - const PoseidonHashWithDomainFactory = new ethers.ContractFactory(generateABI(2), createCode(2), deployer); - const poseidon = await PoseidonHashWithDomainFactory.deploy(); - - const MockZkTrieVerifier = await ethers.getContractFactory("MockZkTrieVerifier", deployer); - verifier = await MockZkTrieVerifier.deploy(poseidon.getAddress()); - }); - - const shouldRevert = async (test: ITestConfig, reason: string, extra?: string) => { - const proof = concat([ - `0x${test.accountProof.length.toString(16).padStart(2, "0")}`, - ...test.accountProof, - `0x${test.storageProof.length.toString(16).padStart(2, "0")}`, - ...test.storageProof, - extra || "0x", - ]); - await expect(verifier.verifyZkTrieProof(test.account, test.storage, proof)).to.revertedWith(reason); - }; - - for (const test of testcases) { - it(`should succeed for block[${test.block}] desc[${test.desc}] account[${test.account}] storage[${test.storage}]`, async () => { - const proof = concat([ - `0x${test.accountProof.length.toString(16).padStart(2, "0")}`, - ...test.accountProof, - `0x${test.storageProof.length.toString(16).padStart(2, "0")}`, - ...test.storageProof, - ]); - const [root, value, gasUsed] = await verifier.verifyZkTrieProof(test.account, test.storage, proof); - expect(test.expectedRoot).to.eq(root); - expect(test.expectedValue).to.eq(value); - console.log("gas usage:", gasUsed.toString()); - }); - } - - it("should revert, when InvalidNodeDepth", async () => { - const test = testcases[0]; - { - const proof = concat([ - `0xfa`, - ...test.accountProof, - `0x${test.storageProof.length.toString(16).padStart(2, "0")}`, - ...test.storageProof, - ]); - await expect(verifier.verifyZkTrieProof(test.account, test.storage, proof)).to.revertedWith("InvalidNodeDepth"); - } - { - const proof = concat([ - `0x${test.accountProof.length.toString(16).padStart(2, "0")}`, - ...test.accountProof, - `0xfa`, - ...test.storageProof, - ]); - await expect(verifier.verifyZkTrieProof(test.account, test.storage, proof)).to.revertedWith("InvalidNodeDepth"); - } - }); - - it("should revert, when InvalidBranchNodeType", async () => { - const test = testcases[0]; - for (const i of [0, 1, test.accountProof.length - 3]) { - const correct = test.accountProof[i]; - const prefix = correct.slice(0, 4); - for (let b = 0; b < 16; ++b) { - if (b >= 6 && b < 10) continue; - test.accountProof[i] = test.accountProof[i].replace(prefix, "0x" + chars[b >> 4] + chars[b % 16]); - await shouldRevert(test, "InvalidBranchNodeType"); - test.accountProof[i] = correct; - } - } - - for (const i of [0, 1, test.storageProof.length - 3]) { - const correct = test.storageProof[i]; - const prefix = correct.slice(0, 4); - for (let b = 0; b < 16; ++b) { - if (b >= 6 && b < 10) continue; - test.storageProof[i] = test.storageProof[i].replace(prefix, "0x" + chars[b >> 4] + chars[b % 16]); - await shouldRevert(test, "InvalidBranchNodeType"); - test.storageProof[i] = correct; - } - } - }); - - it("should revert, when BranchHashMismatch", async () => { - const test = testcases[0]; - for (const i of [1, 2, test.accountProof.length - 3]) { - const correct = test.accountProof[i]; - for (const p of [40, 98]) { - const v = correct[p]; - for (let b = 0; b < 3; ++b) { - if (v === chars[b]) continue; - test.accountProof[i] = correct.slice(0, p) + chars[b] + correct.slice(p + 1); - await shouldRevert(test, "BranchHashMismatch"); - test.accountProof[i] = correct; - } - } - } - - for (const i of [1, 2, test.storageProof.length - 3]) { - const correct = test.storageProof[i]; - for (const p of [40, 98]) { - const v = correct[p]; - for (let b = 0; b < 3; ++b) { - if (v === chars[b]) continue; - test.storageProof[i] = correct.slice(0, p) + chars[b] + correct.slice(p + 1); - await shouldRevert(test, "BranchHashMismatch"); - test.storageProof[i] = correct; - } - } - } - }); - - it("should revert, when InvalidAccountLeafNodeType", async () => { - const test = testcases[0]; - const index = test.accountProof.length - 2; - const correct = test.accountProof[index]; - const prefix = correct.slice(0, 4); - for (let b = 0; b < 20; ++b) { - if (b === 4 || b === 5) continue; - test.accountProof[index] = test.accountProof[index].replace(prefix, "0x" + chars[b >> 4] + chars[b % 16]); - await shouldRevert(test, "InvalidAccountLeafNodeType"); - test.accountProof[index] = correct; - } - }); - - it("should revert, when AccountKeyMismatch", async () => { - const test = testcases[0]; - const index = test.accountProof.length - 2; - const correct = test.accountProof[index]; - for (const p of [4, 10]) { - const v = correct[p]; - for (let b = 0; b < 3; ++b) { - if (v === chars[b]) continue; - test.accountProof[index] = correct.slice(0, p) + chars[b] + correct.slice(p + 1); - await shouldRevert(test, "AccountKeyMismatch"); - test.accountProof[index] = correct; - } - } - }); - - it("should revert, when InvalidAccountCompressedFlag", async () => { - const test = testcases[0]; - const index = test.accountProof.length - 2; - const correct = test.accountProof[index]; - for (const replaced of ["01080000", "05010000"]) { - test.accountProof[index] = test.accountProof[index].replace("05080000", replaced); - await shouldRevert(test, "InvalidAccountCompressedFlag"); - test.accountProof[index] = correct; - } - }); - - it("should revert, when InvalidAccountLeafNodeHash", async () => { - const test = testcases[0]; - const index = test.accountProof.length - 2; - const correct = test.accountProof[index]; - for (const p of [80, 112, 144, 176, 208]) { - const v = correct[p]; - for (let b = 0; b < 3; ++b) { - if (v === chars[b]) continue; - test.accountProof[index] = correct.slice(0, p) + chars[b] + correct.slice(p + 1); - await shouldRevert(test, "InvalidAccountLeafNodeHash"); - test.accountProof[index] = correct; - } - } - }); - - it("should revert, when InvalidAccountKeyPreimageLength", async () => { - const test = testcases[0]; - const index = test.accountProof.length - 2; - const correct = test.accountProof[index]; - for (const p of [396, 397]) { - const v = correct[p]; - for (let b = 0; b < 3; ++b) { - if (v === chars[b]) continue; - test.accountProof[index] = correct.slice(0, p) + chars[b] + correct.slice(p + 1); - await shouldRevert(test, "InvalidAccountKeyPreimageLength"); - test.accountProof[index] = correct; - } - } - }); - - it("should revert, when InvalidAccountKeyPreimage", async () => { - const test = testcases[0]; - const index = test.accountProof.length - 2; - const correct = test.accountProof[index].slice(); - for (const p of [398, 438]) { - const v = correct[p]; - for (let b = 0; b < 3; ++b) { - if (v === chars[b]) continue; - test.accountProof[index] = correct.slice(0, p) + chars[b] + correct.slice(p + 1); - await shouldRevert(test, "InvalidAccountKeyPreimage"); - test.accountProof[index] = correct; - } - } - }); - - it("should revert, when InvalidProofMagicBytes", async () => { - const test = testcases[0]; - let index = test.accountProof.length - 1; - let correct = test.accountProof[index].slice(); - for (const p of [2, 32, 91]) { - const v = correct[p]; - for (let b = 0; b < 3; ++b) { - if (v === chars[b]) continue; - test.accountProof[index] = correct.slice(0, p) + chars[b] + correct.slice(p + 1); - await shouldRevert(test, "InvalidProofMagicBytes"); - test.accountProof[index] = correct; - } - } - - index = test.storageProof.length - 1; - correct = test.storageProof[index].slice(); - for (const p of [2, 32, 91]) { - const v = correct[p]; - for (let b = 0; b < 3; ++b) { - if (v === chars[b]) continue; - test.storageProof[index] = correct.slice(0, p) + chars[b] + correct.slice(p + 1); - await shouldRevert(test, "InvalidProofMagicBytes"); - test.storageProof[index] = correct; - } - } - }); - - it("should revert, when InvalidAccountLeafNodeHash", async () => { - const test = testcases[0]; - const correct = test.accountProof[test.accountProof.length - 2]; - // change nonce - test.accountProof[test.accountProof.length - 2] = correct.replace( - "0x0420e9fb498ff9c35246d527da24aa1710d2cc9b055ecf9a95a8a2a11d3d836cdf050800000", - "0x0420e9fb498ff9c35246d527da24aa1710d2cc9b055ecf9a95a8a2a11d3d836cdf050800001" - ); - await shouldRevert(test, "InvalidAccountLeafNodeHash"); - test.accountProof[test.accountProof.length - 2] = correct; - }); - - it("should revert, when InvalidStorageLeafNodeType", async () => { - const test = testcases[0]; - const index = test.storageProof.length - 2; - const correct = test.storageProof[index]; - const prefix = correct.slice(0, 4); - for (let b = 0; b < 20; ++b) { - if (b === 4 || b === 5) continue; - test.storageProof[index] = test.storageProof[index].replace(prefix, "0x" + chars[b >> 4] + chars[b % 16]); - await shouldRevert(test, "InvalidStorageLeafNodeType"); - test.storageProof[index] = correct; - } - }); - - it("should revert, when StorageKeyMismatch", async () => { - const test = testcases[0]; - const index = test.storageProof.length - 2; - const correct = test.storageProof[index]; - for (const p of [4, 10]) { - const v = correct[p]; - for (let b = 0; b < 3; ++b) { - if (v === chars[b]) continue; - test.storageProof[index] = correct.slice(0, p) + chars[b] + correct.slice(p + 1); - await shouldRevert(test, "StorageKeyMismatch"); - test.storageProof[index] = correct; - } - } - }); - - it("should revert, when InvalidStorageCompressedFlag", async () => { - const test = testcases[0]; - const index = test.storageProof.length - 2; - const correct = test.storageProof[index]; - for (const replaced of ["00010000", "01000000"]) { - test.storageProof[index] = test.storageProof[index].replace("01010000", replaced); - await shouldRevert(test, "InvalidStorageCompressedFlag"); - test.storageProof[index] = correct; - } - }); - - it("should revert, when InvalidStorageLeafNodeHash", async () => { - const test = testcases[0]; - const index = test.storageProof.length - 2; - const correct = test.storageProof[index]; - for (const p of [100, 132]) { - const v = correct[p]; - for (let b = 0; b < 3; ++b) { - if (v === chars[b]) continue; - test.storageProof[index] = correct.slice(0, p) + chars[b] + correct.slice(p + 1); - await shouldRevert(test, "InvalidStorageLeafNodeHash"); - test.storageProof[index] = correct; - } - } - }); - - it("should revert, when InvalidStorageKeyPreimageLength", async () => { - const test = testcases[0]; - const index = test.storageProof.length - 2; - const correct = test.storageProof[index]; - for (const p of [140, 141]) { - const v = correct[p]; - for (let b = 0; b < 3; ++b) { - if (v === chars[b]) continue; - test.storageProof[index] = correct.slice(0, p) + chars[b] + correct.slice(p + 1); - await shouldRevert(test, "InvalidStorageKeyPreimageLength"); - test.storageProof[index] = correct; - } - } - }); - - it("should revert, when InvalidStorageKeyPreimage", async () => { - const test = testcases[0]; - const index = test.storageProof.length - 2; - const correct = test.storageProof[index]; - for (const p of [142, 205]) { - const v = correct[p]; - for (let b = 0; b < 3; ++b) { - if (v === chars[b]) continue; - test.storageProof[index] = correct.slice(0, p) + chars[b] + correct.slice(p + 1); - await shouldRevert(test, "InvalidStorageKeyPreimage"); - test.storageProof[index] = correct; - } - } - }); - - it("should revert, when InvalidStorageEmptyLeafNodeHash", async () => { - const test = testcases[0]; - const index = test.storageProof.length - 2; - const correct = test.storageProof[index]; - test.storageProof[index] = "0x05"; - await shouldRevert(test, "InvalidStorageEmptyLeafNodeHash"); - test.storageProof[index] = correct; - }); - - it("should revert, when ProofLengthMismatch", async () => { - const test = testcases[0]; - await shouldRevert(test, "ProofLengthMismatch", "0x0000"); - }); -}); diff --git a/contracts/integration-test/testdata/plonk_verifier_0.9.8_pi.data b/contracts/integration-test/testdata/plonk_verifier_0.9.8_pi.data deleted file mode 100644 index c941d525b..000000000 Binary files a/contracts/integration-test/testdata/plonk_verifier_0.9.8_pi.data and /dev/null differ diff --git a/contracts/integration-test/testdata/plonk_verifier_0.9.8_proof.data b/contracts/integration-test/testdata/plonk_verifier_0.9.8_proof.data deleted file mode 100644 index fba7545ce..000000000 Binary files a/contracts/integration-test/testdata/plonk_verifier_0.9.8_proof.data and /dev/null differ diff --git a/contracts/integration-test/testdata/poseidon_hash_with_domain.data b/contracts/integration-test/testdata/poseidon_hash_with_domain.data deleted file mode 100644 index 0b877dc75..000000000 --- a/contracts/integration-test/testdata/poseidon_hash_with_domain.data +++ /dev/null @@ -1,1154 +0,0 @@ -6 0 0 17848312925884193353134534408113064827548730776291701343555436351962284922129 -6 63 63 17286103331600103585767161555381256046402899599234314287129103751067463292629 -6 0 63 18983952111277879196374592679765388250428396759848819880727626654011636179230 -6 63 0 14690039247305687499999325872545322096288151836581616112441065582983484442560 -6 18 18 14886119132848955634420839101830750513299311233260887510325258966259308028620 -6 0 18 633665573845290208906073174675508179720579418684041597379662431797826067512 -6 18 0 471071594757765224242595750640672720535774219791325564795146688484582784888 -6 62 62 16806009654065841196345990060655780633859196760058147141225814154039572464303 -6 0 62 4391466341587429900903455872273933210694126159055017138392348141307436923587 -6 62 0 6078856426770083769292700047033541481061793813372066507856605863200208328236 -6 30 30 9044124059490367585703569594649366178510106058117862341764374983418084390063 -6 0 30 4462168647812770697181765485265960835478405605595615752223024940695867334895 -6 30 0 19347919945780736011987607672482106281088545639175512447848257807389058709752 -6 165 165 2353709429392571619789851970113232216785565922613667436338216914183261426248 -6 0 165 10430659806198730770124331858804976104655381755284341008047764582794995977220 -6 165 0 5201660608295546072310996128934058410243861654094413762052330545941800928319 -6 75 75 14823471284772704808547818999984935326707738736421538148742541786058091433660 -6 0 75 20023708521860181839237760496916241430173504416893012613259240367902914757179 -6 75 0 11999318616263540697506732742545287338966559474574408243051610325357831718071 -6 58041 58041 19714449762954386365664209010383555288800681839836405724661178897215525481560 -6 0 58041 10818867850526562502260445829725038799340556161157968091417605032018416709127 -6 58041 0 9863308625509440829917020406107323053195025154288106028343907076318644801222 -6 26923 26923 11140311622090786565090101875648179852726239620951743057347509005833458831497 -6 0 26923 1954436883321412015559726567248568870211061748610776084655575229769314803278 -6 26923 0 17644576382905757706381475968429667455517328858834692504733561110486466034353 -6 62860 62860 5653882128700799903844820274735724821451278650821031412671186567950152484347 -6 0 62860 5534896356842931986772367055997240395478722006769590912512844905175188902060 -6 62860 0 8341554337108489113927851756891922379074028905745730039811118902303990807322 -6 979 979 9438966210233765593431887845984285952009618655830908901053524532317100714716 -6 0 979 6459739653028811813603234300688454949824198507254744079124693076281172414030 -6 979 0 5749508988681583018286930521649834313211313144500841811978281446154161009817 -6 12294 12294 18695133923650903247804841329202112693469694368136469111882387035394189486070 -6 0 12294 17356563297431265952616941570074969468696006517363138623108724289371940367694 -6 12294 0 1012923528057293631915586145735213898988176837452790981077137877572418834244 -6 32058 32058 743919728470565731670512783936916116849558191262287123047290739951074561004 -6 0 32058 12328941778137467198731822260785414139840964131387722833338461436585808509602 -6 32058 0 19325400099224040956353096488879258154566471117265732457309536370903946925868 -6 16263244 16263244 19604647010714207311562046788116190601442650280376907446713974410833259797953 -6 0 16263244 17152686418799728222438076178741110694970073617256358770586795488611109864347 -6 16263244 0 12666062152797307293513947005572816239112884394046002226652734494823655128944 -6 1533676 1533676 14695557825817115639836562450046955915480706939563501748953293183990223563729 -6 0 1533676 17131394996727311251016607252051690958383377733965862215302845221190751102274 -6 1533676 0 19442225058447286442100840484432319696649207590456832229076655525374125932406 -6 13603290 13603290 8963229530401581560774491161052876469968609415267820652513104184835679606249 -6 0 13603290 12993002539816752808822053526323848430333912270052879051588110131356966928773 -6 13603290 0 14182498815310609456785108724278381533546829077591035251393886504507517670203 -6 15651682 15651682 10827892793714260089176119042898403370375726351485742557869368916199765352882 -6 0 15651682 2616995267036979829484515988139499806014561030728837440139500927061898377481 -6 15651682 0 13107449477585397690880193735094680200978749961522633375958756799978866337562 -6 12042036 12042036 5271165068041324939203903863755895219069209918428159609196608007837493444024 -6 0 12042036 3321241574170647310544207811615059464212729421645021050814259102467220492235 -6 12042036 0 14864984164975804726127857985440047655856655203429137952921809491917739038306 -6 7199984 7199984 11469062530196007227217743258266874463727135609250478528991462795593825376263 -6 0 7199984 7430728014876618277049253792035702159745511271303820461515412868872752760412 -6 7199984 0 4819206998370418951204850358508249809271764701011673307972130239463558328602 -6 1626779438 1626779438 10507059625349664837267641390351789270471233831266052636201134673097094013468 -6 0 1626779438 21015108155359204611797211515203713319540485490969057722152475275324980911993 -6 1626779438 0 3675157416428779858799332980925783405284375752959629941267405796018068336922 -6 213030799 213030799 18832049227072506371979591060372650567014579397443848880218326316485647909543 -6 0 213030799 14314526225376326205709111423087765549150584351319138971347700248760542940236 -6 213030799 0 18154700578494140223474301604481626165064631021258520118047683443006018929571 -6 1005434716 1005434716 17358032945976665191573703790310667425127861829599917734214951036170747278681 -6 0 1005434716 21415661414376134702616563193569142156854758845826688570285156868291611094648 -6 1005434716 0 14797973277447517041457674449978547833789544517959773751623347186050903833700 -6 3206263896 3206263896 14895088701380951838674358292987735068675866639641499242222050363769020765102 -6 0 3206263896 15230145317270361597465767371459291014209248511383006049828073147823211577315 -6 3206263896 0 452401107047184161065124761341474848887450524489944374520657275679356922427 -6 1474091809 1474091809 9479429094055133397236829132964077542323625269292435587710509023378139458858 -6 0 1474091809 1029870821267115159633187177076336917590655229396554997400773858518706228932 -6 1474091809 0 2432028741784319790902454654914433583868189624303316899618182541412118339261 -6 2169570907 2169570907 12634898222083291539722578207805899282724122909290634563202517695290494777228 -6 0 2169570907 10446102699189687617933487859919277741443369418799611429862617783606248057272 -6 2169570907 0 18737867352695745488821130290611653065125378821443945316541842701784439199206 -6 944101405379 944101405379 21103433620075409808981113071509366893859268080181970160784635558365825194015 -6 0 944101405379 133507314959349266946909988889922069910592907269552586355692559090667348651 -6 944101405379 0 18959420794924449338862293427049024373347621315835549714634883599377933828806 -6 747045310764 747045310764 14530372433150295756049448859854853303831436983389107938192892018662734390339 -6 0 747045310764 19468961629493903467930557948671405606463066793807035094580228149763014566863 -6 747045310764 0 20828502391809205781663793507810808323380040313962551094744304501923366457210 -6 725071030512 725071030512 16968981025449199653173529380427350260644519658710807356688979233635427740693 -6 0 725071030512 461205499992181331960264175369827869852687961649219600052426130016193511434 -6 725071030512 0 19453917870585726096451083969417020955781311140951618879846794976238885804340 -6 698136735631 698136735631 11504290516817091529651336630036920565585250002598717304782746983429260200102 -6 0 698136735631 16018888192977848929805989951094029614833345030325361446385813440567672399537 -6 698136735631 0 20356572555347646960292472006654385027216676430296941472889233254432838400809 -6 709973890179 709973890179 7490328707491697382374882328722657820911117349665736726397528249159054598518 -6 0 709973890179 8214332415595477078804793752923893703515662874682712204969938890701223630416 -6 709973890179 0 15784734870820766516964525370467923005760853323110371871421672936919453326188 -6 1036010818815 1036010818815 18701021748425803713142053489405600346789353356103495141418065652426574895157 -6 0 1036010818815 11583264366005621453702601135451209506407158607916763584720995936841313701651 -6 1036010818815 0 18795190276699302070970186020305018669358923601442845978683748150232084411409 -6 120105725613308 120105725613308 10166769626686893496033288948115248302715608910913212944521075839451934485070 -6 0 120105725613308 14571141778864450823921619766699183642567429056772715616890518745791282540184 -6 120105725613308 0 1062169461391890740127298678992385088222021269524067726414630196362948061615 -6 116761439789140 116761439789140 18443016739097156765624597580555648280861707463895479780353847861697636325010 -6 0 116761439789140 7781211005902364579597893079097386111840264584370478441159152968707991269298 -6 116761439789140 0 14881797176956029712709584034305936668417583912907914123879380870626796839543 -6 149258471847412 149258471847412 190750393245518229102258555838500036433390250544199422609072908719483576960 -6 0 149258471847412 18385492741995731773576175928134731910487751110251269388669405402845481097917 -6 149258471847412 0 3514633715133393362515859961584429207324291253577918534502975942508441014851 -6 24701993873721 24701993873721 10561876181774014707050070979654865482441324732110632955563060363996617822357 -6 0 24701993873721 10263023223079112751266196464468556310039255088846503440828445458538119761452 -6 24701993873721 0 18786026124096704837191735744025393996552454876797706025116247962232727610071 -6 18226713176339 18226713176339 8811530097134742864308992391254914466712335049632101134273501767738096333268 -6 0 18226713176339 19823607782747479795533790660386205952482732498878660717894452796158981127830 -6 18226713176339 0 5340154969038632442304809836425536419016363185206999912864250132076535597740 -6 72372815122436 72372815122436 2432393068514638369013939158305856958860900007160818487722888938659686955413 -6 0 72372815122436 3057958009096454829805165653602459080463687973716758317591709892534275793706 -6 72372815122436 0 6808232954150374450652786713121540190432754593961240003469190235165491433417 -6 2728577820855916 2728577820855916 2540100706842764390397408309819766063576156342473330338923620482306990523175 -6 0 2728577820855916 19359498516836157447044740373883539044258839980508025800173492429350041406876 -6 2728577820855916 0 18255055010599004062679789273182791622882006038598258455680921814976645392342 -6 51438208550261591 51438208550261591 16321541529191217715961932480181570511714009124027362998026782133825208435443 -6 0 51438208550261591 14994636213705328731286590330002212534308713971470739496386357628373283086421 -6 51438208550261591 0 9698679561901545977657540904127930213643203564239662826759742145181095441192 -6 53924302390760309 53924302390760309 4293300195941306062918138625290614556663176949852147440549081771010120920974 -6 0 53924302390760309 16344471687088988664870656859007655575529020231097486987312774544291916125042 -6 53924302390760309 0 18988874393030048827922223257142140465604358395562738032782944945515630760739 -6 25982883163711118 25982883163711118 1335267917111290902788891656479763459156918626374260312073486288003805359241 -6 0 25982883163711118 4138045479178329531664337265926539345131810312657963991478520261124756561161 -6 25982883163711118 0 15487948843917685247431000339499382657043371466026546007019779287874902475320 -6 56660105319121048 56660105319121048 16828982377767494469838529561686488597707937729652751945472523530309667863194 -6 0 56660105319121048 627975076502141521444605341126355022914381085937513225876740778886786965487 -6 56660105319121048 0 16627267226662878084624942271594688186776322707889631088859004589751184562822 -6 13318136857750949 13318136857750949 1165586750880809369649988324878915054167499191385629651960657205855215497675 -6 0 13318136857750949 11448527802547576196667773116462929207112178613314856120683883315434262656263 -6 13318136857750949 0 21773607555700884363254261380624980766043984085009738684511406121868125837519 -6 13793991437684030813 13793991437684030813 7814683583371404356799298413296775354678802364137390222682619801317063026017 -6 0 13793991437684030813 7424757061022878724703755224520024485130470801165811946798553645927064611674 -6 13793991437684030813 0 13795019197785702560273341388172585557070677589831984714988691523221364806352 -6 8700404954773393146 8700404954773393146 16641289790881958730304856564641839272152353879351181295179628829909187028888 -6 0 8700404954773393146 19116980447094259401837489495312854811987953566262814084099514792561685103820 -6 8700404954773393146 0 7432353616753146005404252354484416272375015210613963005870980302705871982572 -6 10217420485608028411 10217420485608028411 14818223295242836183488114335358331756042101362443357217731168274210838008774 -6 0 10217420485608028411 13279926377036199906352445938019659553735622521880559157600945176852178742677 -6 10217420485608028411 0 7365051602122909324178813634654780198048306931845855552703262788050569120711 -6 14868200320233540080 14868200320233540080 1558395219319982583889288212694072800713052772753871767885618911492378355724 -6 0 14868200320233540080 16459574234554943845711856162070433177540735639507590666234230887528329577688 -6 14868200320233540080 0 18631019581847409420016752295933458486740113757144805269384798907531065043207 -6 12558270869497833710 12558270869497833710 8812656146809054157974234695692662495934392233204998287324351633371854855984 -6 0 12558270869497833710 15280709592177173110136474593145112569105333478610149310824346392779993606602 -6 12558270869497833710 0 3639202286127687420682466660050893030870295572869556547235633815534423357289 -6 5650410343137301043 5650410343137301043 17444368265722537321749620818521987669726457620499608115351416605509788780869 -6 0 5650410343137301043 19098834895461296521837464421357826830373913116430966734845926096548183054088 -6 5650410343137301043 0 8347422515549547149632966547552687727044931315075811548280810520758337857630 -6 3634718677057769607510 3634718677057769607510 8171082585651829676705392699151969452348436133658070514597641981076253912538 -6 0 3634718677057769607510 17405352003848950408267622855441660631571613996071871007948712228910036476823 -6 3634718677057769607510 0 6472920187590443043004828878417796775651670056764829005261417839111785931738 -6 906743155655826118526 906743155655826118526 7440121590270347396450433958074522619879273715049933396206350573265288759920 -6 0 906743155655826118526 14260850328572595899031787571466095480270639225949535644684583863050439224113 -6 906743155655826118526 0 13868431084701373944408801840257294127472552793683599348391208404799267455691 -6 1016942069775258233889 1016942069775258233889 1055145124812380548270298563096550394240182686413998917609804208952339783871 -6 0 1016942069775258233889 279097754679987472518876892894055105349421024476396409241301476555214427952 -6 1016942069775258233889 0 12056439181183685697833268530091402157751141589104723906571365184558848327731 -6 1772417340638181082547 1772417340638181082547 16825888813473181188248978510736680253674794647981256997519317904397185916395 -6 0 1772417340638181082547 5640339435067775905358613315576544981836913708365242200360360196539646248533 -6 1772417340638181082547 0 3575183844491712700230621296004863726655304830103401875160918503399226126207 -6 725354530695940600706 725354530695940600706 20688981141983320586154983966017123707722177043064856881362507289438221166649 -6 0 725354530695940600706 11556832016679870804566551730709957970609346774722487636048290028268826126986 -6 725354530695940600706 0 20676807131282133993752716839416681263083689683183820471817187360125092391671 -6 4310398967825989999873 4310398967825989999873 4494129940287435052177894723787667572683058871549294691203415149789176137093 -6 0 4310398967825989999873 2811187591029694210063495179104527384165040148610454481369163789862971340193 -6 4310398967825989999873 0 10600973294324310340721605883939396736157037716184705057046549217949798517737 -6 687391237980223946025423 687391237980223946025423 5294814287036307605067897932597094299507113620126367097972879402034716443921 -6 0 687391237980223946025423 20011150429541811545907476312379534790007125131505535123833402959378679914999 -6 687391237980223946025423 0 4044485973219037175282817563870444907552769008049452199792563508951156025031 -6 665942745762886148110339 665942745762886148110339 14484846496815990715238595731076076613908537157394670374729372179297487307258 -6 0 665942745762886148110339 17897633735845023589025542617406996954338061026208976928644106112224441245325 -6 665942745762886148110339 0 12847193012291195194405552308519802892103428523541189623880361590351375602307 -6 502666814161950209598677 502666814161950209598677 17505256609148228457637211602769860130412318349430585002345107301882499509960 -6 0 502666814161950209598677 1068689962011235237276638652524484923909282629687819885752175656284119979827 -6 502666814161950209598677 0 11159188149678148365652426388897703108660994647529672860102760877073499383266 -6 194550340526841400783946 194550340526841400783946 6280099194967103209466675793572676677131282527591382172368056203072943191983 -6 0 194550340526841400783946 6506184633901067831683598055898251718092561453663335160169286685659844298232 -6 194550340526841400783946 0 3158941899631672463897764384213781936388972083800464816538145020332722481652 -6 848378722500407886564826 848378722500407886564826 18171752349521701535522419784567959219400133781352661042320694005422614480505 -6 0 848378722500407886564826 11372590674747262942848353866273387993833692943026040641086858771406647047550 -6 848378722500407886564826 0 8179276504563950064163105101592269747933670108751501173207158218504702680937 -6 1030271112124938565070593 1030271112124938565070593 19399114193815993280279395051859773429946658479856360237660925411987725336960 -6 0 1030271112124938565070593 3181447652547497939648946384189949501503151709184216555307501202099274749712 -6 1030271112124938565070593 0 17684953139699009765050003487693633844224269456247941853932801820015154564837 -6 53638046375134878752357896 53638046375134878752357896 12524396444544096674710314885581331339329920816067843966336950604277965203312 -6 0 53638046375134878752357896 21644271645509310186062320036657336388947098966940720102820226420078265046401 -6 53638046375134878752357896 0 12310668175937094387790210851969402441679755185080697650858415216566439054926 -6 244340092955513670873661441 244340092955513670873661441 14441864192039568382156011174611597658694445325893814535790458496668934533437 -6 0 244340092955513670873661441 1550242929113815480158988100871415267969572474211758822685123594178877195369 -6 244340092955513670873661441 0 9744017242497015104332804479814475470946328383366472858621064124112647817628 -6 238227106516505656538016260 238227106516505656538016260 32850335566041106217494540724593475720175821102485615894561572406531295846 -6 0 238227106516505656538016260 13374797701811742728045450797594425837561318557012238459194743899694177410564 -6 238227106516505656538016260 0 879181642007825077069237359427180144755072366501939680232934971375077553093 -6 114517305074967330998834264 114517305074967330998834264 15749323701533881384665329505238121908677666647780980766112085603151154824313 -6 0 114517305074967330998834264 2926365833834875910752742237571966140350402826319257658700426440510382766292 -6 114517305074967330998834264 0 10032897788463808021744036265454261422500290227953461518531485406364861982391 -6 193917592529133645599122603 193917592529133645599122603 7116861151221112863253691455443045998884656970556532235885065899154621711383 -6 0 193917592529133645599122603 11526214878568379463834931661002666138839754881239781593126639805604856038275 -6 193917592529133645599122603 0 5125347598502433622819541367964087494549835299257723012162534015634327159262 -6 265059428212216284663762835 265059428212216284663762835 142528867994682490069695437569041109249873808108497859175294517897602846052 -6 0 265059428212216284663762835 3330239611215860482729999409646873454186907128166851362271350182146181976623 -6 265059428212216284663762835 0 15684796418797176514232767849814112987975032877137565125808688011188780840576 -6 62257582648276236259323021433 62257582648276236259323021433 21696943002633353329586638723362822759382619657130457779350056670023526675191 -6 0 62257582648276236259323021433 21186618162972201271454078206998704321260976731941665492766504820938013398323 -6 62257582648276236259323021433 0 4976841683727493814466514058805213538369160568747812898663960753223095147836 -6 32189801089172378300403667891 32189801089172378300403667891 13464961070272489780567637352683194433462896870939049006647536308747505058112 -6 0 32189801089172378300403667891 10553526949327551485239661589973947961228543166655992035506859399969532365790 -6 32189801089172378300403667891 0 18259934581738613798407264247029277200280933071858747638093799410120926849720 -6 47589881735711972442657796770 47589881735711972442657796770 14511899744559980425956969433768081264688044282677351149201918221872594880078 -6 0 47589881735711972442657796770 5280554719500217350475336990882480540518296377142804478822469159368800012299 -6 47589881735711972442657796770 0 12212470167221637044292935377627869279095904194385471100838920954559437572454 -6 8851827901566083204162231367 8851827901566083204162231367 17022198433339876841789962718234550078454868684790445686042049766052631417299 -6 0 8851827901566083204162231367 8713904322056288539953486553038336367537975530366550166916576646952349434767 -6 8851827901566083204162231367 0 15642005142881051719602352604902778757792060212752590487672052739358671698997 -6 19645021489798962002545563848 19645021489798962002545563848 4946425447061715289813485254360128107698135283324498446199966269334213307521 -6 0 19645021489798962002545563848 13947959474358731160430929475823517223909372241224251356737300041086486618010 -6 19645021489798962002545563848 0 10192871918472852689749473363687443922019883236570494146600018341449504678085 -6 8931998057568672949890022626 8931998057568672949890022626 2946372068763624230393164352563648350218659698295159886722628194176840736225 -6 0 8931998057568672949890022626 8678575126816394500430828905842686494368181070212902195913505749374256128275 -6 8931998057568672949890022626 0 2878958517764072409813442282888974022348455310017276232977096554527107420954 -6 17979744847836449202246625067227 17979744847836449202246625067227 14741518648115218032148487239859240840431896146097202692193135185518169308304 -6 0 17979744847836449202246625067227 2066396136444895205208977935189305967096155608908208530867460003299937226699 -6 17979744847836449202246625067227 0 13857462243084678505392929935410664811276126686007322237250882575003078658196 -6 13175477866112907743905896966449 13175477866112907743905896966449 13729518358660725404385558057843749916736385613749511349755280231629029897489 -6 0 13175477866112907743905896966449 18612327314405120397719298007342307462763315345057878246530314435693357331255 -6 13175477866112907743905896966449 0 16253286799075044922351172797553246006789958243410783655777070825825107280345 -6 3955624931433692042244844099355 3955624931433692042244844099355 4325276793682581384949441937083244718061267102083006514508445490907382010411 -6 0 3955624931433692042244844099355 5541219189624452615859153047925649819803697645996994826868131912871347736021 -6 3955624931433692042244844099355 0 6897768380809075063563483308330096768215862276022327329983173660626218394756 -6 3623192762428616881191380474013 3623192762428616881191380474013 19572280286489766021259452988878678431230207840105702013791895645019255239500 -6 0 3623192762428616881191380474013 9556289603298391737585807027782100541468623406967190483003614161120338556988 -6 3623192762428616881191380474013 0 10414323254896721810450954145622809226202499044679300722173242541051137397525 -6 423625103889994221509265191286 423625103889994221509265191286 3210518232353671813310928490697718237478699552353618585386288494189477479620 -6 0 423625103889994221509265191286 7845946684433042442621697918177746413602877395650622683530242053598565832480 -6 423625103889994221509265191286 0 11220665405148269833622753423138313882463282260928268056806515314213453908965 -6 14289419795992013913219918740680 14289419795992013913219918740680 9594681859637925108523631354379748870466513046533567395156612228293120315915 -6 0 14289419795992013913219918740680 6708453459877545481216305791359420934820816034439924708496132462929973969891 -6 14289419795992013913219918740680 0 11725572063428439141418269240099550445292853728539999321031378732830579568725 -6 1036322828666628607886026780814873 1036322828666628607886026780814873 13342645578606543438818569039382428395758160605530587386328481555073488523711 -6 0 1036322828666628607886026780814873 8232681509918386088557492041954382202088365013804101358522058528031176594364 -6 1036322828666628607886026780814873 0 15781681818802539933861174886242243833900590604825748212847092314471650932099 -6 1159161578203689308695581701602912 1159161578203689308695581701602912 1369587157976822756900480258912570999384583621047010629500805674527033643130 -6 0 1159161578203689308695581701602912 588956151031337152218749767379007008242569513674145353087022587277246233738 -6 1159161578203689308695581701602912 0 9000444689931024348240904206000199785498663498606629935932531189891868129480 -6 788168139141532568467587575302556 788168139141532568467587575302556 16929821042986991495556014903525678643683383861245945440376464655934515608280 -6 0 788168139141532568467587575302556 13097527999423218534769716580056190488378452482019884594765924170695312496532 -6 788168139141532568467587575302556 0 7797787944942286337325166965973503530593278803492248349842183059003056458487 -6 22301990107206922731751474147596 22301990107206922731751474147596 16482933222715719815136698598208222931397549927757951192395472429912215962239 -6 0 22301990107206922731751474147596 1868343632237923192751079026833353081136601386908317127623345432479167092672 -6 22301990107206922731751474147596 0 18634083383595446730763463074691763225767509140658439599284020512687796065107 -6 5016778496686906234416617967930536 5016778496686906234416617967930536 14607702353825605469122265613071303878879138284403792785451404429365681117242 -6 0 5016778496686906234416617967930536 11858380365903285153608289912603300584310578918385786917378216851294593187958 -6 5016778496686906234416617967930536 0 2717067946960217007919782037738381550900866504080504479301536146720356769482 -6 2476799328143028408429552196460489 2476799328143028408429552196460489 1747854937783946984621785124886671393285100588474795060065865395776090053265 -6 0 2476799328143028408429552196460489 6264187177122973378225028101881573464152517850554516236158113546553658630616 -6 2476799328143028408429552196460489 0 18531681696964323057246779441977380969970270887077868998767112303677751945956 -6 760438752558498058861159140213942116 760438752558498058861159140213942116 11789710271936131648168607821307420108267163010294866895426965720963930942364 -6 0 760438752558498058861159140213942116 2968361368687828092181374225570223668524339654784585492644807495422266931446 -6 760438752558498058861159140213942116 0 1735803251885871512586772832872024468296610514203094966501053915552950432169 -6 32762404308845926301014934100567895 32762404308845926301014934100567895 12989368016015441605350418329081680327519834482302966787779327603677135960934 -6 0 32762404308845926301014934100567895 12866225415311343059380572384323692126828094735359759486341867856925746896005 -6 32762404308845926301014934100567895 0 2505780742522496682850112167487181666624060077684351320971545713898589420832 -6 689880042748723018580316124825993919 689880042748723018580316124825993919 4567183875749764178343045846421577169310264955949293580190264546555162641913 -6 0 689880042748723018580316124825993919 18402872507729641173603055788141538123859928783098698848887769756282482387205 -6 689880042748723018580316124825993919 0 12420840892742919675496475319879788836350367305152977375771848429740255781949 -6 724725321422559357616218629417599386 724725321422559357616218629417599386 15380362505822271943109785944171269925569654324606297875988510827813369017641 -6 0 724725321422559357616218629417599386 3336235478407166759232081904130132676997469737358548804472472750195516442316 -6 724725321422559357616218629417599386 0 709185355865659060257258893487219602157212478347134666825013289133373613241 -6 110988444967792801341763937045393607 110988444967792801341763937045393607 18255778838955857442478913613383428601614008444023379950249992484444689497424 -6 0 110988444967792801341763937045393607 12895575920742894456393399710874620282592012114783517250649377007021333301019 -6 110988444967792801341763937045393607 0 2619257365170312675005713323701014335700434870933846250302691175215837677698 -6 843073778749609750927624425869459267 843073778749609750927624425869459267 10082151251031031285718456181909387285092340151591307666839905752442004291778 -6 0 843073778749609750927624425869459267 5645557454158445560841882293892144277128608930375212145413895259336124360682 -6 843073778749609750927624425869459267 0 12664204444383232322258889586410859751150553286158728939468469810810643922236 -6 336831537628931429782210448523125681809 336831537628931429782210448523125681809 10589350836461966200747369318854564774349844411699484058289656338022358774426 -6 0 336831537628931429782210448523125681809 18605255442725204778283667838161944456884993683789253019636211532488527677923 -6 336831537628931429782210448523125681809 0 18513821740737731002665086500966146235267954537957718232342614497516174238627 -6 295645844297087541514152137319884820247 295645844297087541514152137319884820247 4459192206435875968378482349654486823969172963939760129320173563035884513284 -6 0 295645844297087541514152137319884820247 21701313353817071993464585111651739273184645352356782660166630666116757347383 -6 295645844297087541514152137319884820247 0 18052905111221997945516138108427314511749314669036048981944172492770035787756 -6 317374169311517856818067300406944446917 317374169311517856818067300406944446917 5183930302666418625666979008034611218338895636743436508648622991142533626264 -6 0 317374169311517856818067300406944446917 9623016900864843531796783294738062997584808738004116010313332195499998097759 -6 317374169311517856818067300406944446917 0 7309263643057027985202510189520065164725351513924698648130573005457317222866 -6 229323746123379699149725519845957105448 229323746123379699149725519845957105448 18529803060864234666132825004945765333859609971475693210303435923534893340894 -6 0 229323746123379699149725519845957105448 10698000281566394201220850560506554282281838210198113101314857730669236194790 -6 229323746123379699149725519845957105448 0 13384166477545789045281971744089772164589891052466041714768179925851878404305 -6 308037972396171339351440980741287893110 308037972396171339351440980741287893110 6777747554809235641293688661389438117548920125186662703105080504198721541488 -6 0 308037972396171339351440980741287893110 253536259813917762902733150210472459546916870914216560965045686062525100142 -6 308037972396171339351440980741287893110 0 11609337913491283807107206190881247153085178727591461774726978757774884149741 -6 236630132470196203455997217648891592336 236630132470196203455997217648891592336 2296056349870146763389869479559448457242866470504412382199452758474782952111 -6 0 236630132470196203455997217648891592336 11401615457751411824086781707567289124781834658734484229079487696800980409996 -6 236630132470196203455997217648891592336 0 4512779879108586706963429380502725888283190695579299794245262768379638948389 -6 18301163948905144795772560915921851560590 18301163948905144795772560915921851560590 13124170819232004991617991870461581306060293801148970112361615870960056087040 -6 0 18301163948905144795772560915921851560590 4278900018516398794732795937154456302269390209094986771098557074528971067932 -6 18301163948905144795772560915921851560590 0 11003687537115818115382985104480003100664090656800977066737219738280437538578 -6 19764047644017523221027210652356886853677 19764047644017523221027210652356886853677 134186523727454299311843511121633016592077921354627327116896310551866454172 -6 0 19764047644017523221027210652356886853677 5362336451273715633644672957394077157691424126213850478245242595053667459636 -6 19764047644017523221027210652356886853677 0 9468966120879531261969892209564714210788584318584482629212735364872228216978 -6 54919901075952303673991667690961303238411 54919901075952303673991667690961303238411 18603116404922470887231494576157787874786048925763176426728212987244451148335 -6 0 54919901075952303673991667690961303238411 21454297887452376363400376601621374428128265210806948181478164413803205160827 -6 54919901075952303673991667690961303238411 0 11080671359986063207704302919282614094424595918889522650175271248393029365209 -6 16321920162870637829093066152949353662081 16321920162870637829093066152949353662081 3606113715083173840136597356633556687937333253143532379268632587582574788540 -6 0 16321920162870637829093066152949353662081 13948742374689214293941654990539170395206426414798372341854690337842267148995 -6 16321920162870637829093066152949353662081 0 12593314554859454143295518073328999173211622396983386478066230900666939877146 -6 17474320394886525054535747763588367419890 17474320394886525054535747763588367419890 6380015472470453764313544153251618714144382087681535733177845812877942082333 -6 0 17474320394886525054535747763588367419890 15680166674719681391710484152950163960509710294190862585161427491879985909740 -6 17474320394886525054535747763588367419890 0 15071615101319861314727665805099558991169952964265862130305224753693170015366 -6 69146136540108200244466260305158096901689 69146136540108200244466260305158096901689 1507687521470049341074557600923210293509391871599215797955594655077530864190 -6 0 69146136540108200244466260305158096901689 21666379955743961287979050084384831721285176610999918311284111012684540806458 -6 69146136540108200244466260305158096901689 0 2875676625985578084679576403804096485812726957100994804955381751784355045716 -6 21392079331004283852361408290899777295735790 21392079331004283852361408290899777295735790 21681768274898523467503084134515025060419354207649569714326600677782721035840 -6 0 21392079331004283852361408290899777295735790 10569167485819853022068513615230984857665012336830670294882138805754228443129 -6 21392079331004283852361408290899777295735790 0 5380522979265164855930319572840698785562394141176464836411477430126584300265 -6 17055659102617487920980483428225411818700082 17055659102617487920980483428225411818700082 3088325032001870360637868742607253266142843843520054674163500790019914548305 -6 0 17055659102617487920980483428225411818700082 1646282684059219220461265174480814102667362171686041267994784072077548322353 -6 17055659102617487920980483428225411818700082 0 13892299760357794469817027860828795502554978361644998225524338385691008717820 -6 10441712788412149152442268917788227069769779 10441712788412149152442268917788227069769779 2423701611908341097593998636908934280471023166285565241779923901374215999965 -6 0 10441712788412149152442268917788227069769779 3418957502875164351992835681739122769596478505876137157691800524680281319905 -6 10441712788412149152442268917788227069769779 0 134236874706806057026737138013980966380288930481677625339358758589042238962 -6 1240470578921937094127350881534164829722541 1240470578921937094127350881534164829722541 1721536276089075119136391104663600861372870256420712595523709299784737220895 -6 0 1240470578921937094127350881534164829722541 10488130464643906838310491041142373735743509735605587466862885961072775591218 -6 1240470578921937094127350881534164829722541 0 5365499526971174935124314308621945170753367455759470978009570684139198213122 -6 7147874991965697473617764346123326448337845 7147874991965697473617764346123326448337845 8909898004903390337696292382870630657888317621504383565280183077656878041504 -6 0 7147874991965697473617764346123326448337845 4023415826541603776948010994914928737863395105622656674676253468299144146987 -6 7147874991965697473617764346123326448337845 0 289082001715849186387774589697967508914300479451102247147285947272695211617 -6 5793299246260758596101274393737444635517759 5793299246260758596101274393737444635517759 13382436225372237327424425916334932259005090717222136221103681121092233027223 -6 0 5793299246260758596101274393737444635517759 17791069828242744062689953741118647418156061094793377633347249857217891334062 -6 5793299246260758596101274393737444635517759 0 5610163133124017444873495163717921588008590997472553777836248276452664106027 -6 3818134098977532788229779257165413251759632979 3818134098977532788229779257165413251759632979 12447361099475251353587450602818251748478825549351972570983737113183308185569 -6 0 3818134098977532788229779257165413251759632979 2121450760129180533080921229051618757805060335846033745946942325050878822705 -6 3818134098977532788229779257165413251759632979 0 4275050042410824707475739098384242913874297925811724753834850443984355668252 -6 4898200733558666210404372522725094403638890605 4898200733558666210404372522725094403638890605 12127884693598137968511330834149964345020137778464501447529887219996495582098 -6 0 4898200733558666210404372522725094403638890605 8313297998149460008221398520842089567745130857868946656403892268996128994756 -6 4898200733558666210404372522725094403638890605 0 2719629566420988859732629998119362180853602608852350530616495948968489388619 -6 4378489834964170683910402212717834783086985805 4378489834964170683910402212717834783086985805 5622626007290603935527659843746656483511983254599356907947801547979770286515 -6 0 4378489834964170683910402212717834783086985805 14652356190798979018951407444291860411764038477048274768484777344280948611906 -6 4378489834964170683910402212717834783086985805 0 13945492058685798208713541260560168703655217406277297974626078725929394472723 -6 5247751603670957356431303333911672713658088247 5247751603670957356431303333911672713658088247 2256531830939457349616266145442062137129218308675105734132928095287944828783 -6 0 5247751603670957356431303333911672713658088247 6593106125370696306396935068539140545393106848674621570036934809800696418868 -6 5247751603670957356431303333911672713658088247 0 3870726719444635073257056958402178896229594323929821585229834987448183075310 -6 770678005050279602379123633330312047075982365 770678005050279602379123633330312047075982365 5137336393608960656695067003132797603961259417028547264417577357851823349830 -6 0 770678005050279602379123633330312047075982365 14314428999708903300920906468763752393581036552272420540974427777166464147355 -6 770678005050279602379123633330312047075982365 0 18327346937230313852507217486173058209225944830805960787228342312999688393815 -6 907880915752861807719883735005658727311096613 907880915752861807719883735005658727311096613 11141868791430261871893839099117590932192961185046042794910412393037860132990 -6 0 907880915752861807719883735005658727311096613 6150740634379525106278917618264398482272497863238276120362979127776624599289 -6 907880915752861807719883735005658727311096613 0 5995348392905658491934822904835305589707614361953452024396213013472339628518 -6 146203095968306518409443005777446242512187404667 146203095968306518409443005777446242512187404667 14873667885130435263203022415701268779037503661358785872720714622382938218808 -6 0 146203095968306518409443005777446242512187404667 10729583616841892876257026306835298528844433246846901079496915353787957099705 -6 146203095968306518409443005777446242512187404667 0 6187459850667685210488067106912057862951220051792522686243401490753765110520 -6 1090966406750643427961350437692451748283081378400 1090966406750643427961350437692451748283081378400 5478527752992386051491072290273923093928436008304753198404666285453080816356 -6 0 1090966406750643427961350437692451748283081378400 8722294848687382289454335702937210765228006185475856672673107663662367519755 -6 1090966406750643427961350437692451748283081378400 0 14733675238068192929958787210633305182797716338860488521110272079997851927525 -6 270589307940428414500720421159410663489521553477 270589307940428414500720421159410663489521553477 4881581541398837419985177394397521883070634088384010464338829684611003183442 -6 0 270589307940428414500720421159410663489521553477 2619591332666523501750489643006961247725748784097633927755952405349611781510 -6 270589307940428414500720421159410663489521553477 0 419136820876142709088509935528252806610921213917646735280062461991546897250 -6 294193575031415470017342283676188361677938029361 294193575031415470017342283676188361677938029361 19205822791458842756351526457798139299536246230986842885758172050420833748319 -6 0 294193575031415470017342283676188361677938029361 11455515117562527951113838372532741753930271387987659753054820777420536196746 -6 294193575031415470017342283676188361677938029361 0 1414900053980959527473137736261975328383581275720741481779518115057983707847 -6 1379359144276133297932619629588680647433684111640 1379359144276133297932619629588680647433684111640 8895295173768296883994481182802252465915455578182352129712082528237926332560 -6 0 1379359144276133297932619629588680647433684111640 12613187961866371884463696600491071354535756286906940119898084354612227002263 -6 1379359144276133297932619629588680647433684111640 0 8489221067208059060443295189968469773256757130018385899045007475881124014229 -6 725526655599252673193913773466308663523829345773 725526655599252673193913773466308663523829345773 2292464607861525157806216223812624037769797708533615675081626785537132741775 -6 0 725526655599252673193913773466308663523829345773 18567000135855442552845286287635457262392859492980245677148695760952707739255 -6 725526655599252673193913773466308663523829345773 0 3838479158419408670207515378463632343238361733622188767473283572603915825233 -6 196748936827526785371619945279201302975157297455856 196748936827526785371619945279201302975157297455856 1535123455401869470515540312262435776927213205901138509172127927475107026079 -6 0 196748936827526785371619945279201302975157297455856 18525451697017034984997730534005311823044271449216283592125150501700343649364 -6 196748936827526785371619945279201302975157297455856 0 18136970826450134368084495739486073566792140209701266136049758277079001075713 -6 209598035249552029268599517624468916538775765040098 209598035249552029268599517624468916538775765040098 859176540615407941590433190438494815075750738846297666879048581165402996692 -6 0 209598035249552029268599517624468916538775765040098 18779913563925954394075216094148505411758952164881690436659740155363038206106 -6 209598035249552029268599517624468916538775765040098 0 21095576679683863163690147869518844782778721314571136070184972588138360243336 -6 193664650129972312232938003899205094615208397777003 193664650129972312232938003899205094615208397777003 109046154672543865301924239857997657292837600885968230584757725718300137534 -6 0 193664650129972312232938003899205094615208397777003 8218788626867516311963306630310980120173870672322246718920727002162269336743 -6 193664650129972312232938003899205094615208397777003 0 18607645761007344682780176310037720955491115492769120949157179425771254642492 -6 61497234713834754445898584947219352724409233818997 61497234713834754445898584947219352724409233818997 659345121643207960064612927399571710076326771737850574467115622861099348324 -6 0 61497234713834754445898584947219352724409233818997 14918356562237268049798507445695389693690904204393026654062516759836466205384 -6 61497234713834754445898584947219352724409233818997 0 18210002697414676553847456373548157545147562843261821828253608019312189580611 -6 323854589737268632901742849075562838140500664237146 323854589737268632901742849075562838140500664237146 18106633049655991438594191062128063508097974566507596482828452047619644807798 -6 0 323854589737268632901742849075562838140500664237146 5255900008691478776952635561250517579073687165844998339164178169273305195225 -6 323854589737268632901742849075562838140500664237146 0 17685769035785948851194005034220230782341225356716568414209138332390015430526 -6 359932730613597710903631743964349720841387445532016 359932730613597710903631743964349720841387445532016 11236905656634403651375883479057602362866158606745683840046961393657426188465 -6 0 359932730613597710903631743964349720841387445532016 10055697583314565553383006690336083474990284441781692109128224731220711293712 -6 359932730613597710903631743964349720841387445532016 0 6721308460867234832126801761809965564491680122716396236982619608252711405917 -6 13777786870145762879814062558953433822804934510781585 13777786870145762879814062558953433822804934510781585 1644844481285923185566196109742551975111699808173760281987233275616486231164 -6 0 13777786870145762879814062558953433822804934510781585 7826909821494326504137314194617950103627376278108007203907934360523188305123 -6 13777786870145762879814062558953433822804934510781585 0 19046988273735332427177136377974739803892884825339177415777939023665871939083 -6 89612037093011585065439976079923724293935979245589011 89612037093011585065439976079923724293935979245589011 12704722823564373257905467749123934865098042608629729310264794518379952875356 -6 0 89612037093011585065439976079923724293935979245589011 2887669043455083519480139364312236244675444474028698976432850602026136222178 -6 89612037093011585065439976079923724293935979245589011 0 13738312944276252335341556073168593765169495139860845213759806064483100832972 -6 69304942731505437250402871168159369515469543330375979 69304942731505437250402871168159369515469543330375979 21480556432669297476123527610102826462931438826983386669812235035192279773240 -6 0 69304942731505437250402871168159369515469543330375979 18339973617464288709852253095368061249370780216734002781498092056378675898252 -6 69304942731505437250402871168159369515469543330375979 0 11895278797110306786402979833395134158088265600065094847288817423865409837482 -6 11408414591911114114292470084897111680689799968822863 11408414591911114114292470084897111680689799968822863 3406790234776711882191369610595763568877144250758562490071785169598741451112 -6 0 11408414591911114114292470084897111680689799968822863 13753376195725201426114442795828710941178769898139633713048356928782020595309 -6 11408414591911114114292470084897111680689799968822863 0 11590824088933603584339583039547404732011018248229545084439878504681084947231 -6 48119459728544991158852009742954344890894407348893681 48119459728544991158852009742954344890894407348893681 16145387069196829003199398146247588966915371667066372157037403464914769123618 -6 0 48119459728544991158852009742954344890894407348893681 20473917029397180706104093755138235981267503554850997117712563749098253370192 -6 48119459728544991158852009742954344890894407348893681 0 334331603448992845372979143921134657442194706249091660467269285024615227722 -6 48683169953301396815470902798493840468012799210198306 48683169953301396815470902798493840468012799210198306 16954940727756039314253735590939904010109021573016258906641244014559920392232 -6 0 48683169953301396815470902798493840468012799210198306 3329505698727944686654467632508010056829974869315978963162011847838470231693 -6 48683169953301396815470902798493840468012799210198306 0 4373219234548837266614813170570287181257888429478003532820890719427513826079 -6 15028432188239383882403555440578569072878637499648093454 15028432188239383882403555440578569072878637499648093454 18818814233981593216639429667835602995441391675993722980433366019225542626386 -6 0 15028432188239383882403555440578569072878637499648093454 15656571711452585840280054060850046504810629140442844531929451625949199426139 -6 15028432188239383882403555440578569072878637499648093454 0 2795977899996261470285147708587541104457107740501962487054256486020784607583 -6 6708425935069406833517933117484271040804271338767966127 6708425935069406833517933117484271040804271338767966127 4990773428097471990674702149398920210742501067347819220164298085507616507860 -6 0 6708425935069406833517933117484271040804271338767966127 19177459685969623713616589124113637523779529213979410156573337681480861395359 -6 6708425935069406833517933117484271040804271338767966127 0 17837393401949969449374457835084034100135470715135627494179256816660886149474 -6 19793869944824429415954786004054772158779747149176971319 19793869944824429415954786004054772158779747149176971319 7636490828727120827715048390176556945740242218150171066685903876122921114724 -6 0 19793869944824429415954786004054772158779747149176971319 16259360556821956971584780791890478017090635353194994095461209024570793440194 -6 19793869944824429415954786004054772158779747149176971319 0 17693985829256374494235589730296411073691631029626396159550825137235750803982 -6 7615008726549103402254293002696670424207050128244707260 7615008726549103402254293002696670424207050128244707260 6937672683694147113205028831550633439940266576037615927196122396030542004824 -6 0 7615008726549103402254293002696670424207050128244707260 434138320137334154118842592606213479052270179165515438643180199975881083369 -6 7615008726549103402254293002696670424207050128244707260 0 18156476873857734567573812253409920476184936718842779742530599911060653325463 -6 12541953421521212743849764649282107793090375650912568360 12541953421521212743849764649282107793090375650912568360 6623846236914674245920307480093467813401787527661873460881083049972964296258 -6 0 12541953421521212743849764649282107793090375650912568360 13596447312616789183473640134201630238964719315744029496687061237751022121508 -6 12541953421521212743849764649282107793090375650912568360 0 5779363710676369463417195231765555694811367598058997873433450914889864628717 -6 21537176990036391320940381417378862643333236894331254716 21537176990036391320940381417378862643333236894331254716 9832295523909335438865756840246265198318238317042883020443847813975576827113 -6 0 21537176990036391320940381417378862643333236894331254716 1311871063680029326557750163151219879696166877655440563214702649832000513573 -6 21537176990036391320940381417378862643333236894331254716 0 393873038948945832203370953986155563396677987033861125381865399308568403609 -6 4826448105982877391542379247764928922487311990847524324261 4826448105982877391542379247764928922487311990847524324261 720686054950608575999774683986347960082518490262490040933822188095825828937 -6 0 4826448105982877391542379247764928922487311990847524324261 2358962644993704403454567138364021867125779566261448144754874409163845609369 -6 4826448105982877391542379247764928922487311990847524324261 0 757945955434083394694694937714792875079582208963614874223667681714934563154 -6 2765126747869699279184567703688730672290996928665849041224 2765126747869699279184567703688730672290996928665849041224 3286303841466016258536036655251240935395878990354805913340875671430147522672 -6 0 2765126747869699279184567703688730672290996928665849041224 1847008652808949162617606053432725828384111438705368445039050305659075563745 -6 2765126747869699279184567703688730672290996928665849041224 0 16714506065134345550609574182458700437472903654485977054442474050427125976345 -6 1036420455319619934936488449793824749824639680687769420754 1036420455319619934936488449793824749824639680687769420754 18371239343996568676403038833875501028305418497468027084975395230415836684800 -6 0 1036420455319619934936488449793824749824639680687769420754 8523093163241858580095590771341614992513750464150109288154771251276713568260 -6 1036420455319619934936488449793824749824639680687769420754 0 8779214761116700314143903066122233920550624619760308280851216254249952045489 -6 5340200850908719649542233360315843160883494932725359877663 5340200850908719649542233360315843160883494932725359877663 1870671992574900378246955623287352656829959591448139758516830711349285932031 -6 0 5340200850908719649542233360315843160883494932725359877663 15588083116728675079913397120625232349346132570904569881835707456049518585058 -6 5340200850908719649542233360315843160883494932725359877663 0 6982232498901556858077844517925628918575902194161169312125735837347873423178 -6 4093329837622807403461985826061133443396029046424118333980 4093329837622807403461985826061133443396029046424118333980 4506160901548666690445549800239388889433604451665924969201719497505087829994 -6 0 4093329837622807403461985826061133443396029046424118333980 15027118039347564523038977621490316541921665845680768583358184498861411814569 -6 4093329837622807403461985826061133443396029046424118333980 0 15778898337155788518713658899693788032291910346262541377710243805459478328751 -6 3034477151187995991431111608042324190438646554939408878625 3034477151187995991431111608042324190438646554939408878625 1960267442267764552399634355989024787738551761108476485938798427045598849983 -6 0 3034477151187995991431111608042324190438646554939408878625 12604208406320021176483521086222318337642168743249009877109890557127157254199 -6 3034477151187995991431111608042324190438646554939408878625 0 7341528222516247420072485420067563964472324568432148000832526463647812279940 -6 523528126231953926599483070936167970832977098828732777869950 523528126231953926599483070936167970832977098828732777869950 10726507104387326481243278886214445730225817007858241081814747109144161966165 -6 0 523528126231953926599483070936167970832977098828732777869950 13913500812649273852295741300769514461736580318548364677923399291008590207201 -6 523528126231953926599483070936167970832977098828732777869950 0 13341953983310576089188893864126404840692827589244264337722235904286668324302 -6 1078646908883835411459473142309093313826340867275063989097326 1078646908883835411459473142309093313826340867275063989097326 19792073484135798026007395832952392571153320133659474290926091492362388483618 -6 0 1078646908883835411459473142309093313826340867275063989097326 6416013601496846798659685502346435625604586793519177503478831952452169286671 -6 1078646908883835411459473142309093313826340867275063989097326 0 10589113067930752050252185700149448642316230360673511675286564161744723275703 -6 1526698652611597854996315504126372819700947459881450972046260 1526698652611597854996315504126372819700947459881450972046260 20465454168242341294926792649298193370025893503157994248918839893580422691489 -6 0 1526698652611597854996315504126372819700947459881450972046260 10416497797575099206330772990832351353902638472798909072441358527849662532329 -6 1526698652611597854996315504126372819700947459881450972046260 0 19644672611407672322423091575339065510063531954503297516411008354898605556500 -6 1018379703233271698525242374169794825799268770867640016515009 1018379703233271698525242374169794825799268770867640016515009 4967796560788904755123462862216856342358540862583688840993152301626652954728 -6 0 1018379703233271698525242374169794825799268770867640016515009 8541738574118847631904886305460350838195342552348273176183960290191107503886 -6 1018379703233271698525242374169794825799268770867640016515009 0 10295344183551317575452028186204597829528149004837697121348276992163915754048 -6 1532779503020224125698178123126425144734519194900769994355476 1532779503020224125698178123126425144734519194900769994355476 3661094385102073410972634685163601216560370858449028708707325538501446826684 -6 0 1532779503020224125698178123126425144734519194900769994355476 14126884435095322193149152265281199803018111334241185733928046826266430222979 -6 1532779503020224125698178123126425144734519194900769994355476 0 6169708435852949139757265030022356289220655736410119260625447641032242784150 -6 1331043380577363741435027117375264653890948461685003993184734 1331043380577363741435027117375264653890948461685003993184734 4573068927837329071439564713279074208348474486903353176524239740759128848449 -6 0 1331043380577363741435027117375264653890948461685003993184734 4573525012264753079916928369457693987769385254365142939972095460246204661695 -6 1331043380577363741435027117375264653890948461685003993184734 0 2912374184748500893156482561167758693277616753489128418153447681618387580150 -6 188859139257055387297987615947263309235341516058328005853084083 188859139257055387297987615947263309235341516058328005853084083 11843855189538968390104343384812382390473193730462373951035039521645591784473 -6 0 188859139257055387297987615947263309235341516058328005853084083 8448927482879017407747800774057835857402146971632789550108484564736732902712 -6 188859139257055387297987615947263309235341516058328005853084083 0 10518629801766290330874462871631562660498007916124079912408582727507521861360 -6 379776469920446571974676254280096085846554840018770235945269876 379776469920446571974676254280096085846554840018770235945269876 14993008262787242947556761566247068977580119061281289165826447166319412854361 -6 0 379776469920446571974676254280096085846554840018770235945269876 14408997376107399521158434311337450706515347553886761593899147621941898367587 -6 379776469920446571974676254280096085846554840018770235945269876 0 19119248861107626831280186757789742225988602955084041984623864101433174099138 -6 294225456577834725078479009114072190617302481691959249518074814 294225456577834725078479009114072190617302481691959249518074814 6158315092337736614823934658134035363730109944774528369239925793521732319848 -6 0 294225456577834725078479009114072190617302481691959249518074814 10175923812123319371062914470380564994102071316302026969626702479526944165606 -6 294225456577834725078479009114072190617302481691959249518074814 0 12096416577945959842497091782356024635611801544387437103025849391042454642025 -6 2758622564140515111922597342418011994343948047544636502389074 2758622564140515111922597342418011994343948047544636502389074 8608474778093659965036473519263079163994366999210072834887087985920480753276 -6 0 2758622564140515111922597342418011994343948047544636502389074 7100977313122632121880683104241680596080658740523442314300231785706873359050 -6 2758622564140515111922597342418011994343948047544636502389074 0 15745821692871218261168838257987316842828320870636989753443473135728044108786 -6 207303317919341550652106657462448169650185779471255617012452083 207303317919341550652106657462448169650185779471255617012452083 18793199271729395963329416800103432677358890825868200325734667012857151658037 -6 0 207303317919341550652106657462448169650185779471255617012452083 10086371190620890578675547782711292051687933848606178125273635483942703188583 -6 207303317919341550652106657462448169650185779471255617012452083 0 14783496932675756310869989329333597825035684506035390934739000780939545964873 -6 149679224638372073307516556038563213496811981278278780195301298 149679224638372073307516556038563213496811981278278780195301298 20638573276802045461302202936072017161217266385669021366666774674110844933161 -6 0 149679224638372073307516556038563213496811981278278780195301298 3882182171317605814125200675439312843313328102413455174740740607753580099132 -6 149679224638372073307516556038563213496811981278278780195301298 0 21632615654859390593273456127280385419474974834863483282405247726058299609703 -6 65737864876760663587172552216334797837135547686256629533886361384 65737864876760663587172552216334797837135547686256629533886361384 6191360516246570376456902065284650286883365427262723938707341231098924031170 -6 0 65737864876760663587172552216334797837135547686256629533886361384 17331360487455446512053582831488349190665042136401690079036903616720988203274 -6 65737864876760663587172552216334797837135547686256629533886361384 0 3813295355631236938637652264795525022668841663063400904119102501399584637793 -6 10747608900933650918469194946551423387487478578654011490082326311 10747608900933650918469194946551423387487478578654011490082326311 10908462366569385833013409358041724172843717888415551855448618607028412444897 -6 0 10747608900933650918469194946551423387487478578654011490082326311 17804090051199965849365855194028441327264688977229839912374320687148282796001 -6 10747608900933650918469194946551423387487478578654011490082326311 0 8660919422665606135379280949454054740115056361501839318361138309754445619994 -6 34694015305933395195240784276389141224007950892562673854331391607 34694015305933395195240784276389141224007950892562673854331391607 920720054440902678254985616744527430720143156482162131181265343048849832323 -6 0 34694015305933395195240784276389141224007950892562673854331391607 19056611947768495876920419562970914414855937289286601217320547520228161713765 -6 34694015305933395195240784276389141224007950892562673854331391607 0 8937318052399998275934517598025859410870904442280008925245374130170095550238 -6 5436541889689150384567921159482963541492620565897112340458830570 5436541889689150384567921159482963541492620565897112340458830570 4367973681510271174957439612359865440906764550832551766789970470527038269617 -6 0 5436541889689150384567921159482963541492620565897112340458830570 16927607975055589267308661104686380871936398613837627948543299552670616545627 -6 5436541889689150384567921159482963541492620565897112340458830570 0 17806225244827729412845864475815649645908213650222614638435789583402340565470 -6 80457913440472896623391178747950287240249765431490961708616967480 80457913440472896623391178747950287240249765431490961708616967480 21180814455494413418695526981344479341157325222166470713961108906198547508995 -6 0 80457913440472896623391178747950287240249765431490961708616967480 3553961710757547381277141342113415498499009554304237202745095728477470189826 -6 80457913440472896623391178747950287240249765431490961708616967480 0 10203463996725378847432602743131416894108379224416091086198385218927218790286 -6 7002646882497767383944296512524789486811815460010867792490795042 7002646882497767383944296512524789486811815460010867792490795042 2467642294276720894050152966179483281067884123552698146231186222647007909 -6 0 7002646882497767383944296512524789486811815460010867792490795042 2717306038129159077378820761524125557807245878362652889100252990462958674453 -6 7002646882497767383944296512524789486811815460010867792490795042 0 14438815198553971344242259591697352657912796422876408105241503486917455711739 -6 9960542110614378215522854903321333518500829386606688370270289751885 9960542110614378215522854903321333518500829386606688370270289751885 20036026891635923951702208013556683084210687524443390579506939283842528656289 -6 0 9960542110614378215522854903321333518500829386606688370270289751885 10247383916737922088942739255532532390225362722908179720003551930577859197540 -6 9960542110614378215522854903321333518500829386606688370270289751885 0 21800834416108737576858801764835999200675637278904833152440466789563350942525 -6 332935353245800454070494431790772106924676049772410160640512118475 332935353245800454070494431790772106924676049772410160640512118475 13420900808524969960714463701176303336026180755117738002168161204102691840496 -6 0 332935353245800454070494431790772106924676049772410160640512118475 8254583711689483077373332442428133959375856294523910816260206893710474580498 -6 332935353245800454070494431790772106924676049772410160640512118475 0 3590520253471756223215895828229086967870286781288240681241147309040174913514 -6 23163519598722741020297392844856474175805867240301760747871582353510 23163519598722741020297392844856474175805867240301760747871582353510 6302671647228592600827410307019782110728855586228746667706038706879253151696 -6 0 23163519598722741020297392844856474175805867240301760747871582353510 3330118575863258094519314762422953465542683402331674797662545885217109933296 -6 23163519598722741020297392844856474175805867240301760747871582353510 0 17229439275041115328181780963363163848041723153832730423794424762797622199118 -6 12731965885363235280546887867677832607959482555368182147456532390613 12731965885363235280546887867677832607959482555368182147456532390613 6107748385756754455148843547561405759217313001735769326164209527915504082152 -6 0 12731965885363235280546887867677832607959482555368182147456532390613 6665637435409790704005088033242536240508677566200482125416826178218763347331 -6 12731965885363235280546887867677832607959482555368182147456532390613 0 19309805907488623828749813758551814549467763548353870780514821470746171518839 -6 1720007252540685059898123979440999692276918662939203923391132631838 1720007252540685059898123979440999692276918662939203923391132631838 20956973583698369681191483228613700080893036078748040932669409424088694143172 -6 0 1720007252540685059898123979440999692276918662939203923391132631838 3273142398302882696556362855007058436807242111404436048288424693818065226566 -6 1720007252540685059898123979440999692276918662939203923391132631838 0 14336859234188686307581316129066114697783447257098397721691070692263452980856 -6 2786571407685282250339432408941098769314722565042259420426660352678 2786571407685282250339432408941098769314722565042259420426660352678 1325308261411071921115405738506640657592634266422912647733392925762179739627 -6 0 2786571407685282250339432408941098769314722565042259420426660352678 7264345255547517243842602014531456940787746609772727217073257541810558696523 -6 2786571407685282250339432408941098769314722565042259420426660352678 0 12780503975375554443675338315704691638261824214301466188503111935195962316359 -6 3697818691970681810631504055135993101777175177475475095554979931959089 3697818691970681810631504055135993101777175177475475095554979931959089 13834392841539548617497019564924064458961205276652895543540563955352828231986 -6 0 3697818691970681810631504055135993101777175177475475095554979931959089 3579797281919552929983566869317408954729773884999764534811020885335577772274 -6 3697818691970681810631504055135993101777175177475475095554979931959089 0 11455074180497785888837627931978299325069429678039015057280777573970879249865 -6 106019804102395935876870977650837156370735571186616027872412719848144 106019804102395935876870977650837156370735571186616027872412719848144 17935372074734936116526355839359099223596384981570759434157394576596924689595 -6 0 106019804102395935876870977650837156370735571186616027872412719848144 21086834272251230241198833943389109638024036158639910835580767986381360434302 -6 106019804102395935876870977650837156370735571186616027872412719848144 0 21537042025106520192476395062465488060983002407557878693869366766157423775612 -6 2222474423115968943986803770816898126000877759139030471524741360331582 2222474423115968943986803770816898126000877759139030471524741360331582 18064454019836812744755330947241194243344041821959393902428139654270651410822 -6 0 2222474423115968943986803770816898126000877759139030471524741360331582 21749970220415587405961081372303811981227982256995959569458440061065604031836 -6 2222474423115968943986803770816898126000877759139030471524741360331582 0 13745559025419399517701149745353851791831110545549737912548881240227784561072 -6 1175549400748842569359647968466776259326966462796234879511305439365865 1175549400748842569359647968466776259326966462796234879511305439365865 8254202731407877339958559002016215960907913996047120092865301309637807096563 -6 0 1175549400748842569359647968466776259326966462796234879511305439365865 5456928965894608391895265514297149999250480091226336195932231528415406392588 -6 1175549400748842569359647968466776259326966462796234879511305439365865 0 1368168856664812918511707725309584433773557531013064407765597201583162463220 -6 4299985571249736045648141970227205025098414582731906916907668210731689 4299985571249736045648141970227205025098414582731906916907668210731689 1811418849974495629375278426204779838692975245131685450798761243961399903973 -6 0 4299985571249736045648141970227205025098414582731906916907668210731689 19895952653371330649043622640035660001761251918832201041974069230156863364005 -6 4299985571249736045648141970227205025098414582731906916907668210731689 0 7373577254387958353701483242172751517995965838147828309266534302180045002860 -6 6448355797616026830323069082406072031149724610504210161685567857310029 6448355797616026830323069082406072031149724610504210161685567857310029 10885820519238183108518660594676182083220104824645685681274437104590722778370 -6 0 6448355797616026830323069082406072031149724610504210161685567857310029 9986924045997124744617107042984106582084014057884246407516851101582839351626 -6 6448355797616026830323069082406072031149724610504210161685567857310029 0 21599615603346166044370808320789866311188789359712434910810996915263858094594 -6 417005835657085590680740450059687863262191219489879215754921001041657516 417005835657085590680740450059687863262191219489879215754921001041657516 2997611037546070035879894178329666844912334242143907349423494950218444474582 -6 0 417005835657085590680740450059687863262191219489879215754921001041657516 3155988597995725437126665195755489050332736460671495513014062350496179161358 -6 417005835657085590680740450059687863262191219489879215754921001041657516 0 21857367631754487644591759878223013635490700875074744292883169206299868968682 -6 1169717354368838328734104647162847125629751421222345521562438237759682544 1169717354368838328734104647162847125629751421222345521562438237759682544 6402452044679185009997739904490123015770576415938799424897977568325799678763 -6 0 1169717354368838328734104647162847125629751421222345521562438237759682544 18572542858170259633581516812022131028126528180863322248818947805092958278634 -6 1169717354368838328734104647162847125629751421222345521562438237759682544 0 11144865562212414123705782136641096736282052883498693788700479601625855388566 -6 743177306527039602415665730273135717275137789264143269802740795408231211 743177306527039602415665730273135717275137789264143269802740795408231211 18231006310503957818507801380254503816608756765031841226265907234333922212201 -6 0 743177306527039602415665730273135717275137789264143269802740795408231211 17929423629788925637589036982330542102178195640722844262154182726807505558792 -6 743177306527039602415665730273135717275137789264143269802740795408231211 0 20685980741882866780437577518340485997574689988132028580422758548321976428459 -6 651165187186310287020524239080035902232290349173101083465832414316511626 651165187186310287020524239080035902232290349173101083465832414316511626 16842110140620953338450966666239469735982688561520787984396249190510606840917 -6 0 651165187186310287020524239080035902232290349173101083465832414316511626 15150010111789605492942658231199853477038244676139048083365810432746374813274 -6 651165187186310287020524239080035902232290349173101083465832414316511626 0 15957376188483147447942075633716502171535206637059539072552792093182606653177 -6 590236391075294664833702957068177405442451575764265582250962910589418182 590236391075294664833702957068177405442451575764265582250962910589418182 21536438669725193650039932287383977731745793822892757169841110993502679620229 -6 0 590236391075294664833702957068177405442451575764265582250962910589418182 19515702078124343882266724151718268739174511637383074093131726522610335884467 -6 590236391075294664833702957068177405442451575764265582250962910589418182 0 13600071580796008835770657430332104027928731695368317509696074865257215433562 -6 388981885503061965354485486392722501740647456817073704994651699674968671 388981885503061965354485486392722501740647456817073704994651699674968671 3663135388098680276369493491923208828891551340550873577429225996918150170154 -6 0 388981885503061965354485486392722501740647456817073704994651699674968671 19341575787266291066911434850714987798573886788169520398847502937963830869832 -6 388981885503061965354485486392722501740647456817073704994651699674968671 0 2281352867953170023553475472141985207189709827454995363686763103446256103740 -6 58594825100519138315769680293884362850415067192208348280546603840906112985 58594825100519138315769680293884362850415067192208348280546603840906112985 696402663832731782107957993513747326272610366859951913687435897784243817372 -6 0 58594825100519138315769680293884362850415067192208348280546603840906112985 19906440288334610518041830636152263899947417964852414324160285532901909533842 -6 58594825100519138315769680293884362850415067192208348280546603840906112985 0 1003818897315538948624554076875431345910658696701953751703663421637937151904 -6 44163148392407901304262680269300950553670805139975891092056358087756200504 44163148392407901304262680269300950553670805139975891092056358087756200504 4642593568371598082346389269046915960426769128338173225489112558283669187632 -6 0 44163148392407901304262680269300950553670805139975891092056358087756200504 3592286077441627926778526748013783505888801107604064046170454309929192667123 -6 44163148392407901304262680269300950553670805139975891092056358087756200504 0 362256280766062384642904441701982406008791311409568535021623430048040957760 -6 422430966944467267705740288246570068093173449747260656261678024479660573461 422430966944467267705740288246570068093173449747260656261678024479660573461 14001477472788131636354189103511903254468271624945999559143289174704673521217 -6 0 422430966944467267705740288246570068093173449747260656261678024479660573461 8212893580799348842453026760193831425991369466888783279611766490066302429771 -6 422430966944467267705740288246570068093173449747260656261678024479660573461 0 14501986263590130285006154473212958585074420099859205185541418058567289881869 -6 271425016321911257141631323152180272293994474904462323921110032920998337695 271425016321911257141631323152180272293994474904462323921110032920998337695 21099363577962638119379976076668442032720987183546303936588353056168019275020 -6 0 271425016321911257141631323152180272293994474904462323921110032920998337695 7923836762043959324765749919357527773156925824725053318209835651809822277553 -6 271425016321911257141631323152180272293994474904462323921110032920998337695 0 371915678982891536569815533993090551447940228078069219299386635994944922750 -6 215645532002590517161635984158960034717978608320680157057823696608565328872 215645532002590517161635984158960034717978608320680157057823696608565328872 15521172735031250276560411543753198988131015995513902186595850652156949548002 -6 0 215645532002590517161635984158960034717978608320680157057823696608565328872 13985554021085120109526695768522376927503887875457879607318662858549686892179 -6 215645532002590517161635984158960034717978608320680157057823696608565328872 0 8787675692812747552113220722276149492636731146771217574239397768797165351616 -6 283915863058293431615749207247139964307711053968026579104434546065627886279 283915863058293431615749207247139964307711053968026579104434546065627886279 4602697642429520631917992142799378255640258912855823751465203205811254201863 -6 0 283915863058293431615749207247139964307711053968026579104434546065627886279 7163964259766037876221194323835311295074825586073008146318490535771805291193 -6 283915863058293431615749207247139964307711053968026579104434546065627886279 0 16428924413994121584703246873768858630201290427888638032196534414827808325558 -6 12300734523270388670246672444614834379731277775212726108331475604581375120346 12300734523270388670246672444614834379731277775212726108331475604581375120346 297628351999710345327888841791587607549758472549702739184236549055065866359 -6 0 12300734523270388670246672444614834379731277775212726108331475604581375120346 19616963909650060427660144968802575954900454704479315665956570915356886949094 -6 12300734523270388670246672444614834379731277775212726108331475604581375120346 0 17989789670477071882730557888224796106383576352161749470436830641481868191789 -6 15269724289404893295498193386955893630382623708616443502066293341436262104121 15269724289404893295498193386955893630382623708616443502066293341436262104121 18375765713091621360604137816883916652435358819438573947411109620405889238369 -6 0 15269724289404893295498193386955893630382623708616443502066293341436262104121 2804723033934892573858728019783488399637285269072393844906024436471891337913 -6 15269724289404893295498193386955893630382623708616443502066293341436262104121 0 17055685666883135162612730072731476497742240527321201060164358530496976653895 -6 1989636574038449663126215279069746979357435042397506567806465823953706044281 1989636574038449663126215279069746979357435042397506567806465823953706044281 6514085784036495808557953110827477908425925900251180100831079754769677560160 -6 0 1989636574038449663126215279069746979357435042397506567806465823953706044281 20413000657117057043213713290437256494202173284218961387837150063624063179274 -6 1989636574038449663126215279069746979357435042397506567806465823953706044281 0 2734559320037755892234463682330473062102215026733229460356646591846241278661 -6 13005879071196222066607513418606997020748755442177934055567026969651385456375 13005879071196222066607513418606997020748755442177934055567026969651385456375 12230410876843420521734639782546843473755373842234271404241170499132804011110 -6 0 13005879071196222066607513418606997020748755442177934055567026969651385456375 7620115863478778746705864807155377634963134269255821052034661343323677044509 -6 13005879071196222066607513418606997020748755442177934055567026969651385456375 0 10722543694851645718895215511865555237299166510999261027474733965378693479119 -6 2946690020883835228481538034037667030112769571724324674467399801095540992292 2946690020883835228481538034037667030112769571724324674467399801095540992292 4067474577671719316015464098316347545463077122503268749967626644069312861602 -6 0 2946690020883835228481538034037667030112769571724324674467399801095540992292 16045383487971345541184842393061690041376143706101024183999280653293756496471 -6 2946690020883835228481538034037667030112769571724324674467399801095540992292 0 12961010641101550865817735568414298687961054284051067979355084261668802789286 -6 14304180984250378986789008586936766078328960697480840307508664252383718017758 14304180984250378986789008586936766078328960697480840307508664252383718017758 6381445802391264925774443611099377627677161642772635416481936373783237566631 -6 0 14304180984250378986789008586936766078328960697480840307508664252383718017758 2578668140147468113472599911638500703174737803051797602020792797952159447481 -6 14304180984250378986789008586936766078328960697480840307508664252383718017758 0 4840660717891500236417584684291569448530333418874526882694610669400538558677 -7 0 0 20994231331856095272861976502721128670019193481895476667943874333621461724676 -7 4 4 18747253005792370687204412166155555082728494699723704254497260141381952010296 -7 0 4 2400488805001498029992249792881524182981734765735511221733870421952905799209 -7 4 0 8962575652027094297962328171293921026023543664302668286792446712579907613985 -7 234 234 19840847724018688829631248704567425458369885596125311517565958332149746206549 -7 0 234 7647077254325846360228761400400447183802956603400736259761305343669192781551 -7 234 0 5971554597063703033342669006182794468530918901689658362623310148622899084680 -7 153 153 8995247250458630025985126106243062135297807525748150346698752524484376268767 -7 0 153 1181463912832023390392657781135948975578371684470840089941615615665638568692 -7 153 0 6371158747478815312779647206095682416177098856029625412506697112872074297211 -7 227 227 10672788219115858420967704607285845215613157277931563444434908072317363304474 -7 0 227 3370488400918499953451373233109428532375232110901000565406802818006153152654 -7 227 0 1164951604530306616691410182382673337353451481422050969754870099434448387414 -7 88 88 13878864873431015457104357203034782952508173739406327716544883038528082598034 -7 0 88 761687593273018801893990233442219345675142092939295956186499732210849957353 -7 88 0 17898106653705865795838568820539864356982558838828646298233516341393389776239 -7 151 151 21768699512360256455616064137171860457709808494221558896459806529897545128547 -7 0 151 13637732926922210161363070830498512330495158409582195086848586629239925798389 -7 151 0 14374480861587214833002551935765697143083074048821566642915804697735073286863 -7 58571 58571 11501605121155859310853121352207958010820723873654295431537555932551346062738 -7 0 58571 11136590024464160827169226344534873282403028641169608318260534039477818488204 -7 58571 0 9239011205517343007130793534600980688471873735179440046901071171730468388433 -7 31648 31648 17121181002961671572594644831294482945370393561993866723454567563351812795764 -7 0 31648 19440137037836551695169099138045612157128985390298265797716152358961627186304 -7 31648 0 20403740072397200263271466523525639044357004016566047518678410112501436211114 -7 47388 47388 12183906837958958539432276400104539534548286338212138229644040175283351654194 -7 0 47388 8436686469525355016219903389722614600061997839274346293195767093935554224580 -7 47388 0 13720176391983428567085361742228937179930718517422413150482255667000412907150 -7 63589 63589 16715565069671862591538334835228068490814329058636407564873212271956080750778 -7 0 63589 21705799488316615941881126823884313349294180529772285717285616168804039047240 -7 63589 0 1763815859854270413612510973763237998611297536830341820369459738294095403777 -7 57412 57412 13395412874808033415054082346263034723036320484035155535303585111004886428010 -7 0 57412 21138386022884871087603323282457273180949253343493374597659572037621519359620 -7 57412 0 13452004662033887503766924809808022942847317749231290943613083731740065337716 -7 65049 65049 6036162920981515854163798614361000265989891971639356821411640645723457490283 -7 0 65049 17794015705181992885866335340669912675016786749720960542879361998465548278832 -7 65049 0 639233810608654149346177001583304297002087733838769466322839463432660570923 -7 485188 485188 14362143765777067596610304500143829527962733318227923535340358070936153547601 -7 0 485188 19021038872147329892018587088423262537871158403316089025158122005788241907924 -7 485188 0 16320420245853737709525461232795823481687084390983621909132638418220617543461 -7 2012417 2012417 4511936612754982162798793982835043589715299013267266600938674597221748040921 -7 0 2012417 20575150304876244979458318055027801102477572476906307765358304288973172850662 -7 2012417 0 7202815050276323396764337563672408201819478614856718541282252251526166826569 -7 8060366 8060366 5087085889295615866569362950179878090977229239446901672515177225147322196829 -7 0 8060366 2028019722941384182739072046443493586201254832266708285597564565809790257672 -7 8060366 0 4395593208796781481571423147625722206582017278194039797188538989579640372945 -7 11959599 11959599 715720382591867841156398611136348957343356681310083516876730061002476701636 -7 0 11959599 14651807529044145135823662325058994618820126519510348520023112866623190931425 -7 11959599 0 10524052605478115813382293000764699710849766518201747728296047214632992369520 -7 4783486 4783486 842171142237026317291939900099104461968182289357363528795002301278100230098 -7 0 4783486 8632091819037651894151505039897509098887304383701671844831273123112160565662 -7 4783486 0 1997938373325945377817488338241443942705429388788184308188844677484365943082 -7 13036977 13036977 268580334288537350148272213042634369903055066444196269284604085089864710430 -7 0 13036977 1586940663934637916524503173121476877267127414788444239192971574311297879817 -7 13036977 0 3212243208380557285218054066483934385392118135860940721360838921197762745320 -7 2969942405 2969942405 17001355624328613463537575661833296563339053854233534412645907738563335109118 -7 0 2969942405 7526608629438762975683906225276541822072927091724803647591319326406414748719 -7 2969942405 0 14228346642553705378014515775030876408947547590617070553150294607765556290220 -7 3443873377 3443873377 4623795034630059707503186561607238755595958457119069347618503705864508389687 -7 0 3443873377 17251569540017994382938201708601451311980372575432343887116254772411649526958 -7 3443873377 0 2012737284805373448820280811703037430630030755300758957586688281932359195744 -7 2464471814 2464471814 10830694480452794652443565155303613344438630030405894304565972350260156061176 -7 0 2464471814 18523083543036755543695638965501099067860286999773603542973182700178720986943 -7 2464471814 0 8853423482456146771548092443743171227064778223919108726120329862403360296617 -7 1540288886 1540288886 6100340600459231297764636370454700432168353444514967427406615332679051232609 -7 0 1540288886 969955679535523384241701526702243438176518314972696038227423811979447727921 -7 1540288886 0 21201121515784354442529777406960980518332833007681678430162916007840060012678 -7 2103891132 2103891132 17480803491840706912383103684445409074281566719023187053571203271547844912565 -7 0 2103891132 19315612569427869995572362607239655506893029139308038019912932063932706852568 -7 2103891132 0 12414149659938180153304726487540546992671479358561966041559542225420426241106 -7 2357522259 2357522259 1702889757414274055848568366742159824256672051434804247115671234165554866250 -7 0 2357522259 7161767058949017099878914865276428656140803410121303472828348964010993951134 -7 2357522259 0 17232102879363528163831053837133279694873862968167205663516913745954523542259 -7 367014217626 367014217626 11040718564378049684510775315161888795571845431358249400828565305361265683157 -7 0 367014217626 12705744419040819622496664482061708950519778686113412322239060611017889317034 -7 367014217626 0 9611845218064166460729681155462332234506067016904660014351075628487230890721 -7 688260227335 688260227335 9512179666691432475143714639968418137602038741064665906754248954522868309300 -7 0 688260227335 2518179087967000688836074566963233729625923982434310009619189086506545959893 -7 688260227335 0 2539811799156992653235701874599293619686344127635202233963374169657403700500 -7 1004366944697 1004366944697 4850689725079295338462818442381927388321874470928551480716425284157435046734 -7 0 1004366944697 20447459919609205336175193112727876689314053240747897172815135505062973177095 -7 1004366944697 0 7372342250003067293321430056131084604326163944137328287547735815822240430767 -7 475419781036 475419781036 5257652089381645879129663152386390634065356344262825973904455967266337185222 -7 0 475419781036 794184745169763292790175318337919000963805675462347641978396299398055146118 -7 475419781036 0 8594815704178115975164699711479838728420956696197662075627463211049348630441 -7 266992368920 266992368920 6568973971285484864004710152475359034998635937938515645560093660519782228528 -7 0 266992368920 9767589041715191048261486138471537994619987395789627392447450656967250828250 -7 266992368920 0 6171118170174993069135806366310975297924084185581951026743323313595140575195 -7 883428569608 883428569608 10779233241447206331759254223118564789457500530979280557174900765592936071141 -7 0 883428569608 5500213097682541935449873682421771420007368054050177971247495094156825099540 -7 883428569608 0 7235352729329387586187922696113858436435913826883516277103953927745897489884 -7 268105795784720 268105795784720 953572357579253560624347297912132243163193799000164989807089196497645654485 -7 0 268105795784720 6166749164349150955784242841439930875221506920642393730317118232377323511966 -7 268105795784720 0 13890512617732097010212303285178804554156594872316610314065609413359816262857 -7 276528779969561 276528779969561 6297458196210601087322561304892251303141252889606850562128341990002124800437 -7 0 276528779969561 19211391068468388001796817126993237287876665821530933156192942518083158642392 -7 276528779969561 0 16897429954011971558167603657676409696428198280693617531598940368747778428620 -7 238495654056882 238495654056882 1633517828153388764820053045861317928973633002595076301036627599783722421385 -7 0 238495654056882 21115288378223996298169827477329531886819872791780094324971072564108545362886 -7 238495654056882 0 13382578131024356977166444018550270272556196585063928435759887605935395562591 -7 61988763516470 61988763516470 8730957831339229353465758293553312728527807288803050135583280252829176876301 -7 0 61988763516470 20815960903454562768991083885665716236441168678421019514718090607518033899484 -7 61988763516470 0 19943942532059234572917188610905600548718093613959366290970213942642530634790 -7 170860374887067 170860374887067 13912981796002009907483362495738476474422966517476439113986481274557508020110 -7 0 170860374887067 1649459314329257023860510360063626400126175928342119905462926181529590016416 -7 170860374887067 0 16243866934063127209744632671553697993880424415366487146507221184325865337513 -7 252731016750072 252731016750072 3288059636608095301116739125650616739885379710412925374623297584966038510560 -7 0 252731016750072 8843182132622008013602049994768974853977616890774972124105037958298242532550 -7 252731016750072 0 18626474193476762683608815176714564347833607418155104937773242912613261480320 -7 15131623571808088 15131623571808088 8346751259402906423525881768947606984955379080055922371168830490485659733210 -7 0 15131623571808088 8731667245947012493899066082321713819260955077422173220423890860433344085351 -7 15131623571808088 0 13172740582602362885864106040578843086355657305680304409103459874569504288548 -7 68342017051396278 68342017051396278 16310333061944106723399147024004088226456079072951702846339060261125992275110 -7 0 68342017051396278 18868670911261502728247273249855504974550291550155257741181917218953430123994 -7 68342017051396278 0 12904985628784858024173780200188642662798017474228702476001116887545498882201 -7 32758087064994775 32758087064994775 13259703148918042119698802603618070699487945216402563189127605586385803324037 -7 0 32758087064994775 4586555163239587541376728567544855216353737659515790204561931071973398014878 -7 32758087064994775 0 16638789004490201783697929278299570987429274640023141275507844503323888958607 -7 10290459809007179 10290459809007179 3476794936137336337932247403302897288920583785759903551440891366437036246546 -7 0 10290459809007179 18024121996151168718536614151051204346807785125227363379614764692275518695842 -7 10290459809007179 0 14351482996551415551684294704763794846822291507734210629469236162389574709383 -7 33852059636762458 33852059636762458 15156085759491157105785346047309330948529090988207135097353414057974912011143 -7 0 33852059636762458 8754289345015037063056382851556044590508116440463990266364195465810052635370 -7 33852059636762458 0 18269060255287520498228147060448327506605645082969704184539774341110461553821 -7 67024306002247360 67024306002247360 19176787189173498880416039065668908402710765051992917820153575226674236656914 -7 0 67024306002247360 1425890399318643841943447449718101776141584185470403017410463227225388708419 -7 67024306002247360 0 17261235297700275573029206124075958703412345561107594321674769385609809792195 -7 7697877582092852093 7697877582092852093 16017199000027041144702484850160793285784427845903097077033760083155223397442 -7 0 7697877582092852093 12250929944509244738437073597881620989537814270837586260086726576340050913358 -7 7697877582092852093 0 12731114758347912383188202347809448671672265455792752711750218218295277485150 -7 5975307584912439288 5975307584912439288 19660768676014473734910480790428933403015047987691644334411089068984296025273 -7 0 5975307584912439288 1024454748907598085640700997917712959093573322102023535187573207813606335625 -7 5975307584912439288 0 15016722149176515754254174633149330450726035267301087605350618385533070943854 -7 216413252971977072 216413252971977072 14129009540298939436553771862006407919427194266650028285474452043143635855602 -7 0 216413252971977072 6746746812024532478879323266293476364049588182182280287878660067435011957888 -7 216413252971977072 0 19509946104924111201533592646704741406989125054923285277498314801657531418109 -7 10118058039965178865 10118058039965178865 4961667750818317362613906480098144764865940952200841314417231566144388604547 -7 0 10118058039965178865 16456984820563072751418216506499409546021186437638075412155118429554757975271 -7 10118058039965178865 0 20310129503672875530840712791862096664732124716917467116857147363484101509977 -7 3398253591082185807 3398253591082185807 2866585678043681191801418047708843065748586221094318643123160009245649472315 -7 0 3398253591082185807 19235927092608872095598545632476642898799424689241872933650214437499050968480 -7 3398253591082185807 0 14731784191271969072023936623165640714725669494245982509338785261542590191182 -7 11816181387475277392 11816181387475277392 7507529811560891383119833269038363327870570578300943828629406616533906064971 -7 0 11816181387475277392 21583505949887346001928358348988407677862316822993175928085054591278009663494 -7 11816181387475277392 0 7529119780146250030817507375389314670692812778068344329325327717955912298983 -7 850325821179457636044 850325821179457636044 1810934949645347982857117114274851991906717479024581945008445297615974509467 -7 0 850325821179457636044 9133396776029133734010109462478603885777182998223486764200272014317767115609 -7 850325821179457636044 0 7151808909718888274829190260613894663353011001581754389005877942526288641889 -7 2696714211671326766495 2696714211671326766495 10855232832375676942136011201785869216450911537180125020015308175360576088484 -7 0 2696714211671326766495 17790646145250396999648098771641462707337869198290695053954476998562917838151 -7 2696714211671326766495 0 17368303818363144771123728148909988510528733986244676528736227834362679429867 -7 3210962441719726621752 3210962441719726621752 14900097616518782875704097170938702869793742674415649566588236720149534569719 -7 0 3210962441719726621752 2945026408625255433440383280416843682705066498507862319872696515019652593781 -7 3210962441719726621752 0 6492307898805461080585477962899391985964046654324295903148697422852076714577 -7 3643349156370341308485 3643349156370341308485 12218285618184670730139921094228351189193611375280589667911788701465231637468 -7 0 3643349156370341308485 6610013964778931715220097361790225173998769867019254678370862841583285111628 -7 3643349156370341308485 0 20993880848267768244689381975724224760195594402433742166826128532968177870747 -7 714398887623897303953 714398887623897303953 1947890037324317436105541480419926105573119744057338112654908531834622744303 -7 0 714398887623897303953 9250171830868995487101008998160323633299774277136146488375042035116487263760 -7 714398887623897303953 0 20710658857184460646105804329176325617873425672701563990962221822942852897755 -7 4155381412326020807079 4155381412326020807079 13747017189617435028454063980158222819917240053654544692967921939546530073551 -7 0 4155381412326020807079 5067116292666091337471076820708060612541130944690188914532717977374699426603 -7 4155381412326020807079 0 4693378272036878719624722412815669276301458585162792046960432756832956911676 -7 911327320967728747144055 911327320967728747144055 20890475546133535493049381170744919034977167707029807111350237750083984579527 -7 0 911327320967728747144055 7155555996640880755215437445834712984526144188625049622385823685862144983783 -7 911327320967728747144055 0 1629498579531074390096571700970054704019745742130253789244583389629272086542 -7 467263245370211100115855 467263245370211100115855 633018334186307844286976316388552866794705518340009163695633585415378543375 -7 0 467263245370211100115855 19144959015006621801562529972280523004149890876706152217119969724975388673418 -7 467263245370211100115855 0 4030266559249132954261912046040649101537063754129079100863670388803473990855 -7 655808701419179759572087 655808701419179759572087 15193662725799774406202633805967050193629118262548548313806561749300356412963 -7 0 655808701419179759572087 14174948084259026336263790593374764560472578317961854015920898507642685724948 -7 655808701419179759572087 0 21154637956515810300764167226442792210299244203689356223641877317007260338717 -7 881827210254710265650471 881827210254710265650471 5946648105609758166090565372717489104515861507163037074924629038554233944000 -7 0 881827210254710265650471 20264671080413214380050871233990845452238027730276365246834635045525178138553 -7 881827210254710265650471 0 5356570618825672294988222157811187715998020544943875753326413389475921621451 -7 1179345910946959076869363 1179345910946959076869363 9045714891022482295454414266854061374758275668898447462769564857730596708063 -7 0 1179345910946959076869363 566973038521198259975502647366313546247017164605900696749494632684398291912 -7 1179345910946959076869363 0 12350075266268428754580121954722167497555076228633847814135211948747070565444 -7 745595805947126835550922 745595805947126835550922 3390362717033749549800649594815874014208862412275592160946789713302092601377 -7 0 745595805947126835550922 20943612862447941260669509413388471165876673526077028656047808340008515494889 -7 745595805947126835550922 0 7205482901279616356635595091178559072059299003147038524686575821549263317738 -7 218045160747297365344236945 218045160747297365344236945 18154678298888134414332932070096509701801471380633054728068421440170005416380 -7 0 218045160747297365344236945 6448616951396927953642081304912276570150009084713717833456898385997359721426 -7 218045160747297365344236945 0 11755288913732347532600959281209990091851505193717681770431602230716897648006 -7 24522045935225286884884345 24522045935225286884884345 21008677376444730118469263120067425715104086844365455461318570898405493182762 -7 0 24522045935225286884884345 13611779439312328288823718815644118333982567820399207684170324761792752806474 -7 24522045935225286884884345 0 4138282441979988188255606662300966558557420101481335246476698922432148538027 -7 97890126453504581864170179 97890126453504581864170179 21342058337668672458619576742180773422104657867759526349240079019705905044925 -7 0 97890126453504581864170179 17418634697718841974418272439827866846339028308480592282270450839970210554914 -7 97890126453504581864170179 0 8406607281004358897383918507623266931645617140926177886799794177548111490158 -7 50931854333844930685489516 50931854333844930685489516 10024812569768923964667013717870803806712121414300824872650425768557722833570 -7 0 50931854333844930685489516 11722152073847885618958837371805572028356567605577953180114045716459743149754 -7 50931854333844930685489516 0 1706097638807749343442280561581206849922779591543343120319751939240126781058 -7 171559591456638013403638072 171559591456638013403638072 10746523416739685081471157955280879357728883314917230403523492742344351244018 -7 0 171559591456638013403638072 7513231523613194936135795762400901688956987970323783693656840961313957445977 -7 171559591456638013403638072 0 504183159896349979507213746083753423317922424654815331755546738677974361980 -7 6526009484058238909748655 6526009484058238909748655 5383668383545033275260133552900905794633559411112692979930910001662766692405 -7 0 6526009484058238909748655 17581643436020787108678110972170069674763939832585831509293646153468970693257 -7 6526009484058238909748655 0 2005826955808608105357594688138694252608835367216082196258651601254349791782 -7 12061923421319134047835817581 12061923421319134047835817581 1302802504045219209824135509047200441011902376057841118145209338375376503020 -7 0 12061923421319134047835817581 11768462971473265115043353542342495473621419773758724801012744277159997679187 -7 12061923421319134047835817581 0 9492716649293500053945980958431346785580193666634182857185951649397210785600 -7 79070805016387524901754510580 79070805016387524901754510580 10635032621931071429484041980958209262991511519885635925995971772161803665478 -7 0 79070805016387524901754510580 7969302250629248793658141602849697155831519655715412962963666059265601019156 -7 79070805016387524901754510580 0 11012698933324701291027626065736203005374535929907279271293023768239814608819 -7 61472585212647853537800001482 61472585212647853537800001482 5746369103013087051523185800323320571250789124261252451924587250888373011891 -7 0 61472585212647853537800001482 2795753558002648120066416989654041730243712742657079037391421975593713953123 -7 61472585212647853537800001482 0 1055642277915257165422842459064501139787969943794841353826955655421369581226 -7 61955482337934879172876116398 61955482337934879172876116398 16966133839960711799786667549242945241270780151358407614056353909162372339191 -7 0 61955482337934879172876116398 12032180790851391011873886991486299808706105674787352733570040701008081488605 -7 61955482337934879172876116398 0 14729411391718905525084476138800675046983446328076909184186859727805848017668 -7 7465023689022957439423768298 7465023689022957439423768298 1911506379704135985816289952354450030570687907032677271718575401136789017766 -7 0 7465023689022957439423768298 3157462528397357850522930094933941863032451637722690434806392603537547646671 -7 7465023689022957439423768298 0 8618452690342327196977883085727400989587397620483366622450361452024620221061 -7 56183431555817343915384150830 56183431555817343915384150830 13904998746874912568477424714122721272195801301911132763604253474247778523714 -7 0 56183431555817343915384150830 2712287335426548843440309213758022515541973134224854195863613359670138159891 -7 56183431555817343915384150830 0 9699039466412801863927137584892216150897024488877269855185533628403974767285 -7 11769744061594084440604515640355 11769744061594084440604515640355 17138355651884258593953784438868917934134993230646688018621673200383621231559 -7 0 11769744061594084440604515640355 21663566486324301550592824008096280679617307702985857904044395376713992365455 -7 11769744061594084440604515640355 0 163673036086048352150123025425169606966272295408291729768857056410925782096 -7 1959958078535868962721082190998 1959958078535868962721082190998 7808447674130004806126241281800275298724008015659828727294940605182687157015 -7 0 1959958078535868962721082190998 17947308648050599518141926616816311104521969502567575867307937920590534543548 -7 1959958078535868962721082190998 0 10676032156705526183824542663223157002680349693364409226714151156765869349959 -7 12232061141953593371921163503642 12232061141953593371921163503642 8958516657041031468950004222766813033935645272304200345256007684244149234133 -7 0 12232061141953593371921163503642 9515795738063628156729412480584542912808309132569388185277603124172325928438 -7 12232061141953593371921163503642 0 19434324445679897497863240438199360686970583665723673324820104377293965941114 -7 19960988147769851237222055447697 19960988147769851237222055447697 19516740004090641609373921843123905484823403526929251265096392886774336637338 -7 0 19960988147769851237222055447697 13697452656393352217954974033165859232205008633736434844981419475384106588191 -7 19960988147769851237222055447697 0 15383170821032983185322845064689044961685283943032523951626034625678116597607 -7 836903819861062467690819924272 836903819861062467690819924272 9264600368169122528698083189111758794834930183476516533097388431374349807586 -7 0 836903819861062467690819924272 2127615654889747625164555557314801557026223065829531870236701540895759065596 -7 836903819861062467690819924272 0 17183152315309836362311149245518712801936484735383307832475824257601832965619 -7 384319725957180300992859010706 384319725957180300992859010706 9264548776632015135876585721834228125363068855432875409145884336117153743933 -7 0 384319725957180300992859010706 8023153217202240953151181861336309347313476997930591287083863314461786044903 -7 384319725957180300992859010706 0 3880454614671360858592263427255855869697199829135665891826545474760684264614 -7 1932475943339967312129793763190817 1932475943339967312129793763190817 18031841505932144068315041289416869498819269873348731695053724440232826349806 -7 0 1932475943339967312129793763190817 18951640515495808138699058294432053299219102574645360738797426973147817291000 -7 1932475943339967312129793763190817 0 11273533787853413784326715785801155870529981362076302376934367636031466361471 -7 610439696815129482695774739209587 610439696815129482695774739209587 21294576649980853239316341479145925453873844276157349301523860159749435746575 -7 0 610439696815129482695774739209587 11867355915414792604894144304678368690863145804891021100906826506405852700692 -7 610439696815129482695774739209587 0 7388903020180474081431550211427630828172749120805926581629028883579546553691 -7 3787149410712295177878792169857892 3787149410712295177878792169857892 12668091136672104633775177326050815905283302892999902178300156090916303891325 -7 0 3787149410712295177878792169857892 7667372633411171783210455684663982990403479556626182864009420804965569090237 -7 3787149410712295177878792169857892 0 3825300170002551027739524563896996780253131778513081610938340384613925688429 -7 423949996454357483389660951725799 423949996454357483389660951725799 10265753970846521636452659989703739895064201472389772711478976956761709582284 -7 0 423949996454357483389660951725799 4709828461631159008970927381524478381998434058296323392519532322355100852901 -7 423949996454357483389660951725799 0 20187101404773777930994828998300448734024869332109704776615157475946575316020 -7 2920364823816801855046905974856322 2920364823816801855046905974856322 14707182831941364812047434190495547323184693981725641193310288664646738449895 -7 0 2920364823816801855046905974856322 676153090815432607712344049947303561973435916649767306761427328890635431047 -7 2920364823816801855046905974856322 0 20111409278560070705135944394734409831499157736307590335931126916740506123223 -7 4605609385664024730646690906940561 4605609385664024730646690906940561 18625228461930294447298053619323440529215628829049837754298570611668421084979 -7 0 4605609385664024730646690906940561 21181363599252524061682848164304559027011046743681814369927547111255773478753 -7 4605609385664024730646690906940561 0 19973069730874702546993080433193816018100943604668133094064662149503294027397 -7 653839462055493951241793095237800201 653839462055493951241793095237800201 9569987927778967031826284767088733837810187210831455802315659451842622923705 -7 0 653839462055493951241793095237800201 16515390426982164471539613868438272078494413327415859178481369096870428734761 -7 653839462055493951241793095237800201 0 10424062811553458032586522867760562550658817924390384155058873489751798783736 -7 666652131310030688057848245753204302 666652131310030688057848245753204302 5444904335324781665124783854434993372948012785502525181789583624333354961091 -7 0 666652131310030688057848245753204302 1460073014411137101305349667725571557986657098658789925078633781426402099755 -7 666652131310030688057848245753204302 0 8900423460954792121501984087202659724348351011244717906306864619476100407289 -7 1192350435342999182930464330615118438 1192350435342999182930464330615118438 18363856355067307976252527989552520018322852212900539975388583966692532671985 -7 0 1192350435342999182930464330615118438 10615128446566974569747786760576506100398101305667084815179158454490713628821 -7 1192350435342999182930464330615118438 0 7538247263591261820330622213701499681075750962970302110923821864484947294732 -7 364440556429458984901083262324218134 364440556429458984901083262324218134 21170497669340251793943226279094514418106578300873715183381715423170678220286 -7 0 364440556429458984901083262324218134 11534013076762365885666601294288143874067922109107615020159082874355673155454 -7 364440556429458984901083262324218134 0 4649917414621955998585795869876138327887207534541179799869121497157357746216 -7 773366488443620292022834639398137000 773366488443620292022834639398137000 2648277399766832187689033149803409792142037820699146553202119365614839422538 -7 0 773366488443620292022834639398137000 9996669420312159726253197271511432164765472164232943315007307670280889559713 -7 773366488443620292022834639398137000 0 4938851597037254182562280436463987545740518254444761349788584577557120593928 -7 1125844340888105386198157359361893269 1125844340888105386198157359361893269 19592848618130130196035076363341623565413939957786258440720631407172550020171 -7 0 1125844340888105386198157359361893269 20807898790249817780610458542826929221554060137644547960065680127980719464458 -7 1125844340888105386198157359361893269 0 16119393160459571808059675364311983803361980443416803772533647633553889684811 -7 336777852013281045953173947904746055564 336777852013281045953173947904746055564 17076284137460955125112496228581583659493415756937360563530221729666039457747 -7 0 336777852013281045953173947904746055564 6348852028130800944962601243490502783794349615458168415815370710896185182046 -7 336777852013281045953173947904746055564 0 18000797727285704865834797296493827636282667635240129357695835492846059272672 -7 136672384301875357812815697444352391864 136672384301875357812815697444352391864 18511047139730020717604776011963131061963127147632084674991837514958313477929 -7 0 136672384301875357812815697444352391864 18775542053006037171658517613648433536014425390837985554814525391354707974537 -7 136672384301875357812815697444352391864 0 19135135109256131751951075672065504489038939955707133184967752380263105513957 -7 74096832595191725222360602651747320764 74096832595191725222360602651747320764 15062072335821993794419746324379761301960783263802012336992468574511745511513 -7 0 74096832595191725222360602651747320764 17853662436260044943951641256377083771550916055250145054197035694793026079322 -7 74096832595191725222360602651747320764 0 5929934995004943846168304493398435142179979677851691693860778480816231143743 -7 303545207801252939054913100229146912298 303545207801252939054913100229146912298 1216017676662556145094930636106084222497128689606911392390654012671832727391 -7 0 303545207801252939054913100229146912298 2029461504776659573447305146333387978480216099762145629033184781715078778863 -7 303545207801252939054913100229146912298 0 13919068763680025710312696615306636051901888221271867326680512351704835073212 -7 78150906523588029665601061113619682175 78150906523588029665601061113619682175 1381264062005659361614371727044797180831444513438664013479203524482848366023 -7 0 78150906523588029665601061113619682175 20761494002814374101983833959655057982089082780587454600257761237708260298550 -7 78150906523588029665601061113619682175 0 3082581663713118877610034942548422456433831498306222983148045865351432629821 -7 306228989724981450180225344978560285690 306228989724981450180225344978560285690 20078078255504846156822904264105708583786047414583470661766428971789663177902 -7 0 306228989724981450180225344978560285690 9147803222301189826497534844715231841829747748939038840849890845154110991604 -7 306228989724981450180225344978560285690 0 18669124461876335364540910046875806102486306847880120945907763673632620441762 -7 80220964956923768546511561974942420978646 80220964956923768546511561974942420978646 11734917038390699785862331356963464072593019938085932375042574985142072566946 -7 0 80220964956923768546511561974942420978646 14502646061583219349067830077892984130590676541521248503098668649377467930903 -7 80220964956923768546511561974942420978646 0 207480467498562694786828810585956091522316912263959826990617579116914707221 -7 83114820859383843424716870542574437838881 83114820859383843424716870542574437838881 6491842521156864330438157350678957136867926940887131046023651645778685404432 -7 0 83114820859383843424716870542574437838881 4688842135982343099013001021833345386475776647409638471358463827287896451765 -7 83114820859383843424716870542574437838881 0 15571322701941329724363901745628422112547071242837864516665860731178037149404 -7 12677779678950859762755739149228220057426 12677779678950859762755739149228220057426 4746467882279956064509101249048768832441996085430396455202739455314820467055 -7 0 12677779678950859762755739149228220057426 8910603723699473625308464559756529753692149035987543713255221468332082350957 -7 12677779678950859762755739149228220057426 0 4772647089753514694245416800176633083171176496618392242438109247310587023539 -7 66361730564944866742624675210803105089120 66361730564944866742624675210803105089120 3954040981196929478071863595357602392465924710055557472769887069865395208320 -7 0 66361730564944866742624675210803105089120 5958297458484905859684856168531573790543035475992573141380545046617293772299 -7 66361730564944866742624675210803105089120 0 5508744720472769501136518219199672090058287017788139491029575423441417641738 -7 54785003186029088736126697012467624542500 54785003186029088736126697012467624542500 15604404239223554489805845645791820857188926738970119517325252455008474526553 -7 0 54785003186029088736126697012467624542500 13549672323304951726193757444810077202886921121040402410199927806949263758153 -7 54785003186029088736126697012467624542500 0 16986487793384829684565420351541703923860196871187541890939139987419478192924 -7 77675752274509501985761251130117903670260 77675752274509501985761251130117903670260 5585668392600860439518041631286741386760461970739975616853604152200889918322 -7 0 77675752274509501985761251130117903670260 20137908424372548619779398484303530845510824766881663744263324648609049483619 -7 77675752274509501985761251130117903670260 0 12122042647526686112360757057255142799525043249112618410362678713888955155956 -7 14559285341304636926758293787085554773261874 14559285341304636926758293787085554773261874 7031171866300484727390257743248652085789251779588511609883568027676197178096 -7 0 14559285341304636926758293787085554773261874 11115697702607548266423107004050970975539193359615537725089728788485294990452 -7 14559285341304636926758293787085554773261874 0 1027444010738443777926643843740382920029029390130760623907003171750368917152 -7 18820494380150631875759105472470815557645141 18820494380150631875759105472470815557645141 21414889370854318813762550202931222452583030087526621478441197873145393263317 -7 0 18820494380150631875759105472470815557645141 4181104772639808555088344869604134059224692352248208718594162599918455457010 -7 18820494380150631875759105472470815557645141 0 5615971192445727763242425315778230549091074806525054521840917442370995618999 -7 6149796273693798202443248169272226654630857 6149796273693798202443248169272226654630857 15490725342186756675716527706635519020196974946137482910061446865866753632910 -7 0 6149796273693798202443248169272226654630857 20507435382115056835137370931321482769938717712210606337082294413221375231372 -7 6149796273693798202443248169272226654630857 0 18309904409745781467526097547141395677233836366579400894273177809357516973248 -7 2547524368453373120125395586564263390260278 2547524368453373120125395586564263390260278 5637827685325284172830286699795527337622746028604414198476620094006246382270 -7 0 2547524368453373120125395586564263390260278 16936310212740378301503111302630592276839385308342211835513964259397894552770 -7 2547524368453373120125395586564263390260278 0 10489859967333847081169196430135748448306744664229014938995520548654706413000 -7 21952129252755735065037778684681780866715277 21952129252755735065037778684681780866715277 4031187428833372322025266429421699725062744517840909466268201507068174530409 -7 0 21952129252755735065037778684681780866715277 1421443181902385562772338940619468336212343635292474579787521958589956023499 -7 21952129252755735065037778684681780866715277 0 8948150059361468893957005441906617443093318540508854626314024772094768879403 -7 8380302287207060269812091071571863722099559 8380302287207060269812091071571863722099559 3890111933307584146850175150758974096819204010471974098015307476563790425492 -7 0 8380302287207060269812091071571863722099559 20261926376262906512932341077420376815208535142345188969797300461995501125253 -7 8380302287207060269812091071571863722099559 0 17126086955566537109870725539830967579514742128928073454342516651549178670962 -7 3530626645970210560010173045880777604300997701 3530626645970210560010173045880777604300997701 3281534994821398752538458286027478385525684113961664017890138559413144274316 -7 0 3530626645970210560010173045880777604300997701 936570016963913088039854824783797082746839480928944133876851327734853402761 -7 3530626645970210560010173045880777604300997701 0 9672785538773090105278367099804206206099633908167291425859400389847603365478 -7 4181765743007741806407141951059598011198121997 4181765743007741806407141951059598011198121997 1249025842961523087958757478114103792851807414874717455820565217852471878759 -7 0 4181765743007741806407141951059598011198121997 20455827160151358371294392114765394450322634030382806255175658940108419550698 -7 4181765743007741806407141951059598011198121997 0 1224196702107578276790275954723178482173355441480676991238073111282089783993 -7 2878549595822803610761344142643107794132464232 2878549595822803610761344142643107794132464232 349303146593160788014641149695957342018168329381407966428069019796522927091 -7 0 2878549595822803610761344142643107794132464232 6868962717077785916481113074928945331688677599277359873817569052439043955680 -7 2878549595822803610761344142643107794132464232 0 17786185275880785242000021056441794713976491680551039115452386317633221318926 -7 3912253615592984659548099740425676571057027410 3912253615592984659548099740425676571057027410 7589689713732511668140882374426663173824966542090818745902477366171487032251 -7 0 3912253615592984659548099740425676571057027410 20425884119737888375537163836140789082983581983041166148127914044594160235204 -7 3912253615592984659548099740425676571057027410 0 7494320822969028507965789703136500313589266466018083334921948822469347064096 -7 2449684460370649100702255039789615462477778616 2449684460370649100702255039789615462477778616 2855596619330039254128048979881647988329782474853635916210039128194038458607 -7 0 2449684460370649100702255039789615462477778616 14752503645363477335666223345333929350071004822240529451102303135999402080912 -7 2449684460370649100702255039789615462477778616 0 2293985257887516270785611461806372401657591347974693242864842655773274848794 -7 3936161308768608900908885495753546914373906329 3936161308768608900908885495753546914373906329 13512725144915191187762489449963452944442058375241994524032115731832426888872 -7 0 3936161308768608900908885495753546914373906329 20900589836216995876725458484133806921647419203636380618445039992505182901043 -7 3936161308768608900908885495753546914373906329 0 12384811682453449288378469937690619032264087515831521477896452637241841340211 -7 1314026903421240177218054411556991432988596183301 1314026903421240177218054411556991432988596183301 12486050962155233462744004233398446381708747173272804991212455725249829418989 -7 0 1314026903421240177218054411556991432988596183301 1580691663822969388936597546406869050636037456047606515762999280756146937886 -7 1314026903421240177218054411556991432988596183301 0 19071422650406750930557057360761681087765132233290394384644132889417003198357 -7 227837593837987129606941529416786612111127225544 227837593837987129606941529416786612111127225544 5421778255630300545724903444057847405678329387132661980428854730233471986919 -7 0 227837593837987129606941529416786612111127225544 12864098895677123969305375950148206122811366483045317961771387858483359236825 -7 227837593837987129606941529416786612111127225544 0 21340878580315606616320796067335746368014431444672718380145402339784059790152 -7 889974949056360359395658763633643269189042108464 889974949056360359395658763633643269189042108464 5304126368469391130432269883811987314806419741160612977563571734237969765638 -7 0 889974949056360359395658763633643269189042108464 10907191013498905391045984602694711962355306244340819179745784868148538227487 -7 889974949056360359395658763633643269189042108464 0 1665262641772048410139990021592106762849978612363778138568674658224300085421 -7 38153598881835967574629407513077522949850516365 38153598881835967574629407513077522949850516365 4608420777010931735341581337840278158501340037111433283934036351022624797067 -7 0 38153598881835967574629407513077522949850516365 230793395624911080182684350756166640691292041137842834702057816986689459331 -7 38153598881835967574629407513077522949850516365 0 1430454472490737867004164518848975745465852663875753909381257934069777942551 -7 1434893756014855990246071623088496493038523079615 1434893756014855990246071623088496493038523079615 15638653277339556312179417048242054260959383890934888920055816573365656753739 -7 0 1434893756014855990246071623088496493038523079615 2849432529398845400073776820855720429429048449082158361361113637806568441584 -7 1434893756014855990246071623088496493038523079615 0 13669696091945013325484462916973963925507729440553933540327755443449326246398 -7 1379705398060529471004162824082325091786876614434 1379705398060529471004162824082325091786876614434 3442207917519851831761616386426543469736183170542061913879559419137719823766 -7 0 1379705398060529471004162824082325091786876614434 19036909613229178338806340013253541428818189288178359977178544152596398309292 -7 1379705398060529471004162824082325091786876614434 0 21014205316224245185251266973381321190866057471916881889598309378726119940063 -7 126728268110396424903936561391870702270068656618385 126728268110396424903936561391870702270068656618385 15463531189827708447405973960081192932044141850032653836073940071650600517686 -7 0 126728268110396424903936561391870702270068656618385 12239135004552754048478297042954515739405136646199427594876218979633297116383 -7 126728268110396424903936561391870702270068656618385 0 16605223173457035360135575194838125209009892616905893175253542440881545946441 -7 135847959316337713875080304453649776579211134352801 135847959316337713875080304453649776579211134352801 14742571641506562725997383800695033219738618788769275951289549891105938709520 -7 0 135847959316337713875080304453649776579211134352801 19517299429412615595209846559345214682697075979909008315204156724215725678311 -7 135847959316337713875080304453649776579211134352801 0 7720822423492660801522763826209893674031735393863579108455783093400332755516 -7 343210389400620850128734241964197438365066535361364 343210389400620850128734241964197438365066535361364 8453199563338682209813510357062308832663868193259988952393295466285136102984 -7 0 343210389400620850128734241964197438365066535361364 9406293179439781274342822776008387643900471482945578492475452445778201212476 -7 343210389400620850128734241964197438365066535361364 0 12396861514824825849945254251730079580212108666909309754493133236092539444765 -7 249094987265047502574019562144644258488514356394152 249094987265047502574019562144644258488514356394152 14324241285621365667218648256324766395458047669317877455065713323685432616158 -7 0 249094987265047502574019562144644258488514356394152 5998798936375208960289788517850376566530235957562113399119182346837175830796 -7 249094987265047502574019562144644258488514356394152 0 17055503463200757328576404445952710039579937368769301428126231516906614170163 -7 179701302212406085969378994254321104305849480006512 179701302212406085969378994254321104305849480006512 12549623987421327997630362873670323044480702755727634292368311039292223916898 -7 0 179701302212406085969378994254321104305849480006512 17614844094663528840098989498914726233649569136654478048759035557521595015945 -7 179701302212406085969378994254321104305849480006512 0 13384983989128466222959066622007213952240924423303670886887759956367895183233 -7 213635611527811835084917546952121277048883657425941 213635611527811835084917546952121277048883657425941 19150531119815173333627286298840347110171518061611081473124925205413460202995 -7 0 213635611527811835084917546952121277048883657425941 911913226658128297422608861286732085725097865749593389403309073977521754975 -7 213635611527811835084917546952121277048883657425941 0 19245340711725556835968585643876108084173163428656941064482571326811360539182 -7 73296190539720074645892389997094505176564967199428304 73296190539720074645892389997094505176564967199428304 12233102472366966662490036904454561210722284904478346601881913294958164759406 -7 0 73296190539720074645892389997094505176564967199428304 15515420136332042572892173371838221475001542371637881634173697968888358037245 -7 73296190539720074645892389997094505176564967199428304 0 13263581283881992057241846004932976342728398589567896899951651305882469778129 -7 73443204751576137996666238736118219317384293842168887 73443204751576137996666238736118219317384293842168887 8035312752357380069004995363703036131151938995865412386216494376384186651673 -7 0 73443204751576137996666238736118219317384293842168887 14009155283798014183740064911407008195501954439942522771804830355225330012264 -7 73443204751576137996666238736118219317384293842168887 0 18183550898257050822835203011296782852364874875499029801733987439078444855600 -7 75346141797110845751499798607377671395550379587852787 75346141797110845751499798607377671395550379587852787 9599766123338477879059333997840768903452766866635813166737455886624095899697 -7 0 75346141797110845751499798607377671395550379587852787 2962616518331349691261648286597041547446608145264425679601375958811875299171 -7 75346141797110845751499798607377671395550379587852787 0 9447619049181019230493503968352947304194894842979290909790675932631127054138 -7 60471697093024325423309714208221210863756311378395733 60471697093024325423309714208221210863756311378395733 17348571902168880471511602233167687740727475248801058843207369968462591870612 -7 0 60471697093024325423309714208221210863756311378395733 13295533785265422358028514784270742253129124531079379146401885525483766825770 -7 60471697093024325423309714208221210863756311378395733 0 3794584065000485957462096712645111109888388997632843568402689709416553002378 -7 36778681574647414811885506899920601904220321426739615 36778681574647414811885506899920601904220321426739615 9387797632806525675436447580805775897406345294984609268214698994241417916018 -7 0 36778681574647414811885506899920601904220321426739615 14647815764764316589561023729138019474786343831762854909495915671904528249187 -7 36778681574647414811885506899920601904220321426739615 0 14207823044771008727150636651539822211108135611559024237714163199235481193528 -7 74341461027885224754932959824435427322423132583118384 74341461027885224754932959824435427322423132583118384 880465614411063189850154408036737629177024327809757605666371184131910776138 -7 0 74341461027885224754932959824435427322423132583118384 11600957954759362716423833259075512168148633725087951683030250149451166679694 -7 74341461027885224754932959824435427322423132583118384 0 138866565562433155360643872441317003002683943726073056999553294714318238232 -7 7695385699779130713497316032948858712104664779302187232 7695385699779130713497316032948858712104664779302187232 10115680038057183907243812654147838291263571122669248856918544295434879077996 -7 0 7695385699779130713497316032948858712104664779302187232 10541920562929644148407287117731118635950459663320066824518848997286950463574 -7 7695385699779130713497316032948858712104664779302187232 0 9476561245828397265477540460738445757061385267799836527460490822266330391737 -7 22769408045522038699946595093145906985103566531853678864 22769408045522038699946595093145906985103566531853678864 13546215693878164449079924096993611109214083172272520232760187687059786609592 -7 0 22769408045522038699946595093145906985103566531853678864 17673131758233210152551789819665353833129451550397773721269546300507704226177 -7 22769408045522038699946595093145906985103566531853678864 0 10403066839774261434409357707173922086412773601410916458669427623695207600174 -7 6888021322063264915588465093169606684392106173354408411 6888021322063264915588465093169606684392106173354408411 9745596821438241727935787206021946084148365557946441831690096822857659113606 -7 0 6888021322063264915588465093169606684392106173354408411 3064650484571206551530939099001206977131658957008022279663373445186571865360 -7 6888021322063264915588465093169606684392106173354408411 0 3663881766848095863702366789314011100616064321157070271868762223617597504508 -7 21951794056060737693629887525255151366087219521964486001 21951794056060737693629887525255151366087219521964486001 1805956036758013025643915464926179116529693731545755622883852989219070384789 -7 0 21951794056060737693629887525255151366087219521964486001 6836486116731025890658533636822987105916644203062298612692140549590783221145 -7 21951794056060737693629887525255151366087219521964486001 0 16399317006166553333639878797112717232396693165072586081095849659733507941655 -7 4481839468812829843982546398732157131593816927696954243 4481839468812829843982546398732157131593816927696954243 760388190738781454964921659422102538383413990120583344170981001891509084052 -7 0 4481839468812829843982546398732157131593816927696954243 12087025494238585257517425341495564323203437416296959198596475059283763614189 -7 4481839468812829843982546398732157131593816927696954243 0 1224883317073428354757171465998932032589611847085562315092579552777637220569 -7 703868896556918089428492247531385439597180971220512114 703868896556918089428492247531385439597180971220512114 19000727395560279612142641626379503646932316785457997887813476103339567756483 -7 0 703868896556918089428492247531385439597180971220512114 14366758938507922522414534781390963579463729946671733093907271685866051028379 -7 703868896556918089428492247531385439597180971220512114 0 12061541387141414010987077743590914676451400781786409091457288377611900130244 -7 3697842402077037627406658697214965693694719301115015263477 3697842402077037627406658697214965693694719301115015263477 19410283453110099953574830000760488373438715730407892511032937232843176225138 -7 0 3697842402077037627406658697214965693694719301115015263477 12246367295051549464824510038042523868383177674658906114924436408690424974457 -7 3697842402077037627406658697214965693694719301115015263477 0 6082567702390170501731350930641793719302115940755406452887763240719780289398 -7 3408977889599140561203371406564231369145216481691220834711 3408977889599140561203371406564231369145216481691220834711 4051286150147656759781082085601245994000228810489590032398897871044006578146 -7 0 3408977889599140561203371406564231369145216481691220834711 12727414310055064340090421502917905839956098863589431703327346794775681290317 -7 3408977889599140561203371406564231369145216481691220834711 0 10037599000877407086020511375526358793340754571075220785524604139809263497375 -7 1551674706602778625427900003188357108872225900307679292851 1551674706602778625427900003188357108872225900307679292851 15378742702097444167307471921937709125697707307279722238382931292902276295936 -7 0 1551674706602778625427900003188357108872225900307679292851 15035314978025734390721717454149922380501798047865327099870901392610411471158 -7 1551674706602778625427900003188357108872225900307679292851 0 15370909713202870104814864678542807933662123774516755605800417023140618783582 -7 2824652666497862771454697486721970714677743252036924756997 2824652666497862771454697486721970714677743252036924756997 15071908282891624185856333347638711247571599848433241946418953580622083442819 -7 0 2824652666497862771454697486721970714677743252036924756997 18340221730383864226830987906842055898363967140385977284559471939433745496864 -7 2824652666497862771454697486721970714677743252036924756997 0 13095363524555090526344227224838547170832433014769335342722571557821231899553 -7 123424453877070008201438892350302888041237151801771918252 123424453877070008201438892350302888041237151801771918252 19414822208351213491474032864548257067561414678806441885997920567698138523185 -7 0 123424453877070008201438892350302888041237151801771918252 4083302379503170790231989873883314006492816999606271230091268200665718621832 -7 123424453877070008201438892350302888041237151801771918252 0 9899939594871650873455378488919234272177271324101891924823177977092273545408 -7 5827319206658548511917635024732043045649861679339407262394 5827319206658548511917635024732043045649861679339407262394 19658470906268209988450700037054217610405594784731589142436307733344811841133 -7 0 5827319206658548511917635024732043045649861679339407262394 4990143961900574378657363689892877930673607328018682562339976450908923029047 -7 5827319206658548511917635024732043045649861679339407262394 0 11512772035136083557491070595625003912857214736161643886805897486503384914616 -7 934621944414725634188581240157401963554557110465638601479238 934621944414725634188581240157401963554557110465638601479238 9294122188580598402241753389342129688861755804794215915771987289072799702258 -7 0 934621944414725634188581240157401963554557110465638601479238 4923167010995310271583978038161265435998654987279640230012559911097321009650 -7 934621944414725634188581240157401963554557110465638601479238 0 19516826384655846213186623990567499098263431014270800890692000971828335363655 -7 1547022958903142990986230489894848553312796848975500181692948 1547022958903142990986230489894848553312796848975500181692948 2750634595161451698245560519330183720181422608974850450188405556735803626253 -7 0 1547022958903142990986230489894848553312796848975500181692948 15062484583115566599198512431736749321586485298096978181575205088376981469883 -7 1547022958903142990986230489894848553312796848975500181692948 0 20607919581835078554324581051470948639495369558438655575201351787592089366438 -7 834319305919447894018161867006850474576774935071378519987971 834319305919447894018161867006850474576774935071378519987971 11551078730726226108052686978661002233332575893192554651030622764664353446409 -7 0 834319305919447894018161867006850474576774935071378519987971 5682417706684098194311815220517103444554686080774543814024932862219689102320 -7 834319305919447894018161867006850474576774935071378519987971 0 17402839365135556159536231093077746515934634198268368859333277587142263203233 -7 1423985256945517096383950848322286392569148823865636583131238 1423985256945517096383950848322286392569148823865636583131238 20406237953205315335771325223208081737069010373795139627711743296912204131290 -7 0 1423985256945517096383950848322286392569148823865636583131238 7728725589495302896629712042459230330395090538012123833431077273530057558000 -7 1423985256945517096383950848322286392569148823865636583131238 0 16095189741167082142757396336529784021850756389451889230832021137837833423019 -7 78407278752470882460205057114503019490758026790955614647505 78407278752470882460205057114503019490758026790955614647505 17962432893951597799262279848489608670709287854569134971328573691151348914139 -7 0 78407278752470882460205057114503019490758026790955614647505 5675805654786663263086057556492839514913411419302562120691363972556313073129 -7 78407278752470882460205057114503019490758026790955614647505 0 15319842164380127179424855638653210402805813665036423519442284521418625242437 -7 1356510959043953332610177119199927897890935076806120728123218 1356510959043953332610177119199927897890935076806120728123218 14541997279361440729540949289616751641240354447358790448291966354498995810440 -7 0 1356510959043953332610177119199927897890935076806120728123218 3908142001953388872221689762597918543863723241005499295151849225484829963164 -7 1356510959043953332610177119199927897890935076806120728123218 0 11508447958259043063879242275736742404840784854331776536021889760184403784620 -7 45029946681010977501704472577235929022270187064854559562788025 45029946681010977501704472577235929022270187064854559562788025 12605378031700119547223380785832307009238668353830531150950745216726133356298 -7 0 45029946681010977501704472577235929022270187064854559562788025 19701148620761768995554093170318469842310838939976878285407082129113076165721 -7 45029946681010977501704472577235929022270187064854559562788025 0 10553182681208384387306622106974157893504916374163818256926139312103673461451 -7 71121772000017612837601795185741898103294121514978404279927022 71121772000017612837601795185741898103294121514978404279927022 13056923635744230603431529328109567536138229432685351119056791960736966986566 -7 0 71121772000017612837601795185741898103294121514978404279927022 15948035305600327249969062775469469346778456075017892195205924894417970192726 -7 71121772000017612837601795185741898103294121514978404279927022 0 3123056766797618383642351682793779001099101011746747741947965505111846755234 -7 351701134820991236904165396525910865019894306037934853000663900 351701134820991236904165396525910865019894306037934853000663900 11944160007575776331066387485555265450768035669619247248147091542533884579114 -7 0 351701134820991236904165396525910865019894306037934853000663900 1830268126198572650219830666368884192257416104591147649250193700238622863603 -7 351701134820991236904165396525910865019894306037934853000663900 0 8937958634325442801454293670513585183347753080393029551726950904995907728078 -7 184474093158212492748835145195920156492337429678208537608867061 184474093158212492748835145195920156492337429678208537608867061 5487178106459188549645395174932411843477829933717593455583355788435741813104 -7 0 184474093158212492748835145195920156492337429678208537608867061 16618979616136152797339359341015545034224035585852793732956285484211962227027 -7 184474093158212492748835145195920156492337429678208537608867061 0 10228900522461201729212214878225683375012684577195889503558741948749658190835 -7 199389399670695255063380293209033944893100685561421637939408420 199389399670695255063380293209033944893100685561421637939408420 17611843423185660448247082563434415821613861679331418645769888662758916553196 -7 0 199389399670695255063380293209033944893100685561421637939408420 10364847641840550769942656131600009656390619290521197147946379481405385358236 -7 199389399670695255063380293209033944893100685561421637939408420 0 6595036896144407838172469783469595492936711672415161184120678530465681471170 -7 229750663215959825861733302345183157474670810272599228330177204 229750663215959825861733302345183157474670810272599228330177204 1154460331149775781418097242353182180830788005044602952335412237304671248429 -7 0 229750663215959825861733302345183157474670810272599228330177204 14046916959330712203968764964794563033793107771470964326695652990881000447725 -7 229750663215959825861733302345183157474670810272599228330177204 0 7906955323817334541421309060705295359170523539324565627885382569995903848612 -7 36138769411830975130261653627209591763277042851294292451158065315 36138769411830975130261653627209591763277042851294292451158065315 16742323902510637532248251542153200045717085783939503801095530714259667297768 -7 0 36138769411830975130261653627209591763277042851294292451158065315 8457553111501611531655911641166993528678252467975120789823663466267361160402 -7 36138769411830975130261653627209591763277042851294292451158065315 0 20460027702772047680553536714732554783567700072203586829242088714869040292800 -7 68674301456209479167069519631088993013396933844528659309455875325 68674301456209479167069519631088993013396933844528659309455875325 16695493464523510060529666911112103326479365281509187587792916358196282766471 -7 0 68674301456209479167069519631088993013396933844528659309455875325 12461307782284093661798987829515658336860844280799914899569515030632206934622 -7 68674301456209479167069519631088993013396933844528659309455875325 0 18940935925937754646715457636493765102239442822878133147542526814271956490936 -7 66363118198215167119594897250200664868066119799832865536011772642 66363118198215167119594897250200664868066119799832865536011772642 15411416744514574718038114761114613419877670142389107693642880422338313469345 -7 0 66363118198215167119594897250200664868066119799832865536011772642 21073776859139110195711455362606099317001219618492179185480106253608693978941 -7 66363118198215167119594897250200664868066119799832865536011772642 0 683283937878502931071789940468476766583840144281618405031702122216783998094 -7 69836203276541210929265183980925376150898448337084015848203253156 69836203276541210929265183980925376150898448337084015848203253156 16256595328649527994225028331316048091563117045138417753838853762928294393207 -7 0 69836203276541210929265183980925376150898448337084015848203253156 1171442120486165116052098625258604680057294087299979688226274544274138496933 -7 69836203276541210929265183980925376150898448337084015848203253156 0 15938617260102706632247396358319229717389868202510170565008399901788080479531 -7 55192622182575869878545994120208993873054428775743878640903837432 55192622182575869878545994120208993873054428775743878640903837432 8604693103185337422987433980429608652488043403333105684356774517116454183560 -7 0 55192622182575869878545994120208993873054428775743878640903837432 4578090660836542999290179921430528936535069087707826186563502566668868587687 -7 55192622182575869878545994120208993873054428775743878640903837432 0 17012871559020341549127871225699276619839485196279270598551022310762030878147 -7 18887881242658620578146448353135118138755901290331992459374898034 18887881242658620578146448353135118138755901290331992459374898034 5775630818490431041021152941876402087526160628812458184998805977557271542749 -7 0 18887881242658620578146448353135118138755901290331992459374898034 4059112016984523541356862756931564347890622687854889831524564298328783416908 -7 18887881242658620578146448353135118138755901290331992459374898034 0 4337594860839002382835798668699314202978183979220787690268322719702987474609 -7 13727998743993022067091585713741680058436657881427703334898807217994 13727998743993022067091585713741680058436657881427703334898807217994 5568989375493051617477698311466733397787391237415221464123246523274696062227 -7 0 13727998743993022067091585713741680058436657881427703334898807217994 17175235976546040923671041956760302148196864370492278094330089764277884765052 -7 13727998743993022067091585713741680058436657881427703334898807217994 0 15942810308781160596069034474565268425710350460823031162887049878506718391348 -7 23796172715971093073357699487486537923828547572589267391764537117614 23796172715971093073357699487486537923828547572589267391764537117614 10953914693263478171623139488932430514582502756404725713352643484324137847745 -7 0 23796172715971093073357699487486537923828547572589267391764537117614 6334150116120491797663028758593017247188130066480252318103473244344533350133 -7 23796172715971093073357699487486537923828547572589267391764537117614 0 18267227790754564911593021086481030109708414260385526909522536105996711179623 -7 25315158770423470866216422107684867741081458254837718260226295119906 25315158770423470866216422107684867741081458254837718260226295119906 14689159082780978925296466860902037984024093077767095825285084221758558827764 -7 0 25315158770423470866216422107684867741081458254837718260226295119906 5874202063063153643675747083453277090015673213866694669492659554169311837776 -7 25315158770423470866216422107684867741081458254837718260226295119906 0 19556462308564981607100298207971759222616944735727758076866371771663990803139 -7 2751396850401847721435087813488835625726449489692218272943958999473 2751396850401847721435087813488835625726449489692218272943958999473 19654970331431656304868420110064275590199806991033862806114515490050596692057 -7 0 2751396850401847721435087813488835625726449489692218272943958999473 14097514386377238489227479702148010224625780122766758105787346085987739773666 -7 2751396850401847721435087813488835625726449489692218272943958999473 0 21701897288077722632586865426841177375214240049145084832682390643747378679453 -7 4726679854228678607116891203946687439096256191427148469354558748708 4726679854228678607116891203946687439096256191427148469354558748708 11176229475684495955644298218113458998011583263893985381296539865657190363981 -7 0 4726679854228678607116891203946687439096256191427148469354558748708 1554385768709884138931054078656716161001221867842965367704415570846343909699 -7 4726679854228678607116891203946687439096256191427148469354558748708 0 2280692254587099040074634071918921826674487434373335986219774712451292197260 -7 21923645819969958231927727449351889461235256259254185616800433207686 21923645819969958231927727449351889461235256259254185616800433207686 9257635470904326285299162740191087274937309602111782408351834749484194016732 -7 0 21923645819969958231927727449351889461235256259254185616800433207686 12500022997406385924701834503000208785249432191817553014469581415871002622988 -7 21923645819969958231927727449351889461235256259254185616800433207686 0 3672023344048451963282648609398372743380102799433215909930046980337480677628 -7 74754028719967603288528196534923919342068599432442735770922818504006 74754028719967603288528196534923919342068599432442735770922818504006 5336879744961096196092864130582549598617743109664360786370565141324205654468 -7 0 74754028719967603288528196534923919342068599432442735770922818504006 19534266739582153752654136789924338424850022871919461898234325545170871511592 -7 74754028719967603288528196534923919342068599432442735770922818504006 0 16234130647796498574868883834767886572016205023070527188973228479441899615082 -7 2363128381208062029215486018432384453572915619830251079500388882034401 2363128381208062029215486018432384453572915619830251079500388882034401 10635421932006451043929268992634878358272156777470774943009895758976684723906 -7 0 2363128381208062029215486018432384453572915619830251079500388882034401 10523234330232429653704698976152611654112508625303337518895360852557291952028 -7 2363128381208062029215486018432384453572915619830251079500388882034401 0 12730128737435722813038612482065170952861401752100183913557320188449383423276 -7 2673803014093303360151314563269070653483918709971604637459749945141832 2673803014093303360151314563269070653483918709971604637459749945141832 6926463524279374245022221424533092295107893947976993478163101530890797475151 -7 0 2673803014093303360151314563269070653483918709971604637459749945141832 10133965885212296304823798129572074112530763443008942085048437583617595258810 -7 2673803014093303360151314563269070653483918709971604637459749945141832 0 18579041453731680925892043308724174943654400665750167059216558125202972110076 -7 4257412346975243691011317996804337495829190921940247791126828810872039 4257412346975243691011317996804337495829190921940247791126828810872039 17089734331504906841255164465299509907833594785239872993783079785337874112611 -7 0 4257412346975243691011317996804337495829190921940247791126828810872039 8433635198958021614215816533701171127436393924271356236983382299978729560545 -7 4257412346975243691011317996804337495829190921940247791126828810872039 0 8047753191873803370445452913748966989666283396547464836466861831732088585857 -7 2819569840414721944057740991622082879555394487936542565235853217444479 2819569840414721944057740991622082879555394487936542565235853217444479 17908102847634749414343788897833986740710189236363386774483108426452511721196 -7 0 2819569840414721944057740991622082879555394487936542565235853217444479 21706375369263197966950391407522617161521340715645373731655393479459472173539 -7 2819569840414721944057740991622082879555394487936542565235853217444479 0 9836244084143634647246046990602984230634421046953991950938176186754462576745 -7 4772954372425665773719768664593404610022639318026998291054481500134865 4772954372425665773719768664593404610022639318026998291054481500134865 10954517090683367683533464313342938726503573820973307966555987468837296385242 -7 0 4772954372425665773719768664593404610022639318026998291054481500134865 18604915054851602435932902800331901819970151341507031365160489606246262528614 -7 4772954372425665773719768664593404610022639318026998291054481500134865 0 18736995903536546490323211614020810093945100419429137098246063650084423439124 -7 136025195348529212365158570413867106238380137585352279224082858028839133 136025195348529212365158570413867106238380137585352279224082858028839133 20992998996171113698647222998331862398219702891171051833077253814969262261804 -7 0 136025195348529212365158570413867106238380137585352279224082858028839133 16704968443233583864379672757477563938365982895841783032946502795866120352275 -7 136025195348529212365158570413867106238380137585352279224082858028839133 0 2656490097324286628807681103273357172719900421832247794168313913062897923498 -7 471989507385339122413559343959625507836052893966568845123046339748673691 471989507385339122413559343959625507836052893966568845123046339748673691 15496389748220708480042843693218545549409006685306260647037202048271153893060 -7 0 471989507385339122413559343959625507836052893966568845123046339748673691 21053914647315147831255576456547484625971550641392595120336461401368512484740 -7 471989507385339122413559343959625507836052893966568845123046339748673691 0 4451931153342694341202942843605284711947940846050418931461718644849207808397 -7 643140671154465353540324662247580773794269702663363305380990825114644303 643140671154465353540324662247580773794269702663363305380990825114644303 2908317455217254743041330014450841899602940465253188074145253501058336208299 -7 0 643140671154465353540324662247580773794269702663363305380990825114644303 14536398038163466659498657396595180289780053626817254139340296646136410852176 -7 643140671154465353540324662247580773794269702663363305380990825114644303 0 11206266484443482004920500319349923951603519693670856518633322270521536545348 -7 1367776378473849238099749435385941001765671420284950098267091157822212079 1367776378473849238099749435385941001765671420284950098267091157822212079 19014540575804805435073316472269945804644820713813681395365143704611442380730 -7 0 1367776378473849238099749435385941001765671420284950098267091157822212079 9784679001788328388319097836501843799944706551654470630070252869146498224126 -7 1367776378473849238099749435385941001765671420284950098267091157822212079 0 18809131884455186264046880579466842832250058321722736501727846964040023320453 -7 1377574423878361302434505079661845110322617973133269519390872180274079719 1377574423878361302434505079661845110322617973133269519390872180274079719 17424183330367483654426582731619486614887802222682362075506738617658308746148 -7 0 1377574423878361302434505079661845110322617973133269519390872180274079719 7894311119122524988426675240600547916022938666000447052232453859572155130055 -7 1377574423878361302434505079661845110322617973133269519390872180274079719 0 6414310157523396278548716427939779531068747726354461628623320055801880661037 -7 341858280027370902540401312182682656313285812002204885066314129660077851 341858280027370902540401312182682656313285812002204885066314129660077851 15131170439036962258075706728835681564568302009522138076622421294962471876023 -7 0 341858280027370902540401312182682656313285812002204885066314129660077851 1735878276054569698108329923239011861268293390559830694153295649306211663635 -7 341858280027370902540401312182682656313285812002204885066314129660077851 0 8120878459502619959419488806467206061355317089359644766199651917546660948212 -7 64547905471220192702391019007379342322611264661212270783366961435685870636 64547905471220192702391019007379342322611264661212270783366961435685870636 6938966987615470606764197594203663615403557259139617155236031063317994982857 -7 0 64547905471220192702391019007379342322611264661212270783366961435685870636 7751496671681777925097136588758465891413635470859086918162776058692080398401 -7 64547905471220192702391019007379342322611264661212270783366961435685870636 0 14662783712125903840109783670454916613684483415775763371721491399060125337493 -7 392718432754820352521043489090258225174418029226345884162735475070148026190 392718432754820352521043489090258225174418029226345884162735475070148026190 4161474917668373985749152521353114701441358512370548782303889203305979073135 -7 0 392718432754820352521043489090258225174418029226345884162735475070148026190 14054874045464981323162033064574558369406775546563235805290536851623895249048 -7 392718432754820352521043489090258225174418029226345884162735475070148026190 0 17291856607572488046267265938791760804689423931539530025712198999815096439058 -7 389901407064670479347319907272279310549878454312587224637071839048868256626 389901407064670479347319907272279310549878454312587224637071839048868256626 21039854477463782364096485356210274493257562394502411647828600635685676440235 -7 0 389901407064670479347319907272279310549878454312587224637071839048868256626 12497609036324352326720042110556199531647900906926838160387041318580574663426 -7 389901407064670479347319907272279310549878454312587224637071839048868256626 0 7496056596477953637866778142045377908791146616307462340622554813110117207989 -7 151728081964243712155292499435395729415238645275701427697772008463395182468 151728081964243712155292499435395729415238645275701427697772008463395182468 9347573713844361634539687505812929802620674960289407149985083445009781259195 -7 0 151728081964243712155292499435395729415238645275701427697772008463395182468 19953278382521741189441291924059781304290753939451192304528204505131928728814 -7 151728081964243712155292499435395729415238645275701427697772008463395182468 0 6418532858683888652956936992372039296983188559038355746517404775530456106432 -7 395651583548367851028829013987094760455393382042370361863926974146268754844 395651583548367851028829013987094760455393382042370361863926974146268754844 19593269055024257093674991825404204176978591419390172322464182219672871076143 -7 0 395651583548367851028829013987094760455393382042370361863926974146268754844 17273580071502263272537237250644155326721754116500930137095297793883907975630 -7 395651583548367851028829013987094760455393382042370361863926974146268754844 0 9027068886077164798136593789676730682073991684932483065174441988396916807818 -7 233049213894097817470586660641792089067825974697072651614874971657215614489 233049213894097817470586660641792089067825974697072651614874971657215614489 11590811007440831694950440191206800823796948636238907364313428056132975441592 -7 0 233049213894097817470586660641792089067825974697072651614874971657215614489 8436461224132581311118840478853798900005020088337949291330662045116910803838 -7 233049213894097817470586660641792089067825974697072651614874971657215614489 0 655170687338897547134494291079217476763288338399832694739494702050617171274 -7 15228093958148267250964162308475488471428689945169901896089336183553343849489 15228093958148267250964162308475488471428689945169901896089336183553343849489 16977709412943559986914862967200361478637218492609663827625753816786840562499 -7 0 15228093958148267250964162308475488471428689945169901896089336183553343849489 8854421832393573832340133388237702367966819391772102676614208300346685292334 -7 15228093958148267250964162308475488471428689945169901896089336183553343849489 0 18382142854419574293008142481350528723959590478779473793297637573268932023393 -7 19912432864139097364494806297184807858032361534918134187673311998114222038607 19912432864139097364494806297184807858032361534918134187673311998114222038607 18998248031119430354299106946584684521026227318298372871198872199946464636675 -7 0 19912432864139097364494806297184807858032361534918134187673311998114222038607 2543526340866321404210078552382803099195689760445673305399938505361973109627 -7 19912432864139097364494806297184807858032361534918134187673311998114222038607 0 7982383647465178398190824054388638788218816822505132476321220430390918655308 -7 7020219358573873117136020093605583475141095160011014247680181555885812525761 7020219358573873117136020093605583475141095160011014247680181555885812525761 3142326836352511003462323575902081944827923262793590320160809336077473604321 -7 0 7020219358573873117136020093605583475141095160011014247680181555885812525761 12591988469262117828073231728507584518251477915793126082315121530927236315950 -7 7020219358573873117136020093605583475141095160011014247680181555885812525761 0 4342462207957342989839772352162852661592601275552050311530265608700828270551 -7 9285405545275227910121788521455146172621717603335451261616309661038319278048 9285405545275227910121788521455146172621717603335451261616309661038319278048 2802066694180274358272688054778740661047555907622022451478535015698611221133 -7 0 9285405545275227910121788521455146172621717603335451261616309661038319278048 8962960612841104418073027735618194223130211504855887969314337136829747931437 -7 9285405545275227910121788521455146172621717603335451261616309661038319278048 0 6412535219948206370671891958515494672754231279424573663576055078426365274686 -7 3615518995053111145686827784937618023724774816194183726265452586134522239244 3615518995053111145686827784937618023724774816194183726265452586134522239244 18843569134454229480340485201638436261589188085899043260462368753654834229603 -7 0 3615518995053111145686827784937618023724774816194183726265452586134522239244 6264356954943354827372470263953901525983434880536676177315263190337406301184 -7 3615518995053111145686827784937618023724774816194183726265452586134522239244 0 6297204882724017617444387977415741183310572168569976031575924339225125094548 -7 10678224721557598063690364833172229961599167383270930809780552848090203180915 10678224721557598063690364833172229961599167383270930809780552848090203180915 7348141915647236382489226376648957201994023279203269650509777248966458751919 -7 0 10678224721557598063690364833172229961599167383270930809780552848090203180915 12288171311013424167911799696256744851095482647296018843840849232032324602510 -7 10678224721557598063690364833172229961599167383270930809780552848090203180915 0 4246320328592011563401202690977238599826712268354753358699722631548510251765 \ No newline at end of file diff --git a/contracts/lib/ds-test b/contracts/lib/ds-test deleted file mode 160000 index 9310e879d..000000000 --- a/contracts/lib/ds-test +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 9310e879db8ba3ea6d5c6489a579118fd264a3f5 diff --git a/contracts/lib/forge-std b/contracts/lib/forge-std deleted file mode 160000 index 662ae0d69..000000000 --- a/contracts/lib/forge-std +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 662ae0d6936654c5d1fb79fc15f521de28edb60e diff --git a/contracts/lib/solmate b/contracts/lib/solmate deleted file mode 160000 index bff24e835..000000000 --- a/contracts/lib/solmate +++ /dev/null @@ -1 +0,0 @@ -Subproject commit bff24e835192470ed38bf15dbed6084c2d723ace diff --git a/contracts/package.json b/contracts/package.json deleted file mode 100644 index b62bd10e8..000000000 --- a/contracts/package.json +++ /dev/null @@ -1,73 +0,0 @@ -{ - "name": "scroll-contracts", - "version": "1.0.0", - "main": "index.js", - "license": "MIT", - "scripts": { - "test:hardhat": "npx hardhat test", - "test:forge": "forge test -vvv --evm-version cancun", - "test": "yarn test:hardhat && yarn test:forge", - "solhint": "./node_modules/.bin/solhint -f table 'src/**/*.sol'", - "lint:sol": "./node_modules/.bin/prettier --write 'src/**/*.sol'", - "lint:ts": "./node_modules/.bin/prettier --write 'integration-test/**/*.ts' 'scripts/**/*.ts' *.ts", - "lint": "yarn lint:ts && yarn lint:sol", - "coverage": "hardhat coverage", - "coverage:forge": "forge coverage", - "prepare": "cd .. && husky install contracts/.husky" - }, - "devDependencies": { - "@nomicfoundation/hardhat-chai-matchers": "^2.0.6", - "@nomicfoundation/hardhat-ethers": "^3.0.5", - "@nomicfoundation/hardhat-verify": "^2.0.5", - "@primitivefi/hardhat-dodoc": "^0.2.3", - "@typechain/ethers-v6": "^0.5.1", - "@typechain/hardhat": "^9.1.0", - "@types/chai": "^4.2.21", - "@types/edit-json-file": "^1.7.0", - "@types/mocha": "^9.0.0", - "@types/node": "^20.11.27", - "@typescript-eslint/eslint-plugin": "^7.2.0", - "@typescript-eslint/parser": "^7.2.0", - "chai": "^4.2.0", - "circom": "^0.5.46", - "circomlib": "^0.5.0", - "dotenv": "^10.0.0", - "edit-json-file": "^1.7.0", - "eslint": "^8.57.0", - "eslint-config-prettier": "^8.3.0", - "eslint-config-standard": "^17.1.0", - "eslint-plugin-import": "^2.23.4", - "eslint-plugin-n": "^16.6.2", - "eslint-plugin-node": "^11.1.0", - "eslint-plugin-prettier": "^3.4.0", - "eslint-plugin-promise": "^6.1.1", - "ethereum-waffle": "^3.0.0", - "ethers": "^6.11.1", - "hardhat": "^2.22.0", - "hardhat-gas-reporter": "^1.0.4", - "husky": "^8.0.1", - "lint-staged": "^13.0.3", - "lodash": "^4.17.21", - "prettier": "^2.3.2", - "prettier-plugin-solidity": "^1.0.0-beta.13", - "solhint": "^3.3.6", - "solidity-coverage": "^0.8.11", - "squirrelly": "8.0.8", - "toml": "^3.0.0", - "ts-node": "^10.1.0", - "typechain": "^8.3.2", - "typescript": "^5.4.2" - }, - "dependencies": { - "@openzeppelin/contracts": "^v4.9.3", - "@openzeppelin/contracts-upgradeable": "^v4.9.3" - }, - "lint-staged": { - "*.{js,ts}": "npx eslint --cache --fix", - "!(docs/apis/*).md": "prettier --ignore-unknown --write", - "*.sol": "prettier --ignore-unknown --write" - }, - "engines": { - "node": ">=10.4.0" - } -} diff --git a/contracts/remappings.txt b/contracts/remappings.txt deleted file mode 100644 index 47abd0682..000000000 --- a/contracts/remappings.txt +++ /dev/null @@ -1,5 +0,0 @@ -hardhat/=node_modules/hardhat/ -forge-std/=lib/forge-std/src/ -ds-test/=lib/ds-test/src/ -solmate/=lib/solmate/src/ -@openzeppelin/=node_modules/@openzeppelin \ No newline at end of file diff --git a/contracts/scripts/README.md b/contracts/scripts/README.md deleted file mode 100644 index 986d28d92..000000000 --- a/contracts/scripts/README.md +++ /dev/null @@ -1,104 +0,0 @@ -# Deployment scripts of Scroll contracts - -## Deployment using Hardhat - -The scripts should run as below sequence: - -```bash -export layer1=l1geth # change to actual network name -export layer2=l2geth # change to actual network name -export owner=0x0000000000000000000000000000000000000000 # change to actual owner - -# deploy contracts in layer 1 -npx hardhat --network $layer1 run scripts/deploy_proxy_admin.ts -npx hardhat --network $layer1 run scripts/deploy_scroll_chain.ts -env CONTRACT_NAME=L1ScrollMessenger npx hardhat run --network $layer1 scripts/deploy_proxy_contract.ts -env CONTRACT_NAME=L1GatewayRouter npx hardhat run --network $layer1 scripts/deploy_proxy_contract.ts -env CONTRACT_NAME=L1StandardERC20Gateway npx hardhat run --network $layer1 scripts/deploy_proxy_contract.ts -env CONTRACT_NAME=L1CustomERC20Gateway npx hardhat run --network $layer1 scripts/deploy_proxy_contract.ts -env CONTRACT_NAME=L1ERC721Gateway npx hardhat run --network $layer1 scripts/deploy_proxy_contract.ts -env CONTRACT_NAME=L1ERC1155Gateway npx hardhat run --network $layer1 scripts/deploy_proxy_contract.ts -env CONTRACT_NAME=L1ETHGateway npx hardhat run --network $layer1 scripts/deploy_proxy_contract.ts -env CONTRACT_NAME=L1WETHGateway npx hardhat run --network $layer1 scripts/deploy_proxy_contract.ts - -# deploy contracts in layer 2, note: l2_messenger is predeployed -npx hardhat --network $layer2 run scripts/deploy_proxy_admin.ts -npx hardhat --network $layer2 run scripts/deploy_l2_messenger.ts -npx hardhat --network $layer2 run scripts/deploy_l2_token_factory.ts -env CONTRACT_NAME=L2GatewayRouter npx hardhat run --network $layer2 scripts/deploy_proxy_contract.ts -env CONTRACT_NAME=L2StandardERC20Gateway npx hardhat run --network $layer2 scripts/deploy_proxy_contract.ts -env CONTRACT_NAME=L2CustomERC20Gateway npx hardhat run --network $layer2 scripts/deploy_proxy_contract.ts -env CONTRACT_NAME=L2ERC721Gateway npx hardhat run --network $layer2 scripts/deploy_proxy_contract.ts -env CONTRACT_NAME=L2ERC1155Gateway npx hardhat run --network $layer2 scripts/deploy_proxy_contract.ts -env CONTRACT_NAME=L2ETHGateway npx hardhat run --network $layer2 scripts/deploy_proxy_contract.ts -env CONTRACT_NAME=L2WETHGateway npx hardhat run --network $layer2 scripts/deploy_proxy_contract.ts - -# initialize contracts in layer 1, should set proper bash env variables first -npx hardhat --network $layer1 run scripts/initialize_l1_erc20_gateway.ts -npx hardhat --network $layer1 run scripts/initialize_l1_gateway_router.ts -npx hardhat --network $layer1 run scripts/initialize_scroll_chain.ts -npx hardhat --network $layer1 run scripts/initialize_l1_messenger.ts -npx hardhat --network $layer1 run scripts/initialize_l1_custom_erc20_gateway.ts -npx hardhat --network $layer1 run scripts/initialize_l1_erc1155_gateway.ts -npx hardhat --network $layer1 run scripts/initialize_l1_erc721_gateway.ts - -# initialize contracts in layer 2, should set proper bash env variables first -npx hardhat --network $layer2 run scripts/initialize_l2_erc20_gateway.ts -npx hardhat --network $layer2 run scripts/initialize_l2_gateway_router.ts -npx hardhat --network $layer2 run scripts/initialize_l2_custom_erc20_gateway.ts -npx hardhat --network $layer2 run scripts/initialize_l2_erc1155_gateway.ts -npx hardhat --network $layer2 run scripts/initialize_l2_erc721_gateway.ts -npx hardhat --network $layer2 run scripts/initialize_l2_token_factory.ts - -# transfer ownership in layer 1 -env CONTRACT_NAME=ProxyAdmin CONTRACT_OWNER=$owner npx hardhat run --network $layer1 scripts/transfer_ownership.ts -env CONTRACT_NAME=L1ScrollMessenger CONTRACT_OWNER=$owner npx hardhat run --network $layer1 scripts/transfer_ownership.ts -env CONTRACT_NAME=ZKRollup CONTRACT_OWNER=$owner npx hardhat run --network $layer1 scripts/transfer_ownership.ts -env CONTRACT_NAME=L1GatewayRouter CONTRACT_OWNER=$owner npx hardhat run --network $layer1 scripts/transfer_ownership.ts -env CONTRACT_NAME=L1CustomERC20Gateway CONTRACT_OWNER=$owner npx hardhat run --network $layer1 scripts/transfer_ownership.ts -env CONTRACT_NAME=L1ERC721Gateway CONTRACT_OWNER=$owner npx hardhat run --network $layer1 scripts/transfer_ownership.ts -env CONTRACT_NAME=L1ERC1155Gateway CONTRACT_OWNER=$owner npx hardhat run --network $layer1 scripts/transfer_ownership.ts -# transfer ownership in layer 2 -env CONTRACT_NAME=ProxyAdmin CONTRACT_OWNER=$owner npx hardhat run --network $layer2 scripts/transfer_ownership.ts -env CONTRACT_NAME=L2ScrollMessenger CONTRACT_OWNER=$owner npx hardhat run --network $layer2 scripts/transfer_ownership.ts -env CONTRACT_NAME=L2GatewayRouter CONTRACT_OWNER=$owner npx hardhat run --network $layer2 scripts/transfer_ownership.ts -env CONTRACT_NAME=L2CustomERC20Gateway CONTRACT_OWNER=$owner npx hardhat run --network $layer2 scripts/transfer_ownership.ts -env CONTRACT_NAME=L2ERC721Gateway CONTRACT_OWNER=$owner npx hardhat run --network $layer2 scripts/transfer_ownership.ts -env CONTRACT_NAME=L2ERC1155Gateway CONTRACT_OWNER=$owner npx hardhat run --network $layer2 scripts/transfer_ownership.ts -``` - -Reference testnet [run_deploy_contracts.sh](https://github.com/scroll-tech/testnet/blob/staging/run_deploy_contracts.sh) for details. - -## Deployment using Foundry - -Note: The Foundry scripts take parameters like `CHAIN_ID_L2` and `L1_SCROLL_CHAIN_PROXY_ADDR` as environment variables. - -```bash -# allexport -$ set -a - -$ cat .env -CHAIN_ID_L2="5343541" -SCROLL_L1_RPC="http://localhost:8543" -SCROLL_L2_RPC="http://localhost:8545" -L1_DEPLOYER_PRIVATE_KEY="0x0000000000000000000000000000000000000000000000000000000000000001" -L2_DEPLOYER_PRIVATE_KEY="0x0000000000000000000000000000000000000000000000000000000000000002" -L1_ROLLUP_OPERATOR_ADDR="0x1111111111111111111111111111111111111111" - -$ source .env - -# Deploy L1 contracts -# Note: We extract the logged addresses as environment variables. -$ OUTPUT=$(forge script scripts/foundry/DeployL1BridgeContracts.s.sol:DeployL1BridgeContracts --rpc-url $SCROLL_L1_RPC --broadcast); echo $OUTPUT -$ echo "$OUTPUT" | grep -Eo "(L1)_.*" > .env.l1_addresses -$ source .env.l1_addresses - -# Deploy L2 contracts -$ OUTPUT=$(forge script scripts/foundry/DeployL2BridgeContracts.s.sol:DeployL2BridgeContracts --rpc-url $SCROLL_L2_RPC --broadcast); echo $OUTPUT -$ echo "$OUTPUT" | grep -Eo "(L2)_.*" > .env.l2_addresses -$ source .env.l2_addresses - -# Initialize contracts -$ forge script scripts/foundry/InitializeL1BridgeContracts.s.sol:InitializeL1BridgeContracts --rpc-url $SCROLL_L1_RPC --broadcast -$ forge script scripts/foundry/InitializeL2BridgeContracts.s.sol:InitializeL2BridgeContracts --rpc-url $SCROLL_L2_RPC --broadcast -``` diff --git a/contracts/scripts/ScrollChainCommitmentVerifier.deploy.ts b/contracts/scripts/ScrollChainCommitmentVerifier.deploy.ts deleted file mode 100644 index 24dc639ca..000000000 --- a/contracts/scripts/ScrollChainCommitmentVerifier.deploy.ts +++ /dev/null @@ -1,40 +0,0 @@ -/* eslint-disable node/no-missing-import */ -import * as dotenv from "dotenv"; - -import { ethers } from "hardhat"; -import { generateABI, createCode } from "../scripts/poseidon"; - -dotenv.config(); - -async function main() { - const [deployer] = await ethers.getSigners(); - - const ScrollChainCommitmentVerifier = await ethers.getContractFactory("ScrollChainCommitmentVerifier", deployer); - - const L1ScrollChainAddress = process.env.L1_SCROLL_CHAIN_PROXY_ADDR!; - let PoseidonUnit2Address = process.env.POSEIDON_UNIT2_ADDR; - - if (!PoseidonUnit2Address) { - const Poseidon2Elements = new ethers.ContractFactory(generateABI(2), createCode(2), deployer); - - const poseidon = await Poseidon2Elements.deploy(); - console.log("Deploy PoseidonUnit2 contract, hash:", poseidon.deployTransaction.hash); - const receipt = await poseidon.deployTransaction.wait(); - console.log(`✅ Deploy PoseidonUnit2 contract at: ${poseidon.address}, gas used: ${receipt.gasUsed}`); - PoseidonUnit2Address = poseidon.address; - } - - const verifier = await ScrollChainCommitmentVerifier.deploy(PoseidonUnit2Address, L1ScrollChainAddress, { - gasPrice: 1e9, - }); - console.log("Deploy ScrollChainCommitmentVerifier contract, hash:", verifier.deployTransaction.hash); - const receipt = await verifier.deployTransaction.wait(); - console.log(`✅ Deploy ScrollChainCommitmentVerifier contract at: ${verifier.address}, gas used: ${receipt.gasUsed}`); -} - -// We recommend this pattern to be able to use async/await everywhere -// and properly handle errors. -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); diff --git a/contracts/scripts/deploy_l2_messenger.ts b/contracts/scripts/deploy_l2_messenger.ts deleted file mode 100644 index 4e5c8d195..000000000 --- a/contracts/scripts/deploy_l2_messenger.ts +++ /dev/null @@ -1,50 +0,0 @@ -/* eslint-disable node/no-missing-import */ -import * as hre from "hardhat"; -import { ethers } from "hardhat"; -import { selectAddressFile } from "./utils"; - -async function main() { - const addressFile = selectAddressFile(hre.network.name); - - const [deployer] = await ethers.getSigners(); - - const ProxyAdmin = await ethers.getContractAt("ProxyAdmin", addressFile.get("ProxyAdmin"), deployer); - - const container = process.env.L1_BLOCK_CONTAINER_ADDR!; - const queue = process.env.L2_MESSAGE_QUEUE_ADDR!; - if (!addressFile.get("L2ScrollMessenger.implementation")) { - console.log(">> Deploy L2ScrollMessenger implementation"); - const L2ScrollMessenger = await ethers.getContractFactory("L2ScrollMessenger", deployer); - const impl = await L2ScrollMessenger.deploy(container, queue); - console.log(`>> waiting for transaction: ${impl.deployTransaction.hash}`); - await impl.deployed(); - console.log(`✅ L2ScrollMessenger implementation deployed at ${impl.address}`); - addressFile.set("L2ScrollMessenger.implementation", impl.address); - } - - const impl = addressFile.get("L2ScrollMessenger.implementation") as string; - - if (!addressFile.get("L2ScrollMessenger.proxy")) { - console.log(">> Deploy L2ScrollMessenger proxy"); - const TransparentUpgradeableProxy = await ethers.getContractFactory("TransparentUpgradeableProxy", deployer); - const proxy = await TransparentUpgradeableProxy.deploy(impl, ProxyAdmin.address, "0x"); - console.log(`>> waiting for transaction: ${proxy.deployTransaction.hash}`); - await proxy.deployed(); - console.log(`✅ L2ScrollMessenger proxy deployed at ${proxy.address}`); - addressFile.set(`L2ScrollMessenger.proxy`, proxy.address); - } - - // Export contract address to testnet. - console.log( - `testnet-export: ${addressFile.get("L2ScrollMessenger.implementation")};${addressFile.get( - "L2ScrollMessenger.proxy" - )}` - ); -} - -// We recommend this pattern to be able to use async/await everywhere -// and properly handle errors. -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); diff --git a/contracts/scripts/deploy_l2_token_factory.ts b/contracts/scripts/deploy_l2_token_factory.ts deleted file mode 100644 index 42c71c9dc..000000000 --- a/contracts/scripts/deploy_l2_token_factory.ts +++ /dev/null @@ -1,44 +0,0 @@ -/* eslint-disable node/no-missing-import */ -import * as hre from "hardhat"; -import { ethers } from "hardhat"; -import { selectAddressFile } from "./utils"; - -async function main() { - const addressFile = selectAddressFile(hre.network.name); - - const [deployer] = await ethers.getSigners(); - - if (!addressFile.get("ScrollStandardERC20")) { - console.log(">> Deploy ScrollStandardERC20"); - const ScrollStandardERC20 = await ethers.getContractFactory("ScrollStandardERC20", deployer); - const token = await ScrollStandardERC20.deploy(); - console.log(`>> waiting for transaction: ${token.deployTransaction.hash}`); - await token.deployed(); - console.log(`✅ ScrollStandardERC20 deployed at ${token.address}`); - addressFile.set("ScrollStandardERC20", token.address); - } - - const tokenImpl = addressFile.get("ScrollStandardERC20") as string; - - if (!addressFile.get("ScrollStandardERC20Factory")) { - console.log(">> Deploy ScrollStandardERC20Factory"); - const ScrollStandardERC20Factory = await ethers.getContractFactory("ScrollStandardERC20Factory", deployer); - const token = await ScrollStandardERC20Factory.deploy(tokenImpl); - console.log(`>> waiting for transaction: ${token.deployTransaction.hash}`); - await token.deployed(); - console.log(`✅ ScrollStandardERC20Factory deployed at ${token.address}`); - addressFile.set("ScrollStandardERC20Factory", token.address); - } - - // Export contract address to testnet. - console.log( - `testnet-export: ${addressFile.get("ScrollStandardERC20")};${addressFile.get("ScrollStandardERC20Factory")}` - ); -} - -// We recommend this pattern to be able to use async/await everywhere -// and properly handle errors. -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); diff --git a/contracts/scripts/deploy_proxy_admin.ts b/contracts/scripts/deploy_proxy_admin.ts deleted file mode 100644 index 8894dc3c0..000000000 --- a/contracts/scripts/deploy_proxy_admin.ts +++ /dev/null @@ -1,30 +0,0 @@ -/* eslint-disable node/no-missing-import */ -import * as hre from "hardhat"; -import { ethers } from "hardhat"; -import { selectAddressFile } from "./utils"; - -async function main() { - const addressFile = selectAddressFile(hre.network.name); - - const [deployer] = await ethers.getSigners(); - - if (!addressFile.get("ProxyAdmin")) { - console.log(">> Deploy ProxyAdmin"); - const ProxyAdmin = await ethers.getContractFactory("ProxyAdmin", deployer); - const proxyAdmin = await ProxyAdmin.deploy(); - console.log(`>> waiting for transaction: ${proxyAdmin.deployTransaction.hash}`); - await proxyAdmin.deployed(); - console.log(`✅ ProxyAdmin deployed at ${proxyAdmin.address}`); - addressFile.set("ProxyAdmin", proxyAdmin.address); - } - - // Export contract address to testnet. - console.log(`testnet-export: ${addressFile.get("ProxyAdmin")}`); -} - -// We recommend this pattern to be able to use async/await everywhere -// and properly handle errors. -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); diff --git a/contracts/scripts/deploy_proxy_contract.ts b/contracts/scripts/deploy_proxy_contract.ts deleted file mode 100644 index 2921a1146..000000000 --- a/contracts/scripts/deploy_proxy_contract.ts +++ /dev/null @@ -1,54 +0,0 @@ -/* eslint-disable node/no-missing-import */ -import * as dotenv from "dotenv"; -import * as hre from "hardhat"; -import { ethers } from "hardhat"; -import { selectAddressFile } from "./utils"; - -dotenv.config(); - -async function main() { - const addressFile = selectAddressFile(hre.network.name); - - const [deployer] = await ethers.getSigners(); - - if (process.env.CONTRACT_NAME === undefined) { - throw new Error("env CONTRACT_NAME undefined"); - } - - const contractName = process.env.CONTRACT_NAME!; - const ProxyAdmin = await ethers.getContractAt("ProxyAdmin", addressFile.get("ProxyAdmin"), deployer); - - if (!addressFile.get(`${contractName}.implementation`)) { - console.log(`>> Deploy ${contractName} implementation`); - const ContractImpl = await ethers.getContractFactory(contractName, deployer); - const impl = await ContractImpl.deploy(); - console.log(`>> waiting for transaction: ${impl.deployTransaction.hash}`); - await impl.deployed(); - console.log(`✅ ${contractName} implementation deployed at ${impl.address}`); - addressFile.set(`${contractName}.implementation`, impl.address); - } - - const impl = addressFile.get(`${contractName}.implementation`) as string; - - if (!addressFile.get(`${contractName}.proxy`)) { - console.log(`>> Deploy ${contractName} proxy`); - const TransparentUpgradeableProxy = await ethers.getContractFactory("TransparentUpgradeableProxy", deployer); - const proxy = await TransparentUpgradeableProxy.deploy(impl, ProxyAdmin.address, "0x"); - console.log(`>> waiting for transaction: ${proxy.deployTransaction.hash}`); - await proxy.deployed(); - console.log(`✅ ${contractName} proxy deployed at ${proxy.address}`); - addressFile.set(`${contractName}.proxy`, proxy.address); - } - - // Export contract address to testnet. - console.log( - `testnet-export: ${addressFile.get(`${contractName}.implementation`)};${addressFile.get(`${contractName}.proxy`)}` - ); -} - -// We recommend this pattern to be able to use async/await everywhere -// and properly handle errors. -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); diff --git a/contracts/scripts/deploy_scroll_chain.ts b/contracts/scripts/deploy_scroll_chain.ts deleted file mode 100644 index 18052f3cb..000000000 --- a/contracts/scripts/deploy_scroll_chain.ts +++ /dev/null @@ -1,66 +0,0 @@ -/* eslint-disable node/no-missing-import */ -import * as hre from "hardhat"; -import { ethers } from "hardhat"; -import { selectAddressFile } from "./utils"; - -async function main() { - const addressFile = selectAddressFile(hre.network.name); - - const [deployer] = await ethers.getSigners(); - - const CHAIN_ID_L2 = process.env.CHAIN_ID_L2 || "none"; - const MAX_TX_IN_BATCH = process.env.MAX_TX_IN_BATCH || 25; - const PADDING_TX_HASH = - process.env.PADDING_TX_HASH || "0xb5baa665b2664c3bfed7eb46e00ebc110ecf2ebd257854a9bf2b9dbc9b2c08f6"; - - const ProxyAdmin = await ethers.getContractAt("ProxyAdmin", addressFile.get("ProxyAdmin"), deployer); - - if (!addressFile.get("ScrollChain.verifier")) { - console.log(">> Deploy RollupVerifier"); - const RollupVerifier = await ethers.getContractFactory("RollupVerifier", deployer); - const verifier = await RollupVerifier.deploy(); - console.log(`>> waiting for transaction: ${verifier.deployTransaction.hash}`); - await verifier.deployed(); - console.log(`✅ RollupVerifier deployed at ${verifier.address}`); - addressFile.set("ScrollChain.verifier", verifier.address); - } - - if (!addressFile.get("ScrollChain.implementation")) { - console.log(">> Deploy ScrollChain implementation"); - const ScrollChain = await ethers.getContractFactory("ScrollChain", { - libraries: { - RollupVerifier: addressFile.get("ScrollChain.verifier"), - }, - signer: deployer, - }); - const impl = await ScrollChain.deploy(CHAIN_ID_L2, MAX_TX_IN_BATCH, PADDING_TX_HASH); - console.log(`>> waiting for transaction: ${impl.deployTransaction.hash}`); - await impl.deployed(); - console.log(`✅ ScrollChain implementation deployed at ${impl.address}`); - addressFile.set("ScrollChain.implementation", impl.address); - } - - const impl = addressFile.get("ScrollChain.implementation") as string; - - if (!addressFile.get("ScrollChain.proxy")) { - console.log(">> Deploy ScrollChain proxy"); - const TransparentUpgradeableProxy = await ethers.getContractFactory("TransparentUpgradeableProxy", deployer); - const proxy = await TransparentUpgradeableProxy.deploy(impl, ProxyAdmin.address, "0x"); - console.log(`>> waiting for transaction: ${proxy.deployTransaction.hash}`); - await proxy.deployed(); - console.log(`✅ ScrollChain proxy deployed at ${proxy.address}`); - addressFile.set("ScrollChain.proxy", proxy.address); - } - - // Export contract address to testnet. - console.log( - `testnet-export: ${addressFile.get("ScrollChain.implementation")};${addressFile.get("ScrollChain.proxy")}` - ); -} - -// We recommend this pattern to be able to use async/await everywhere -// and properly handle errors. -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); diff --git a/contracts/scripts/deploy_weth.ts b/contracts/scripts/deploy_weth.ts deleted file mode 100644 index b9a2d5242..000000000 --- a/contracts/scripts/deploy_weth.ts +++ /dev/null @@ -1,30 +0,0 @@ -/* eslint-disable node/no-missing-import */ -import * as hre from "hardhat"; -import { ethers } from "hardhat"; -import { selectAddressFile } from "./utils"; - -async function main() { - const addressFile = selectAddressFile(hre.network.name); - - const [deployer] = await ethers.getSigners(); - - if (!addressFile.get("WETH")) { - console.log(">> Deploy WETH"); - const WrappedEther = await ethers.getContractFactory("WrappedEther", deployer); - const weth = await WrappedEther.deploy(); - console.log(`>> waiting for transaction: ${weth.deployTransaction.hash}`); - await weth.deployed(); - console.log(`✅ WETH deployed at ${weth.address}`); - addressFile.set("WETH", weth.address); - } - - // Export contract address to testnet. - console.log(`testnet-export: ${addressFile.get("WETH")}`); -} - -// We recommend this pattern to be able to use async/await everywhere -// and properly handle errors. -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); diff --git a/contracts/scripts/foundry/DeployFallbackContracts.s.sol b/contracts/scripts/foundry/DeployFallbackContracts.s.sol deleted file mode 100644 index ac0f226e6..000000000 --- a/contracts/scripts/foundry/DeployFallbackContracts.s.sol +++ /dev/null @@ -1,32 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity =0.8.24; - -// solhint-disable no-console - -import {Script} from "forge-std/Script.sol"; -import {console} from "forge-std/console.sol"; - -import {Fallback} from "../../src/misc/Fallback.sol"; - -// solhint-disable state-visibility -// solhint-disable var-name-mixedcase - -contract DeployFallbackContracts is Script { - uint256 DEPLOYER_PRIVATE_KEY = vm.envUint("DEPLOYER_PRIVATE_KEY"); - uint256 NUM_CONTRACTS = vm.envUint("NUM_CONTRACTS"); - - function run() external { - vm.startBroadcast(DEPLOYER_PRIVATE_KEY); - - for (uint256 ii = 0; ii < NUM_CONTRACTS; ++ii) { - Fallback fallbackContract = new Fallback(); - logAddress("FALLBACK", address(fallbackContract)); - } - - vm.stopBroadcast(); - } - - function logAddress(string memory name, address addr) internal view { - console.log(string(abi.encodePacked(name, "=", vm.toString(address(addr))))); - } -} diff --git a/contracts/scripts/foundry/DeployL1BridgeContracts.s.sol b/contracts/scripts/foundry/DeployL1BridgeContracts.s.sol deleted file mode 100644 index 827db491a..000000000 --- a/contracts/scripts/foundry/DeployL1BridgeContracts.s.sol +++ /dev/null @@ -1,233 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity =0.8.24; - -// solhint-disable no-console - -import {Script} from "forge-std/Script.sol"; -import {console} from "forge-std/console.sol"; - -import {ProxyAdmin} from "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol"; -import {TransparentUpgradeableProxy} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; - -import {EnforcedTxGateway} from "../../src/L1/gateways/EnforcedTxGateway.sol"; -import {L1CustomERC20Gateway} from "../../src/L1/gateways/L1CustomERC20Gateway.sol"; -import {L1ERC1155Gateway} from "../../src/L1/gateways/L1ERC1155Gateway.sol"; -import {L1ERC721Gateway} from "../../src/L1/gateways/L1ERC721Gateway.sol"; -import {L1ETHGateway} from "../../src/L1/gateways/L1ETHGateway.sol"; -import {L1GatewayRouter} from "../../src/L1/gateways/L1GatewayRouter.sol"; -import {L1MessageQueueWithGasPriceOracle} from "../../src/L1/rollup/L1MessageQueueWithGasPriceOracle.sol"; -import {L1ScrollMessenger} from "../../src/L1/L1ScrollMessenger.sol"; -import {L1StandardERC20Gateway} from "../../src/L1/gateways/L1StandardERC20Gateway.sol"; -import {L1WETHGateway} from "../../src/L1/gateways/L1WETHGateway.sol"; -import {L2GasPriceOracle} from "../../src/L1/rollup/L2GasPriceOracle.sol"; -import {MultipleVersionRollupVerifier} from "../../src/L1/rollup/MultipleVersionRollupVerifier.sol"; -import {ScrollChain} from "../../src/L1/rollup/ScrollChain.sol"; -import {Whitelist} from "../../src/L2/predeploys/Whitelist.sol"; -import {ZkEvmVerifierV1} from "../../src/libraries/verifier/ZkEvmVerifierV1.sol"; - -// solhint-disable max-states-count -// solhint-disable state-visibility -// solhint-disable var-name-mixedcase - -contract DeployL1BridgeContracts is Script { - uint256 L1_DEPLOYER_PRIVATE_KEY = vm.envUint("L1_DEPLOYER_PRIVATE_KEY"); - - uint64 CHAIN_ID_L2 = uint64(vm.envUint("CHAIN_ID_L2")); - - address L1_WETH_ADDR = vm.envAddress("L1_WETH_ADDR"); - address L2_WETH_ADDR = vm.envAddress("L2_WETH_ADDR"); - - address L1_PLONK_VERIFIER_ADDR = vm.envAddress("L1_PLONK_VERIFIER_ADDR"); - - address L1_PROXY_ADMIN_ADDR = vm.envAddress("L1_PROXY_ADMIN_ADDR"); - - address L1_SCROLL_CHAIN_PROXY_ADDR = vm.envAddress("L1_SCROLL_CHAIN_PROXY_ADDR"); - address L1_MESSAGE_QUEUE_PROXY_ADDR = vm.envAddress("L1_MESSAGE_QUEUE_PROXY_ADDR"); - address L1_SCROLL_MESSENGER_PROXY_ADDR = vm.envAddress("L1_SCROLL_MESSENGER_PROXY_ADDR"); - - address L2_SCROLL_MESSENGER_PROXY_ADDR = vm.envAddress("L2_SCROLL_MESSENGER_PROXY_ADDR"); - address L2_CUSTOM_ERC20_GATEWAY_PROXY_ADDR = vm.envAddress("L2_CUSTOM_ERC20_GATEWAY_PROXY_ADDR"); - address L2_ERC721_GATEWAY_PROXY_ADDR = vm.envAddress("L2_ERC721_GATEWAY_PROXY_ADDR"); - address L2_ERC1155_GATEWAY_PROXY_ADDR = vm.envAddress("L2_ERC1155_GATEWAY_PROXY_ADDR"); - address L2_ETH_GATEWAY_PROXY_ADDR = vm.envAddress("L2_ETH_GATEWAY_PROXY_ADDR"); - address L2_STANDARD_ERC20_GATEWAY_PROXY_ADDR = vm.envAddress("L2_STANDARD_ERC20_GATEWAY_PROXY_ADDR"); - address L2_WETH_GATEWAY_PROXY_ADDR = vm.envAddress("L2_WETH_GATEWAY_PROXY_ADDR"); - address L2_SCROLL_STANDARD_ERC20_ADDR = vm.envAddress("L2_SCROLL_STANDARD_ERC20_ADDR"); - address L2_SCROLL_STANDARD_ERC20_FACTORY_ADDR = vm.envAddress("L2_SCROLL_STANDARD_ERC20_FACTORY_ADDR"); - - ZkEvmVerifierV1 zkEvmVerifierV1; - MultipleVersionRollupVerifier rollupVerifier; - EnforcedTxGateway enforcedTxGateway; - ProxyAdmin proxyAdmin; - L1GatewayRouter router; - - function run() external { - proxyAdmin = ProxyAdmin(L1_PROXY_ADMIN_ADDR); - - vm.startBroadcast(L1_DEPLOYER_PRIVATE_KEY); - - deployZkEvmVerifierV1(); - deployMultipleVersionRollupVerifier(); - deployL1Whitelist(); - deployEnforcedTxGateway(); - deployL1MessageQueue(); - deployL2GasPriceOracle(); - deployScrollChain(); - deployL1ScrollMessenger(); - deployL1GatewayRouter(); - deployL1ETHGateway(); - deployL1WETHGateway(); - deployL1StandardERC20Gateway(); - deployL1CustomERC20Gateway(); - deployL1ERC721Gateway(); - deployL1ERC1155Gateway(); - - vm.stopBroadcast(); - } - - function deployZkEvmVerifierV1() internal { - zkEvmVerifierV1 = new ZkEvmVerifierV1(L1_PLONK_VERIFIER_ADDR); - - logAddress("L1_ZKEVM_VERIFIER_V1_ADDR", address(zkEvmVerifierV1)); - } - - function deployMultipleVersionRollupVerifier() internal { - uint256[] memory _versions = new uint256[](1); - address[] memory _verifiers = new address[](1); - _versions[0] = 0; - _verifiers[0] = address(zkEvmVerifierV1); - rollupVerifier = new MultipleVersionRollupVerifier(_versions, _verifiers); - - logAddress("L1_MULTIPLE_VERSION_ROLLUP_VERIFIER_ADDR", address(rollupVerifier)); - } - - function deployL1Whitelist() internal { - address owner = vm.addr(L1_DEPLOYER_PRIVATE_KEY); - Whitelist whitelist = new Whitelist(owner); - - logAddress("L1_WHITELIST_ADDR", address(whitelist)); - } - - function deployScrollChain() internal { - ScrollChain impl = new ScrollChain(CHAIN_ID_L2, L1_MESSAGE_QUEUE_PROXY_ADDR, address(rollupVerifier)); - - logAddress("L1_SCROLL_CHAIN_IMPLEMENTATION_ADDR", address(impl)); - } - - function deployL1MessageQueue() internal { - L1MessageQueueWithGasPriceOracle impl = new L1MessageQueueWithGasPriceOracle( - L1_SCROLL_MESSENGER_PROXY_ADDR, - L1_SCROLL_CHAIN_PROXY_ADDR, - address(enforcedTxGateway) - ); - logAddress("L1_MESSAGE_QUEUE_IMPLEMENTATION_ADDR", address(impl)); - } - - function deployL1ScrollMessenger() internal { - L1ScrollMessenger impl = new L1ScrollMessenger( - L2_SCROLL_MESSENGER_PROXY_ADDR, - L1_SCROLL_CHAIN_PROXY_ADDR, - L1_MESSAGE_QUEUE_PROXY_ADDR - ); - - logAddress("L1_SCROLL_MESSENGER_IMPLEMENTATION_ADDR", address(impl)); - } - - function deployL2GasPriceOracle() internal { - L2GasPriceOracle impl = new L2GasPriceOracle(); - TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy( - address(impl), - address(proxyAdmin), - new bytes(0) - ); - logAddress("L2_GAS_PRICE_ORACLE_IMPLEMENTATION_ADDR", address(impl)); - logAddress("L2_GAS_PRICE_ORACLE_PROXY_ADDR", address(proxy)); - } - - function deployL1GatewayRouter() internal { - L1GatewayRouter impl = new L1GatewayRouter(); - TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy( - address(impl), - address(proxyAdmin), - new bytes(0) - ); - - logAddress("L1_GATEWAY_ROUTER_IMPLEMENTATION_ADDR", address(impl)); - logAddress("L1_GATEWAY_ROUTER_PROXY_ADDR", address(proxy)); - - router = L1GatewayRouter(address(proxy)); - } - - function deployL1StandardERC20Gateway() internal { - L1StandardERC20Gateway impl = new L1StandardERC20Gateway( - L2_STANDARD_ERC20_GATEWAY_PROXY_ADDR, - address(router), - L1_SCROLL_MESSENGER_PROXY_ADDR, - L2_SCROLL_STANDARD_ERC20_ADDR, - L2_SCROLL_STANDARD_ERC20_FACTORY_ADDR - ); - - logAddress("L1_STANDARD_ERC20_GATEWAY_IMPLEMENTATION_ADDR", address(impl)); - } - - function deployL1ETHGateway() internal { - L1ETHGateway impl = new L1ETHGateway( - L2_ETH_GATEWAY_PROXY_ADDR, - address(router), - L1_SCROLL_MESSENGER_PROXY_ADDR - ); - - logAddress("L1_ETH_GATEWAY_IMPLEMENTATION_ADDR", address(impl)); - } - - function deployL1WETHGateway() internal { - L1WETHGateway impl = new L1WETHGateway( - L1_WETH_ADDR, - L2_WETH_ADDR, - L2_WETH_GATEWAY_PROXY_ADDR, - address(router), - L1_SCROLL_MESSENGER_PROXY_ADDR - ); - - logAddress("L1_WETH_GATEWAY_IMPLEMENTATION_ADDR", address(impl)); - } - - function deployL1CustomERC20Gateway() internal { - L1CustomERC20Gateway impl = new L1CustomERC20Gateway( - L2_CUSTOM_ERC20_GATEWAY_PROXY_ADDR, - address(router), - L1_SCROLL_MESSENGER_PROXY_ADDR - ); - - logAddress("L1_CUSTOM_ERC20_GATEWAY_IMPLEMENTATION_ADDR", address(impl)); - } - - function deployL1ERC721Gateway() internal { - L1ERC721Gateway impl = new L1ERC721Gateway(L2_ERC721_GATEWAY_PROXY_ADDR, L1_SCROLL_MESSENGER_PROXY_ADDR); - - logAddress("L1_ERC721_GATEWAY_IMPLEMENTATION_ADDR", address(impl)); - } - - function deployL1ERC1155Gateway() internal { - L1ERC1155Gateway impl = new L1ERC1155Gateway(L2_ERC1155_GATEWAY_PROXY_ADDR, L1_SCROLL_MESSENGER_PROXY_ADDR); - - logAddress("L1_ERC1155_GATEWAY_IMPLEMENTATION_ADDR", address(impl)); - } - - function deployEnforcedTxGateway() internal { - EnforcedTxGateway impl = new EnforcedTxGateway(); - TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy( - address(impl), - address(proxyAdmin), - new bytes(0) - ); - - logAddress("L1_ENFORCED_TX_GATEWAY_IMPLEMENTATION_ADDR", address(impl)); - logAddress("L1_ENFORCED_TX_GATEWAY_PROXY_ADDR", address(proxy)); - enforcedTxGateway = EnforcedTxGateway(address(proxy)); - } - - function logAddress(string memory name, address addr) internal view { - console.log(string(abi.encodePacked(name, "=", vm.toString(address(addr))))); - } -} diff --git a/contracts/scripts/foundry/DeployL1BridgeProxyPlaceholder.s.sol b/contracts/scripts/foundry/DeployL1BridgeProxyPlaceholder.s.sol deleted file mode 100644 index 2d9afe4ea..000000000 --- a/contracts/scripts/foundry/DeployL1BridgeProxyPlaceholder.s.sol +++ /dev/null @@ -1,145 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity =0.8.24; - -// solhint-disable no-console - -import {Script} from "forge-std/Script.sol"; -import {console} from "forge-std/console.sol"; - -import {ProxyAdmin} from "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol"; -import {TransparentUpgradeableProxy} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; - -import {EmptyContract} from "../../src/misc/EmptyContract.sol"; - -// solhint-disable state-visibility -// solhint-disable var-name-mixedcase - -contract DeployL1BridgeProxyPlaceholder is Script { - uint256 L1_DEPLOYER_PRIVATE_KEY = vm.envUint("L1_DEPLOYER_PRIVATE_KEY"); - - ProxyAdmin proxyAdmin; - EmptyContract placeholder; - - function run() external { - vm.startBroadcast(L1_DEPLOYER_PRIVATE_KEY); - - deployProxyAdmin(); - deployPlaceHolder(); - deployL1MessageQueue(); - deployScrollChain(); - deployL1ETHGateway(); - deployL1WETHGateway(); - deployL1StandardERC20Gateway(); - deployL1ScrollMessenger(); - deployL1CustomERC20Gateway(); - deployL1ERC721Gateway(); - deployL1ERC1155Gateway(); - - vm.stopBroadcast(); - } - - function deployProxyAdmin() internal { - proxyAdmin = new ProxyAdmin(); - - logAddress("L1_PROXY_ADMIN_ADDR", address(proxyAdmin)); - } - - function deployPlaceHolder() internal { - placeholder = new EmptyContract(); - - logAddress("L1_PROXY_IMPLEMENTATION_PLACEHOLDER_ADDR", address(placeholder)); - } - - function deployScrollChain() internal { - TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy( - address(placeholder), - address(proxyAdmin), - new bytes(0) - ); - - logAddress("L1_SCROLL_CHAIN_PROXY_ADDR", address(proxy)); - } - - function deployL1MessageQueue() internal { - TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy( - address(placeholder), - address(proxyAdmin), - new bytes(0) - ); - logAddress("L1_MESSAGE_QUEUE_PROXY_ADDR", address(proxy)); - } - - function deployL1StandardERC20Gateway() internal { - TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy( - address(placeholder), - address(proxyAdmin), - new bytes(0) - ); - - logAddress("L1_STANDARD_ERC20_GATEWAY_PROXY_ADDR", address(proxy)); - } - - function deployL1ETHGateway() internal { - TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy( - address(placeholder), - address(proxyAdmin), - new bytes(0) - ); - - logAddress("L1_ETH_GATEWAY_PROXY_ADDR", address(proxy)); - } - - function deployL1WETHGateway() internal { - TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy( - address(placeholder), - address(proxyAdmin), - new bytes(0) - ); - - logAddress("L1_WETH_GATEWAY_PROXY_ADDR", address(proxy)); - } - - function deployL1ScrollMessenger() internal { - TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy( - address(placeholder), - address(proxyAdmin), - new bytes(0) - ); - - logAddress("L1_SCROLL_MESSENGER_PROXY_ADDR", address(proxy)); - } - - function deployL1CustomERC20Gateway() internal { - TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy( - address(placeholder), - address(proxyAdmin), - new bytes(0) - ); - - logAddress("L1_CUSTOM_ERC20_GATEWAY_PROXY_ADDR", address(proxy)); - } - - function deployL1ERC721Gateway() internal { - TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy( - address(placeholder), - address(proxyAdmin), - new bytes(0) - ); - - logAddress("L1_ERC721_GATEWAY_PROXY_ADDR", address(proxy)); - } - - function deployL1ERC1155Gateway() internal { - TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy( - address(placeholder), - address(proxyAdmin), - new bytes(0) - ); - - logAddress("L1_ERC1155_GATEWAY_PROXY_ADDR", address(proxy)); - } - - function logAddress(string memory name, address addr) internal view { - console.log(string(abi.encodePacked(name, "=", vm.toString(address(addr))))); - } -} diff --git a/contracts/scripts/foundry/DeployL1ScrollOwner.s.sol b/contracts/scripts/foundry/DeployL1ScrollOwner.s.sol deleted file mode 100644 index 3eda44644..000000000 --- a/contracts/scripts/foundry/DeployL1ScrollOwner.s.sol +++ /dev/null @@ -1,66 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity =0.8.24; - -import {Script} from "forge-std/Script.sol"; -import {console} from "forge-std/console.sol"; - -import {TimelockController} from "@openzeppelin/contracts/governance/TimelockController.sol"; - -import {ScrollOwner} from "../../src/misc/ScrollOwner.sol"; - -// solhint-disable state-visibility -// solhint-disable var-name-mixedcase - -contract DeployL1ScrollOwner is Script { - string NETWORK = vm.envString("NETWORK"); - - uint256 L1_DEPLOYER_PRIVATE_KEY = vm.envUint("L1_DEPLOYER_PRIVATE_KEY"); - - address SCROLL_MULTISIG_ADDR = vm.envAddress("L1_SCROLL_MULTISIG_ADDR"); - - address SECURITY_COUNCIL_ADDR = vm.envAddress("L1_SECURITY_COUNCIL_ADDR"); - - address L1_PROPOSAL_EXECUTOR_ADDR = vm.envAddress("L1_PROPOSAL_EXECUTOR_ADDR"); - - function run() external { - vm.startBroadcast(L1_DEPLOYER_PRIVATE_KEY); - - deployScrollOwner(); - - if (keccak256(abi.encodePacked(NETWORK)) == keccak256(abi.encodePacked("sepolia"))) { - // for sepolia - deployTimelockController("1D", 1 minutes); - deployTimelockController("7D", 7 minutes); - deployTimelockController("14D", 14 minutes); - } else if (keccak256(abi.encodePacked(NETWORK)) == keccak256(abi.encodePacked("mainnet"))) { - // for mainnet - deployTimelockController("1D", 1 days); - deployTimelockController("7D", 7 days); - deployTimelockController("14D", 14 days); - } - - vm.stopBroadcast(); - } - - function deployScrollOwner() internal { - ScrollOwner owner = new ScrollOwner(); - - logAddress("L1_SCROLL_OWNER_ADDR", address(owner)); - } - - function deployTimelockController(string memory label, uint256 delay) internal { - address[] memory proposers = new address[](1); - address[] memory executors = new address[](1); - - proposers[0] = SCROLL_MULTISIG_ADDR; - executors[0] = L1_PROPOSAL_EXECUTOR_ADDR; - - TimelockController timelock = new TimelockController(delay, proposers, executors, SECURITY_COUNCIL_ADDR); - - logAddress(string(abi.encodePacked("L1_", label, "_TIMELOCK_ADDR")), address(timelock)); - } - - function logAddress(string memory name, address addr) internal view { - console.log(string(abi.encodePacked(name, "=", vm.toString(address(addr))))); - } -} diff --git a/contracts/scripts/foundry/DeployL2BridgeContracts.s.sol b/contracts/scripts/foundry/DeployL2BridgeContracts.s.sol deleted file mode 100644 index 5ea907707..000000000 --- a/contracts/scripts/foundry/DeployL2BridgeContracts.s.sol +++ /dev/null @@ -1,222 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity =0.8.24; - -// solhint-disable no-console - -import {Script} from "forge-std/Script.sol"; -import {console} from "forge-std/console.sol"; - -import {ProxyAdmin} from "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol"; -import {TransparentUpgradeableProxy} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; - -import {L2CustomERC20Gateway} from "../../src/L2/gateways/L2CustomERC20Gateway.sol"; -import {L2ERC1155Gateway} from "../../src/L2/gateways/L2ERC1155Gateway.sol"; -import {L2ERC721Gateway} from "../../src/L2/gateways/L2ERC721Gateway.sol"; -import {L2ETHGateway} from "../../src/L2/gateways/L2ETHGateway.sol"; -import {L2GatewayRouter} from "../../src/L2/gateways/L2GatewayRouter.sol"; -import {L2ScrollMessenger} from "../../src/L2/L2ScrollMessenger.sol"; -import {L2StandardERC20Gateway} from "../../src/L2/gateways/L2StandardERC20Gateway.sol"; -import {L2WETHGateway} from "../../src/L2/gateways/L2WETHGateway.sol"; -import {L1GasPriceOracle} from "../../src/L2/predeploys/L1GasPriceOracle.sol"; -import {L2MessageQueue} from "../../src/L2/predeploys/L2MessageQueue.sol"; -import {L2TxFeeVault} from "../../src/L2/predeploys/L2TxFeeVault.sol"; -import {Whitelist} from "../../src/L2/predeploys/Whitelist.sol"; -import {ScrollStandardERC20} from "../../src/libraries/token/ScrollStandardERC20.sol"; -import {ScrollStandardERC20Factory} from "../../src/libraries/token/ScrollStandardERC20Factory.sol"; - -// solhint-disable max-states-count -// solhint-disable state-visibility -// solhint-disable var-name-mixedcase - -contract DeployL2BridgeContracts is Script { - uint256 L2_DEPLOYER_PRIVATE_KEY = vm.envUint("L2_DEPLOYER_PRIVATE_KEY"); - - address L2_PROXY_ADMIN_ADDR = vm.envAddress("L2_PROXY_ADMIN_ADDR"); - - address L1_TX_FEE_RECIPIENT_ADDR = vm.envAddress("L1_TX_FEE_RECIPIENT_ADDR"); - address L1_WETH_ADDR = vm.envAddress("L1_WETH_ADDR"); - address L2_WETH_ADDR = vm.envAddress("L2_WETH_ADDR"); - - L1GasPriceOracle oracle; - L2MessageQueue queue; - ProxyAdmin proxyAdmin; - L2GatewayRouter router; - ScrollStandardERC20Factory factory; - - address L2_SCROLL_MESSENGER_PROXY_ADDR = vm.envAddress("L2_SCROLL_MESSENGER_PROXY_ADDR"); - - address L1_SCROLL_MESSENGER_PROXY_ADDR = vm.envAddress("L1_SCROLL_MESSENGER_PROXY_ADDR"); - address L1_CUSTOM_ERC20_GATEWAY_PROXY_ADDR = vm.envAddress("L1_CUSTOM_ERC20_GATEWAY_PROXY_ADDR"); - address L1_ERC721_GATEWAY_PROXY_ADDR = vm.envAddress("L1_ERC721_GATEWAY_PROXY_ADDR"); - address L1_ERC1155_GATEWAY_PROXY_ADDR = vm.envAddress("L1_ERC1155_GATEWAY_PROXY_ADDR"); - address L1_ETH_GATEWAY_PROXY_ADDR = vm.envAddress("L1_ETH_GATEWAY_PROXY_ADDR"); - address L1_STANDARD_ERC20_GATEWAY_PROXY_ADDR = vm.envAddress("L1_STANDARD_ERC20_GATEWAY_PROXY_ADDR"); - address L1_WETH_GATEWAY_PROXY_ADDR = vm.envAddress("L1_WETH_GATEWAY_PROXY_ADDR"); - - // predeploy contracts - address L1_GAS_PRICE_ORACLE_PREDEPLOY_ADDR = vm.envOr("L1_GAS_PRICE_ORACLE_PREDEPLOY_ADDR", address(0)); - address L2_MESSAGE_QUEUE_PREDEPLOY_ADDR = vm.envOr("L2_MESSAGE_QUEUE_PREDEPLOY_ADDR", address(0)); - address L2_TX_FEE_VAULT_PREDEPLOY_ADDR = vm.envOr("L2_TX_FEE_VAULT_PREDEPLOY_ADDR", address(0)); - address L2_WHITELIST_PREDEPLOY_ADDR = vm.envOr("L2_WHITELIST_PREDEPLOY_ADDR", address(0)); - - function run() external { - proxyAdmin = ProxyAdmin(L2_PROXY_ADMIN_ADDR); - - vm.startBroadcast(L2_DEPLOYER_PRIVATE_KEY); - - // predeploys - deployL1GasPriceOracle(); - deployL2MessageQueue(); - deployTxFeeVault(); - deployL2Whitelist(); - - // upgradable - deployL2ScrollMessenger(); - deployL2GatewayRouter(); - deployScrollStandardERC20Factory(); - deployL2StandardERC20Gateway(); - deployL2ETHGateway(); - deployL2WETHGateway(); - deployL2CustomERC20Gateway(); - deployL2ERC721Gateway(); - deployL2ERC1155Gateway(); - - vm.stopBroadcast(); - } - - function deployL1GasPriceOracle() internal { - if (L1_GAS_PRICE_ORACLE_PREDEPLOY_ADDR != address(0)) { - oracle = L1GasPriceOracle(L1_GAS_PRICE_ORACLE_PREDEPLOY_ADDR); - logAddress("L1_GAS_PRICE_ORACLE_ADDR", address(L1_GAS_PRICE_ORACLE_PREDEPLOY_ADDR)); - return; - } - - address owner = vm.addr(L2_DEPLOYER_PRIVATE_KEY); - oracle = new L1GasPriceOracle(owner); - - logAddress("L1_GAS_PRICE_ORACLE_ADDR", address(oracle)); - } - - function deployL2MessageQueue() internal { - if (L2_MESSAGE_QUEUE_PREDEPLOY_ADDR != address(0)) { - queue = L2MessageQueue(L2_MESSAGE_QUEUE_PREDEPLOY_ADDR); - logAddress("L2_MESSAGE_QUEUE_ADDR", address(L2_MESSAGE_QUEUE_PREDEPLOY_ADDR)); - return; - } - - address owner = vm.addr(L2_DEPLOYER_PRIVATE_KEY); - queue = new L2MessageQueue(owner); - - logAddress("L2_MESSAGE_QUEUE_ADDR", address(queue)); - } - - function deployTxFeeVault() internal { - if (L2_TX_FEE_VAULT_PREDEPLOY_ADDR != address(0)) { - logAddress("L2_TX_FEE_VAULT_ADDR", address(L2_TX_FEE_VAULT_PREDEPLOY_ADDR)); - return; - } - - address owner = vm.addr(L2_DEPLOYER_PRIVATE_KEY); - L2TxFeeVault feeVault = new L2TxFeeVault(address(owner), L1_TX_FEE_RECIPIENT_ADDR, 10 ether); - - logAddress("L2_TX_FEE_VAULT_ADDR", address(feeVault)); - } - - function deployL2Whitelist() internal { - if (L2_WHITELIST_PREDEPLOY_ADDR != address(0)) { - logAddress("L2_WHITELIST_ADDR", address(L2_WHITELIST_PREDEPLOY_ADDR)); - return; - } - - address owner = vm.addr(L2_DEPLOYER_PRIVATE_KEY); - Whitelist whitelist = new Whitelist(owner); - - logAddress("L2_WHITELIST_ADDR", address(whitelist)); - } - - function deployL2ScrollMessenger() internal { - L2ScrollMessenger impl = new L2ScrollMessenger(L1_SCROLL_MESSENGER_PROXY_ADDR, address(queue)); - - logAddress("L2_SCROLL_MESSENGER_IMPLEMENTATION_ADDR", address(impl)); - } - - function deployL2GatewayRouter() internal { - L2GatewayRouter impl = new L2GatewayRouter(); - TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy( - address(impl), - address(proxyAdmin), - new bytes(0) - ); - - logAddress("L2_GATEWAY_ROUTER_IMPLEMENTATION_ADDR", address(impl)); - logAddress("L2_GATEWAY_ROUTER_PROXY_ADDR", address(proxy)); - - router = L2GatewayRouter(address(proxy)); - } - - function deployScrollStandardERC20Factory() internal { - ScrollStandardERC20 tokenImpl = new ScrollStandardERC20(); - factory = new ScrollStandardERC20Factory(address(tokenImpl)); - - logAddress("L2_SCROLL_STANDARD_ERC20_ADDR", address(tokenImpl)); - logAddress("L2_SCROLL_STANDARD_ERC20_FACTORY_ADDR", address(factory)); - } - - function deployL2StandardERC20Gateway() internal { - L2StandardERC20Gateway impl = new L2StandardERC20Gateway( - L1_STANDARD_ERC20_GATEWAY_PROXY_ADDR, - address(router), - L2_SCROLL_MESSENGER_PROXY_ADDR, - address(factory) - ); - - logAddress("L2_STANDARD_ERC20_GATEWAY_IMPLEMENTATION_ADDR", address(impl)); - } - - function deployL2ETHGateway() internal { - L2ETHGateway impl = new L2ETHGateway( - L1_ETH_GATEWAY_PROXY_ADDR, - address(router), - L2_SCROLL_MESSENGER_PROXY_ADDR - ); - - logAddress("L2_ETH_GATEWAY_IMPLEMENTATION_ADDR", address(impl)); - } - - function deployL2WETHGateway() internal { - L2WETHGateway impl = new L2WETHGateway( - L2_WETH_ADDR, - L1_WETH_ADDR, - L1_WETH_GATEWAY_PROXY_ADDR, - address(router), - L2_SCROLL_MESSENGER_PROXY_ADDR - ); - - logAddress("L2_WETH_GATEWAY_IMPLEMENTATION_ADDR", address(impl)); - } - - function deployL2CustomERC20Gateway() internal { - L2CustomERC20Gateway impl = new L2CustomERC20Gateway( - L1_CUSTOM_ERC20_GATEWAY_PROXY_ADDR, - address(router), - L2_SCROLL_MESSENGER_PROXY_ADDR - ); - - logAddress("L2_CUSTOM_ERC20_GATEWAY_IMPLEMENTATION_ADDR", address(impl)); - } - - function deployL2ERC721Gateway() internal { - L2ERC721Gateway impl = new L2ERC721Gateway(L1_ERC721_GATEWAY_PROXY_ADDR, L2_SCROLL_MESSENGER_PROXY_ADDR); - - logAddress("L2_ERC721_GATEWAY_IMPLEMENTATION_ADDR", address(impl)); - } - - function deployL2ERC1155Gateway() internal { - L2ERC1155Gateway impl = new L2ERC1155Gateway(L1_ERC1155_GATEWAY_PROXY_ADDR, L2_SCROLL_MESSENGER_PROXY_ADDR); - logAddress("L2_ERC1155_GATEWAY_IMPLEMENTATION_ADDR", address(impl)); - } - - function logAddress(string memory name, address addr) internal view { - console.log(string(abi.encodePacked(name, "=", vm.toString(address(addr))))); - } -} diff --git a/contracts/scripts/foundry/DeployL2BridgeProxyPlaceholder.s.sol b/contracts/scripts/foundry/DeployL2BridgeProxyPlaceholder.s.sol deleted file mode 100644 index 94c214b99..000000000 --- a/contracts/scripts/foundry/DeployL2BridgeProxyPlaceholder.s.sol +++ /dev/null @@ -1,125 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity =0.8.24; - -// solhint-disable no-console - -import {Script} from "forge-std/Script.sol"; -import {console} from "forge-std/console.sol"; - -import {ProxyAdmin} from "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol"; -import {TransparentUpgradeableProxy} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; - -import {EmptyContract} from "../../src/misc/EmptyContract.sol"; - -// solhint-disable state-visibility -// solhint-disable var-name-mixedcase - -contract DeployL2BridgeProxyPlaceholder is Script { - uint256 L2_DEPLOYER_PRIVATE_KEY = vm.envUint("L2_DEPLOYER_PRIVATE_KEY"); - - ProxyAdmin proxyAdmin; - EmptyContract placeholder; - - function run() external { - vm.startBroadcast(L2_DEPLOYER_PRIVATE_KEY); - - // upgradable - deployProxyAdmin(); - deployPlaceHolder(); - deployL2ScrollMessenger(); - deployL2ETHGateway(); - deployL2WETHGateway(); - deployL2StandardERC20Gateway(); - deployL2CustomERC20Gateway(); - deployL2ERC721Gateway(); - deployL2ERC1155Gateway(); - - vm.stopBroadcast(); - } - - function deployProxyAdmin() internal { - proxyAdmin = new ProxyAdmin(); - - logAddress("L2_PROXY_ADMIN_ADDR", address(proxyAdmin)); - } - - function deployPlaceHolder() internal { - placeholder = new EmptyContract(); - - logAddress("L2_PROXY_IMPLEMENTATION_PLACEHOLDER_ADDR", address(placeholder)); - } - - function deployL2ScrollMessenger() internal { - TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy( - address(placeholder), - address(proxyAdmin), - new bytes(0) - ); - - logAddress("L2_SCROLL_MESSENGER_PROXY_ADDR", address(proxy)); - } - - function deployL2StandardERC20Gateway() internal { - TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy( - address(placeholder), - address(proxyAdmin), - new bytes(0) - ); - - logAddress("L2_STANDARD_ERC20_GATEWAY_PROXY_ADDR", address(proxy)); - } - - function deployL2ETHGateway() internal { - TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy( - address(placeholder), - address(proxyAdmin), - new bytes(0) - ); - - logAddress("L2_ETH_GATEWAY_PROXY_ADDR", address(proxy)); - } - - function deployL2WETHGateway() internal { - TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy( - address(placeholder), - address(proxyAdmin), - new bytes(0) - ); - - logAddress("L2_WETH_GATEWAY_PROXY_ADDR", address(proxy)); - } - - function deployL2CustomERC20Gateway() internal { - TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy( - address(placeholder), - address(proxyAdmin), - new bytes(0) - ); - - logAddress("L2_CUSTOM_ERC20_GATEWAY_PROXY_ADDR", address(proxy)); - } - - function deployL2ERC721Gateway() internal { - TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy( - address(placeholder), - address(proxyAdmin), - new bytes(0) - ); - - logAddress("L2_ERC721_GATEWAY_PROXY_ADDR", address(proxy)); - } - - function deployL2ERC1155Gateway() internal { - TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy( - address(placeholder), - address(proxyAdmin), - new bytes(0) - ); - - logAddress("L2_ERC1155_GATEWAY_PROXY_ADDR", address(proxy)); - } - - function logAddress(string memory name, address addr) internal view { - console.log(string(abi.encodePacked(name, "=", vm.toString(address(addr))))); - } -} diff --git a/contracts/scripts/foundry/DeployL2ScrollOwner.s.sol b/contracts/scripts/foundry/DeployL2ScrollOwner.s.sol deleted file mode 100644 index fe20dac0a..000000000 --- a/contracts/scripts/foundry/DeployL2ScrollOwner.s.sol +++ /dev/null @@ -1,66 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity =0.8.24; - -import {Script} from "forge-std/Script.sol"; -import {console} from "forge-std/console.sol"; - -import {TimelockController} from "@openzeppelin/contracts/governance/TimelockController.sol"; - -import {ScrollOwner} from "../../src/misc/ScrollOwner.sol"; - -// solhint-disable state-visibility -// solhint-disable var-name-mixedcase - -contract DeployL2ScrollOwner is Script { - string NETWORK = vm.envString("NETWORK"); - - uint256 L2_DEPLOYER_PRIVATE_KEY = vm.envUint("L2_DEPLOYER_PRIVATE_KEY"); - - address SCROLL_MULTISIG_ADDR = vm.envAddress("L2_SCROLL_MULTISIG_ADDR"); - - address SECURITY_COUNCIL_ADDR = vm.envAddress("L2_SECURITY_COUNCIL_ADDR"); - - address L2_PROPOSAL_EXECUTOR_ADDR = vm.envAddress("L2_PROPOSAL_EXECUTOR_ADDR"); - - function run() external { - vm.startBroadcast(L2_DEPLOYER_PRIVATE_KEY); - - deployScrollOwner(); - - if (keccak256(abi.encodePacked(NETWORK)) == keccak256(abi.encodePacked("sepolia"))) { - // for sepolia - deployTimelockController("1D", 1 minutes); - deployTimelockController("7D", 7 minutes); - deployTimelockController("14D", 14 minutes); - } else if (keccak256(abi.encodePacked(NETWORK)) == keccak256(abi.encodePacked("mainnet"))) { - // for mainnet - deployTimelockController("1D", 1 days); - deployTimelockController("7D", 7 days); - deployTimelockController("14D", 14 days); - } - - vm.stopBroadcast(); - } - - function deployScrollOwner() internal { - ScrollOwner owner = new ScrollOwner(); - - logAddress("L2_SCROLL_OWNER_ADDR", address(owner)); - } - - function deployTimelockController(string memory label, uint256 delay) internal { - address[] memory proposers = new address[](1); - address[] memory executors = new address[](1); - - proposers[0] = SCROLL_MULTISIG_ADDR; - executors[0] = L2_PROPOSAL_EXECUTOR_ADDR; - - TimelockController timelock = new TimelockController(delay, proposers, executors, SECURITY_COUNCIL_ADDR); - - logAddress(string(abi.encodePacked("L2_", label, "_TIMELOCK_ADDR")), address(timelock)); - } - - function logAddress(string memory name, address addr) internal view { - console.log(string(abi.encodePacked(name, "=", vm.toString(address(addr))))); - } -} diff --git a/contracts/scripts/foundry/DeployLidoGateway.s.sol b/contracts/scripts/foundry/DeployLidoGateway.s.sol deleted file mode 100644 index 2619bd857..000000000 --- a/contracts/scripts/foundry/DeployLidoGateway.s.sol +++ /dev/null @@ -1,63 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.10; - -import {Script} from "forge-std/Script.sol"; -import {console} from "forge-std/console.sol"; - -import {L1LidoGateway} from "../../src/lido/L1LidoGateway.sol"; -import {L2LidoGateway} from "../../src/lido/L2LidoGateway.sol"; - -// solhint-disable state-visibility -// solhint-disable var-name-mixedcase - -contract DeployLidoGateway is Script { - string NETWORK = vm.envString("NETWORK"); - - uint256 L1_DEPLOYER_PRIVATE_KEY = vm.envUint("L1_DEPLOYER_PRIVATE_KEY"); - - uint256 L2_DEPLOYER_PRIVATE_KEY = vm.envUint("L2_DEPLOYER_PRIVATE_KEY"); - - address L1_WSTETH_ADDR = vm.envAddress("L1_WSTETH_ADDR"); - - address L2_WSTETH_ADDR = vm.envAddress("L2_WSTETH_ADDR"); - - address L1_SCROLL_MESSENGER_PROXY_ADDR = vm.envAddress("L1_SCROLL_MESSENGER_PROXY_ADDR"); - address L1_GATEWAY_ROUTER_PROXY_ADDR = vm.envAddress("L1_GATEWAY_ROUTER_PROXY_ADDR"); - address L1_LIDO_GATEWAY_PROXY_ADDR = vm.envAddress("L1_LIDO_GATEWAY_PROXY_ADDR"); - - address L2_SCROLL_MESSENGER_PROXY_ADDR = vm.envAddress("L2_SCROLL_MESSENGER_PROXY_ADDR"); - address L2_GATEWAY_ROUTER_PROXY_ADDR = vm.envAddress("L2_GATEWAY_ROUTER_PROXY_ADDR"); - address L2_LIDO_GATEWAY_PROXY_ADDR = vm.envAddress("L2_LIDO_GATEWAY_PROXY_ADDR"); - - function run() external { - vm.startBroadcast(L2_DEPLOYER_PRIVATE_KEY); - - if (keccak256(abi.encodePacked(NETWORK)) == keccak256(abi.encodePacked("L1"))) { - // deploy l1 lido gateway - L1LidoGateway gateway = new L1LidoGateway( - L1_WSTETH_ADDR, - L2_WSTETH_ADDR, - L2_LIDO_GATEWAY_PROXY_ADDR, - L1_GATEWAY_ROUTER_PROXY_ADDR, - L1_SCROLL_MESSENGER_PROXY_ADDR - ); - logAddress("L1_LIDO_GATEWAY_IMPLEMENTATION_ADDR", address(gateway)); - } else if (keccak256(abi.encodePacked(NETWORK)) == keccak256(abi.encodePacked("L2"))) { - // deploy l2 lido gateway - L2LidoGateway gateway = new L2LidoGateway( - L1_WSTETH_ADDR, - L2_WSTETH_ADDR, - L1_LIDO_GATEWAY_PROXY_ADDR, - L2_GATEWAY_ROUTER_PROXY_ADDR, - L2_SCROLL_MESSENGER_PROXY_ADDR - ); - logAddress("L2_LIDO_GATEWAY_IMPLEMENTATION_ADDR", address(gateway)); - } - - vm.stopBroadcast(); - } - - function logAddress(string memory name, address addr) internal view { - console.log(string(abi.encodePacked(name, "=", vm.toString(address(addr))))); - } -} diff --git a/contracts/scripts/foundry/DeployScrollChainCommitmentVerifier.s.sol b/contracts/scripts/foundry/DeployScrollChainCommitmentVerifier.s.sol deleted file mode 100644 index 1347b0173..000000000 --- a/contracts/scripts/foundry/DeployScrollChainCommitmentVerifier.s.sol +++ /dev/null @@ -1,36 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity =0.8.24; - -import {Script} from "forge-std/Script.sol"; -import {console} from "forge-std/console.sol"; - -import {ScrollChainCommitmentVerifier} from "../../src/L1/rollup/ScrollChainCommitmentVerifier.sol"; - -contract DeployScrollChainCommitmentVerifier is Script { - uint256 L1_DEPLOYER_PRIVATE_KEY = vm.envUint("L1_DEPLOYER_PRIVATE_KEY"); - - address L1_SCROLL_CHAIN_PROXY_ADDR = vm.envAddress("L1_SCROLL_CHAIN_PROXY_ADDR"); - - address POSEIDON_UNIT2_ADDR = vm.envAddress("POSEIDON_UNIT2_ADDR"); - - function run() external { - vm.startBroadcast(L1_DEPLOYER_PRIVATE_KEY); - - deployScrollChainCommitmentVerifier(); - - vm.stopBroadcast(); - } - - function deployScrollChainCommitmentVerifier() internal { - ScrollChainCommitmentVerifier verifier = new ScrollChainCommitmentVerifier( - POSEIDON_UNIT2_ADDR, - L1_SCROLL_CHAIN_PROXY_ADDR - ); - - logAddress("L1_SCROLL_CHAIN_COMMITMENT_VERIFIER", address(verifier)); - } - - function logAddress(string memory name, address addr) internal view { - console.log(string(abi.encodePacked(name, "=", vm.toString(address(addr))))); - } -} diff --git a/contracts/scripts/foundry/DeployWeth.s.sol b/contracts/scripts/foundry/DeployWeth.s.sol deleted file mode 100644 index 3b1976d71..000000000 --- a/contracts/scripts/foundry/DeployWeth.s.sol +++ /dev/null @@ -1,30 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity =0.8.24; - -import {Script} from "forge-std/Script.sol"; -import {console} from "forge-std/console.sol"; - -import {WrappedEther} from "../../src/L2/predeploys/WrappedEther.sol"; - -contract DeployWeth is Script { - address L1_WETH_ADDR = vm.envAddress("L1_WETH_ADDR"); - address L2_WETH_ADDR = vm.envAddress("L2_WETH_ADDR"); - - function run() external { - // deploy weth only if we're running a private L1 network - if (L1_WETH_ADDR == address(0)) { - uint256 L1_WETH_DEPLOYER_PRIVATE_KEY = vm.envUint("L1_WETH_DEPLOYER_PRIVATE_KEY"); - vm.startBroadcast(L1_WETH_DEPLOYER_PRIVATE_KEY); - WrappedEther weth = new WrappedEther(); - L1_WETH_ADDR = address(weth); - vm.stopBroadcast(); - } - - logAddress("L1_WETH_ADDR", L1_WETH_ADDR); - logAddress("L2_WETH_ADDR", L2_WETH_ADDR); - } - - function logAddress(string memory name, address addr) internal view { - console.log(string(abi.encodePacked(name, "=", vm.toString(address(addr))))); - } -} diff --git a/contracts/scripts/foundry/InitializeL1BridgeContracts.s.sol b/contracts/scripts/foundry/InitializeL1BridgeContracts.s.sol deleted file mode 100644 index 790cea353..000000000 --- a/contracts/scripts/foundry/InitializeL1BridgeContracts.s.sol +++ /dev/null @@ -1,229 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity =0.8.24; - -import {Script} from "forge-std/Script.sol"; - -import {ProxyAdmin} from "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol"; -import {ITransparentUpgradeableProxy} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; - -import {L1CustomERC20Gateway} from "../../src/L1/gateways/L1CustomERC20Gateway.sol"; -import {L1ERC1155Gateway} from "../../src/L1/gateways/L1ERC1155Gateway.sol"; -import {L1ERC721Gateway} from "../../src/L1/gateways/L1ERC721Gateway.sol"; -import {L1ETHGateway} from "../../src/L1/gateways/L1ETHGateway.sol"; -import {L1GatewayRouter} from "../../src/L1/gateways/L1GatewayRouter.sol"; -import {L1ScrollMessenger} from "../../src/L1/L1ScrollMessenger.sol"; -import {L1StandardERC20Gateway} from "../../src/L1/gateways/L1StandardERC20Gateway.sol"; -import {L1WETHGateway} from "../../src/L1/gateways/L1WETHGateway.sol"; -import {MultipleVersionRollupVerifier} from "../../src/L1/rollup/MultipleVersionRollupVerifier.sol"; -import {ScrollChain} from "../../src/L1/rollup/ScrollChain.sol"; -import {L1MessageQueue} from "../../src/L1/rollup/L1MessageQueue.sol"; -import {L1MessageQueueWithGasPriceOracle} from "../../src/L1/rollup/L1MessageQueueWithGasPriceOracle.sol"; -import {L2GasPriceOracle} from "../../src/L1/rollup/L2GasPriceOracle.sol"; -import {EnforcedTxGateway} from "../../src/L1/gateways/EnforcedTxGateway.sol"; - -// solhint-disable max-states-count -// solhint-disable state-visibility -// solhint-disable var-name-mixedcase - -contract InitializeL1BridgeContracts is Script { - uint256 L1_DEPLOYER_PRIVATE_KEY = vm.envUint("L1_DEPLOYER_PRIVATE_KEY"); - - uint256 CHAIN_ID_L2 = vm.envUint("CHAIN_ID_L2"); - uint256 MAX_TX_IN_CHUNK = vm.envUint("MAX_TX_IN_CHUNK"); - uint256 MAX_L1_MESSAGE_GAS_LIMIT = vm.envUint("MAX_L1_MESSAGE_GAS_LIMIT"); - address L1_COMMIT_SENDER_ADDRESS = vm.envAddress("L1_COMMIT_SENDER_ADDRESS"); - address L1_FINALIZE_SENDER_ADDRESS = vm.envAddress("L1_FINALIZE_SENDER_ADDRESS"); - address L1_FEE_VAULT_ADDR = vm.envAddress("L1_FEE_VAULT_ADDR"); - address L1_WETH_ADDR = vm.envAddress("L1_WETH_ADDR"); - - address L1_PROXY_ADMIN_ADDR = vm.envAddress("L1_PROXY_ADMIN_ADDR"); - - address L1_WHITELIST_ADDR = vm.envAddress("L1_WHITELIST_ADDR"); - address L1_SCROLL_CHAIN_PROXY_ADDR = vm.envAddress("L1_SCROLL_CHAIN_PROXY_ADDR"); - address L1_SCROLL_CHAIN_IMPLEMENTATION_ADDR = vm.envAddress("L1_SCROLL_CHAIN_IMPLEMENTATION_ADDR"); - address L1_MESSAGE_QUEUE_PROXY_ADDR = vm.envAddress("L1_MESSAGE_QUEUE_PROXY_ADDR"); - address L1_MESSAGE_QUEUE_IMPLEMENTATION_ADDR = vm.envAddress("L1_MESSAGE_QUEUE_IMPLEMENTATION_ADDR"); - address L2_GAS_PRICE_ORACLE_PROXY_ADDR = vm.envAddress("L2_GAS_PRICE_ORACLE_PROXY_ADDR"); - address L1_SCROLL_MESSENGER_PROXY_ADDR = vm.envAddress("L1_SCROLL_MESSENGER_PROXY_ADDR"); - address L1_SCROLL_MESSENGER_IMPLEMENTATION_ADDR = vm.envAddress("L1_SCROLL_MESSENGER_IMPLEMENTATION_ADDR"); - address L1_GATEWAY_ROUTER_PROXY_ADDR = vm.envAddress("L1_GATEWAY_ROUTER_PROXY_ADDR"); - address L1_CUSTOM_ERC20_GATEWAY_PROXY_ADDR = vm.envAddress("L1_CUSTOM_ERC20_GATEWAY_PROXY_ADDR"); - address L1_CUSTOM_ERC20_GATEWAY_IMPLEMENTATION_ADDR = vm.envAddress("L1_CUSTOM_ERC20_GATEWAY_IMPLEMENTATION_ADDR"); - address L1_ERC721_GATEWAY_PROXY_ADDR = vm.envAddress("L1_ERC721_GATEWAY_PROXY_ADDR"); - address L1_ERC721_GATEWAY_IMPLEMENTATION_ADDR = vm.envAddress("L1_ERC721_GATEWAY_IMPLEMENTATION_ADDR"); - address L1_ERC1155_GATEWAY_PROXY_ADDR = vm.envAddress("L1_ERC1155_GATEWAY_PROXY_ADDR"); - address L1_ERC1155_GATEWAY_IMPLEMENTATION_ADDR = vm.envAddress("L1_ERC1155_GATEWAY_IMPLEMENTATION_ADDR"); - address L1_ETH_GATEWAY_PROXY_ADDR = vm.envAddress("L1_ETH_GATEWAY_PROXY_ADDR"); - address L1_ETH_GATEWAY_IMPLEMENTATION_ADDR = vm.envAddress("L1_ETH_GATEWAY_IMPLEMENTATION_ADDR"); - address L1_STANDARD_ERC20_GATEWAY_PROXY_ADDR = vm.envAddress("L1_STANDARD_ERC20_GATEWAY_PROXY_ADDR"); - address L1_STANDARD_ERC20_GATEWAY_IMPLEMENTATION_ADDR = - vm.envAddress("L1_STANDARD_ERC20_GATEWAY_IMPLEMENTATION_ADDR"); - address L1_WETH_GATEWAY_PROXY_ADDR = vm.envAddress("L1_WETH_GATEWAY_PROXY_ADDR"); - address L1_WETH_GATEWAY_IMPLEMENTATION_ADDR = vm.envAddress("L1_WETH_GATEWAY_IMPLEMENTATION_ADDR"); - address L1_MULTIPLE_VERSION_ROLLUP_VERIFIER_ADDR = vm.envAddress("L1_MULTIPLE_VERSION_ROLLUP_VERIFIER_ADDR"); - address L1_ENFORCED_TX_GATEWAY_PROXY_ADDR = vm.envAddress("L1_ENFORCED_TX_GATEWAY_PROXY_ADDR"); - - address L2_SCROLL_MESSENGER_PROXY_ADDR = vm.envAddress("L2_SCROLL_MESSENGER_PROXY_ADDR"); - address L2_CUSTOM_ERC20_GATEWAY_PROXY_ADDR = vm.envAddress("L2_CUSTOM_ERC20_GATEWAY_PROXY_ADDR"); - address L2_ERC721_GATEWAY_PROXY_ADDR = vm.envAddress("L2_ERC721_GATEWAY_PROXY_ADDR"); - address L2_ERC1155_GATEWAY_PROXY_ADDR = vm.envAddress("L2_ERC1155_GATEWAY_PROXY_ADDR"); - address L2_ETH_GATEWAY_PROXY_ADDR = vm.envAddress("L2_ETH_GATEWAY_PROXY_ADDR"); - address L2_STANDARD_ERC20_GATEWAY_PROXY_ADDR = vm.envAddress("L2_STANDARD_ERC20_GATEWAY_PROXY_ADDR"); - address L2_WETH_GATEWAY_PROXY_ADDR = vm.envAddress("L2_WETH_GATEWAY_PROXY_ADDR"); - address L2_SCROLL_STANDARD_ERC20_ADDR = vm.envAddress("L2_SCROLL_STANDARD_ERC20_ADDR"); - address L2_SCROLL_STANDARD_ERC20_FACTORY_ADDR = vm.envAddress("L2_SCROLL_STANDARD_ERC20_FACTORY_ADDR"); - - function run() external { - ProxyAdmin proxyAdmin = ProxyAdmin(L1_PROXY_ADMIN_ADDR); - - vm.startBroadcast(L1_DEPLOYER_PRIVATE_KEY); - - // note: we use call upgrade(...) and initialize(...) instead of upgradeAndCall(...), - // otherwise the contract owner would become ProxyAdmin. - - // initialize ScrollChain - proxyAdmin.upgrade( - ITransparentUpgradeableProxy(L1_SCROLL_CHAIN_PROXY_ADDR), - L1_SCROLL_CHAIN_IMPLEMENTATION_ADDR - ); - - ScrollChain(L1_SCROLL_CHAIN_PROXY_ADDR).initialize( - L1_MESSAGE_QUEUE_PROXY_ADDR, - L1_MULTIPLE_VERSION_ROLLUP_VERIFIER_ADDR, - MAX_TX_IN_CHUNK - ); - - ScrollChain(L1_SCROLL_CHAIN_PROXY_ADDR).addSequencer(L1_COMMIT_SENDER_ADDRESS); - ScrollChain(L1_SCROLL_CHAIN_PROXY_ADDR).addProver(L1_FINALIZE_SENDER_ADDRESS); - - // initialize L2GasPriceOracle - L2GasPriceOracle(L2_GAS_PRICE_ORACLE_PROXY_ADDR).initialize( - 21000, // _txGas - 53000, // _txGasContractCreation - 4, // _zeroGas - 16 // _nonZeroGas - ); - L2GasPriceOracle(L2_GAS_PRICE_ORACLE_PROXY_ADDR).updateWhitelist(L1_WHITELIST_ADDR); - - // initialize L1MessageQueueWithGasPriceOracle - proxyAdmin.upgrade( - ITransparentUpgradeableProxy(L1_MESSAGE_QUEUE_PROXY_ADDR), - L1_MESSAGE_QUEUE_IMPLEMENTATION_ADDR - ); - - L1MessageQueueWithGasPriceOracle(L1_MESSAGE_QUEUE_PROXY_ADDR).initialize( - L1_SCROLL_MESSENGER_PROXY_ADDR, - L1_SCROLL_CHAIN_PROXY_ADDR, - L1_ENFORCED_TX_GATEWAY_PROXY_ADDR, - L2_GAS_PRICE_ORACLE_PROXY_ADDR, - MAX_L1_MESSAGE_GAS_LIMIT - ); - - L1MessageQueueWithGasPriceOracle(L1_MESSAGE_QUEUE_PROXY_ADDR).initializeV2(); - - // initialize L1ScrollMessenger - proxyAdmin.upgrade( - ITransparentUpgradeableProxy(L1_SCROLL_MESSENGER_PROXY_ADDR), - L1_SCROLL_MESSENGER_IMPLEMENTATION_ADDR - ); - - L1ScrollMessenger(payable(L1_SCROLL_MESSENGER_PROXY_ADDR)).initialize( - L2_SCROLL_MESSENGER_PROXY_ADDR, - L1_FEE_VAULT_ADDR, - L1_SCROLL_CHAIN_PROXY_ADDR, - L1_MESSAGE_QUEUE_PROXY_ADDR - ); - - // initialize EnforcedTxGateway - EnforcedTxGateway(payable(L1_ENFORCED_TX_GATEWAY_PROXY_ADDR)).initialize( - L1_MESSAGE_QUEUE_PROXY_ADDR, - L1_FEE_VAULT_ADDR - ); - - // initialize L1GatewayRouter - L1GatewayRouter(L1_GATEWAY_ROUTER_PROXY_ADDR).initialize( - L1_ETH_GATEWAY_PROXY_ADDR, - L1_STANDARD_ERC20_GATEWAY_PROXY_ADDR - ); - - // initialize L1CustomERC20Gateway - proxyAdmin.upgrade( - ITransparentUpgradeableProxy(L1_CUSTOM_ERC20_GATEWAY_PROXY_ADDR), - L1_CUSTOM_ERC20_GATEWAY_IMPLEMENTATION_ADDR - ); - - L1CustomERC20Gateway(L1_CUSTOM_ERC20_GATEWAY_PROXY_ADDR).initialize( - L2_CUSTOM_ERC20_GATEWAY_PROXY_ADDR, - L1_GATEWAY_ROUTER_PROXY_ADDR, - L1_SCROLL_MESSENGER_PROXY_ADDR - ); - - // initialize L1ERC1155Gateway - proxyAdmin.upgrade( - ITransparentUpgradeableProxy(L1_ERC1155_GATEWAY_PROXY_ADDR), - L1_ERC1155_GATEWAY_IMPLEMENTATION_ADDR - ); - - L1ERC1155Gateway(L1_ERC1155_GATEWAY_PROXY_ADDR).initialize( - L2_ERC1155_GATEWAY_PROXY_ADDR, - L1_SCROLL_MESSENGER_PROXY_ADDR - ); - - // initialize L1ERC721Gateway - proxyAdmin.upgrade( - ITransparentUpgradeableProxy(L1_ERC721_GATEWAY_PROXY_ADDR), - L1_ERC721_GATEWAY_IMPLEMENTATION_ADDR - ); - - L1ERC721Gateway(L1_ERC721_GATEWAY_PROXY_ADDR).initialize( - L2_ERC721_GATEWAY_PROXY_ADDR, - L1_SCROLL_MESSENGER_PROXY_ADDR - ); - - // initialize L1ETHGateway - proxyAdmin.upgrade(ITransparentUpgradeableProxy(L1_ETH_GATEWAY_PROXY_ADDR), L1_ETH_GATEWAY_IMPLEMENTATION_ADDR); - - L1ETHGateway(L1_ETH_GATEWAY_PROXY_ADDR).initialize( - L2_ETH_GATEWAY_PROXY_ADDR, - L1_GATEWAY_ROUTER_PROXY_ADDR, - L1_SCROLL_MESSENGER_PROXY_ADDR - ); - - // initialize L1StandardERC20Gateway - proxyAdmin.upgrade( - ITransparentUpgradeableProxy(L1_STANDARD_ERC20_GATEWAY_PROXY_ADDR), - L1_STANDARD_ERC20_GATEWAY_IMPLEMENTATION_ADDR - ); - - L1StandardERC20Gateway(L1_STANDARD_ERC20_GATEWAY_PROXY_ADDR).initialize( - L2_STANDARD_ERC20_GATEWAY_PROXY_ADDR, - L1_GATEWAY_ROUTER_PROXY_ADDR, - L1_SCROLL_MESSENGER_PROXY_ADDR, - L2_SCROLL_STANDARD_ERC20_ADDR, - L2_SCROLL_STANDARD_ERC20_FACTORY_ADDR - ); - - // initialize L1WETHGateway - proxyAdmin.upgrade( - ITransparentUpgradeableProxy(L1_WETH_GATEWAY_PROXY_ADDR), - L1_WETH_GATEWAY_IMPLEMENTATION_ADDR - ); - - L1WETHGateway(payable(L1_WETH_GATEWAY_PROXY_ADDR)).initialize( - L2_WETH_GATEWAY_PROXY_ADDR, - L1_GATEWAY_ROUTER_PROXY_ADDR, - L1_SCROLL_MESSENGER_PROXY_ADDR - ); - - // set WETH gateway in router - { - address[] memory _tokens = new address[](1); - _tokens[0] = L1_WETH_ADDR; - address[] memory _gateways = new address[](1); - _gateways[0] = L1_WETH_GATEWAY_PROXY_ADDR; - L1GatewayRouter(L1_GATEWAY_ROUTER_PROXY_ADDR).setERC20Gateway(_tokens, _gateways); - } - - vm.stopBroadcast(); - } -} diff --git a/contracts/scripts/foundry/InitializeL1ScrollOwner.s.sol b/contracts/scripts/foundry/InitializeL1ScrollOwner.s.sol deleted file mode 100644 index b2af8e9d4..000000000 --- a/contracts/scripts/foundry/InitializeL1ScrollOwner.s.sol +++ /dev/null @@ -1,275 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity =0.8.24; - -import {Script} from "forge-std/Script.sol"; - -import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; -import {ProxyAdmin} from "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol"; - -import {L1ScrollMessenger} from "../../src/L1/L1ScrollMessenger.sol"; -import {L1USDCGateway} from "../../src/L1/gateways/usdc/L1USDCGateway.sol"; -import {EnforcedTxGateway} from "../../src/L1/gateways/EnforcedTxGateway.sol"; -import {L1CustomERC20Gateway} from "../../src/L1/gateways/L1CustomERC20Gateway.sol"; -import {L1ERC1155Gateway} from "../../src/L1/gateways/L1ERC1155Gateway.sol"; -import {L1ERC721Gateway} from "../../src/L1/gateways/L1ERC721Gateway.sol"; -import {L1GatewayRouter} from "../../src/L1/gateways/L1GatewayRouter.sol"; -import {L1MessageQueue} from "../../src/L1/rollup/L1MessageQueue.sol"; -import {ScrollMessengerBase} from "../../src/libraries/ScrollMessengerBase.sol"; -import {L2GasPriceOracle} from "../../src/L1/rollup/L2GasPriceOracle.sol"; -import {MultipleVersionRollupVerifier} from "../../src/L1/rollup/MultipleVersionRollupVerifier.sol"; -import {ScrollChain} from "../../src/L1/rollup/ScrollChain.sol"; -import {ScrollOwner} from "../../src/misc/ScrollOwner.sol"; -import {Whitelist} from "../../src/L2/predeploys/Whitelist.sol"; - -// solhint-disable max-states-count -// solhint-disable state-visibility -// solhint-disable var-name-mixedcase - -contract InitializeL1ScrollOwner is Script { - uint256 L1_DEPLOYER_PRIVATE_KEY = vm.envUint("L1_DEPLOYER_PRIVATE_KEY"); - - bytes32 constant SECURITY_COUNCIL_NO_DELAY_ROLE = keccak256("SECURITY_COUNCIL_NO_DELAY_ROLE"); - bytes32 constant SCROLL_MULTISIG_NO_DELAY_ROLE = keccak256("SCROLL_MULTISIG_NO_DELAY_ROLE"); - bytes32 constant EMERGENCY_MULTISIG_NO_DELAY_ROLE = keccak256("EMERGENCY_MULTISIG_NO_DELAY_ROLE"); - - bytes32 constant TIMELOCK_1DAY_DELAY_ROLE = keccak256("TIMELOCK_1DAY_DELAY_ROLE"); - bytes32 constant TIMELOCK_7DAY_DELAY_ROLE = keccak256("TIMELOCK_7DAY_DELAY_ROLE"); - - address SCROLL_MULTISIG_ADDR = vm.envAddress("L1_SCROLL_MULTISIG_ADDR"); - address SECURITY_COUNCIL_ADDR = vm.envAddress("L1_SECURITY_COUNCIL_ADDR"); - address EMERGENCY_MULTISIG_ADDR = vm.envAddress("L1_EMERGENCY_MULTISIG_ADDR"); - - address L1_SCROLL_OWNER_ADDR = vm.envAddress("L1_SCROLL_OWNER_ADDR"); - address L1_1D_TIMELOCK_ADDR = vm.envAddress("L1_1D_TIMELOCK_ADDR"); - address L1_7D_TIMELOCK_ADDR = vm.envAddress("L1_7D_TIMELOCK_ADDR"); - address L1_14D_TIMELOCK_ADDR = vm.envAddress("L1_14D_TIMELOCK_ADDR"); - - address L1_PROXY_ADMIN_ADDR = vm.envAddress("L1_PROXY_ADMIN_ADDR"); - address L1_SCROLL_CHAIN_PROXY_ADDR = vm.envAddress("L1_SCROLL_CHAIN_PROXY_ADDR"); - address L1_MESSAGE_QUEUE_PROXY_ADDR = vm.envAddress("L1_MESSAGE_QUEUE_PROXY_ADDR"); - address L2_GAS_PRICE_ORACLE_PROXY_ADDR = vm.envAddress("L2_GAS_PRICE_ORACLE_PROXY_ADDR"); - address L1_SCROLL_MESSENGER_PROXY_ADDR = vm.envAddress("L1_SCROLL_MESSENGER_PROXY_ADDR"); - address L1_GATEWAY_ROUTER_PROXY_ADDR = vm.envAddress("L1_GATEWAY_ROUTER_PROXY_ADDR"); - address L1_CUSTOM_ERC20_GATEWAY_PROXY_ADDR = vm.envAddress("L1_CUSTOM_ERC20_GATEWAY_PROXY_ADDR"); - address L1_DAI_GATEWAY_PROXY_ADDR = vm.envAddress("L1_DAI_GATEWAY_PROXY_ADDR"); - address L1_LIDO_GATEWAY_PROXY_ADDR = vm.envAddress("L1_LIDO_GATEWAY_PROXY_ADDR"); - address L1_ETH_GATEWAY_PROXY_ADDR = vm.envAddress("L1_ETH_GATEWAY_PROXY_ADDR"); - address L1_STANDARD_ERC20_GATEWAY_PROXY_ADDR = vm.envAddress("L1_STANDARD_ERC20_GATEWAY_PROXY_ADDR"); - address L1_USDC_GATEWAY_PROXY_ADDR = vm.envAddress("L1_USDC_GATEWAY_PROXY_ADDR"); - address L1_WETH_GATEWAY_PROXY_ADDR = vm.envAddress("L1_WETH_GATEWAY_PROXY_ADDR"); - address L1_ERC721_GATEWAY_PROXY_ADDR = vm.envAddress("L1_ERC721_GATEWAY_PROXY_ADDR"); - address L1_ERC1155_GATEWAY_PROXY_ADDR = vm.envAddress("L1_ERC1155_GATEWAY_PROXY_ADDR"); - address L1_MULTIPLE_VERSION_ROLLUP_VERIFIER_ADDR = vm.envAddress("L1_MULTIPLE_VERSION_ROLLUP_VERIFIER_ADDR"); - address L1_ENFORCED_TX_GATEWAY_PROXY_ADDR = vm.envAddress("L1_ENFORCED_TX_GATEWAY_PROXY_ADDR"); - address L1_WHITELIST_ADDR = vm.envAddress("L1_WHITELIST_ADDR"); - - ScrollOwner owner; - - function run() external { - vm.startBroadcast(L1_DEPLOYER_PRIVATE_KEY); - - owner = ScrollOwner(payable(L1_SCROLL_OWNER_ADDR)); - - // @note we don't config 14D access, since the default admin is a 14D timelock which can access all methods. - configProxyAdmin(); - configScrollChain(); - configL1MessageQueue(); - configL1ScrollMessenger(); - configL2GasPriceOracle(); - configL1Whitelist(); - configMultipleVersionRollupVerifier(); - configL1GatewayRouter(); - configL1CustomERC20Gateway(); - configL1ERC721Gateway(); - configL1ERC1155Gateway(); - - configL1USDCGateway(); - configEnforcedTxGateway(); - - grantRoles(); - transferOwnership(); - - vm.stopBroadcast(); - } - - function transferOwnership() internal { - Ownable(L1_PROXY_ADMIN_ADDR).transferOwnership(address(owner)); - Ownable(L1_SCROLL_CHAIN_PROXY_ADDR).transferOwnership(address(owner)); - Ownable(L1_MESSAGE_QUEUE_PROXY_ADDR).transferOwnership(address(owner)); - Ownable(L1_SCROLL_MESSENGER_PROXY_ADDR).transferOwnership(address(owner)); - Ownable(L1_ENFORCED_TX_GATEWAY_PROXY_ADDR).transferOwnership(address(owner)); - Ownable(L2_GAS_PRICE_ORACLE_PROXY_ADDR).transferOwnership(address(owner)); - Ownable(L1_WHITELIST_ADDR).transferOwnership(address(owner)); - Ownable(L1_MULTIPLE_VERSION_ROLLUP_VERIFIER_ADDR).transferOwnership(address(owner)); - Ownable(L1_GATEWAY_ROUTER_PROXY_ADDR).transferOwnership(address(owner)); - Ownable(L1_CUSTOM_ERC20_GATEWAY_PROXY_ADDR).transferOwnership(address(owner)); - Ownable(L1_DAI_GATEWAY_PROXY_ADDR).transferOwnership(address(owner)); - Ownable(L1_LIDO_GATEWAY_PROXY_ADDR).transferOwnership(address(owner)); - Ownable(L1_ETH_GATEWAY_PROXY_ADDR).transferOwnership(address(owner)); - Ownable(L1_STANDARD_ERC20_GATEWAY_PROXY_ADDR).transferOwnership(address(owner)); - Ownable(L1_USDC_GATEWAY_PROXY_ADDR).transferOwnership(address(owner)); - Ownable(L1_WETH_GATEWAY_PROXY_ADDR).transferOwnership(address(owner)); - Ownable(L1_ERC721_GATEWAY_PROXY_ADDR).transferOwnership(address(owner)); - Ownable(L1_ERC1155_GATEWAY_PROXY_ADDR).transferOwnership(address(owner)); - } - - function grantRoles() internal { - owner.grantRole(SECURITY_COUNCIL_NO_DELAY_ROLE, SECURITY_COUNCIL_ADDR); - owner.grantRole(SCROLL_MULTISIG_NO_DELAY_ROLE, SCROLL_MULTISIG_ADDR); - owner.grantRole(EMERGENCY_MULTISIG_NO_DELAY_ROLE, EMERGENCY_MULTISIG_ADDR); - owner.grantRole(TIMELOCK_1DAY_DELAY_ROLE, L1_1D_TIMELOCK_ADDR); - owner.grantRole(TIMELOCK_7DAY_DELAY_ROLE, L1_7D_TIMELOCK_ADDR); - - owner.grantRole(owner.DEFAULT_ADMIN_ROLE(), L1_14D_TIMELOCK_ADDR); - owner.revokeRole(owner.DEFAULT_ADMIN_ROLE(), vm.addr(L1_DEPLOYER_PRIVATE_KEY)); - } - - function configProxyAdmin() internal { - bytes4[] memory _selectors; - - // no delay, security council - _selectors = new bytes4[](2); - _selectors[0] = ProxyAdmin.upgrade.selector; - _selectors[1] = ProxyAdmin.upgradeAndCall.selector; - owner.updateAccess(L1_PROXY_ADMIN_ADDR, _selectors, SECURITY_COUNCIL_NO_DELAY_ROLE, true); - } - - function configScrollChain() internal { - bytes4[] memory _selectors; - - // no delay, scroll multisig and emergency multisig - _selectors = new bytes4[](4); - _selectors[0] = ScrollChain.revertBatch.selector; - _selectors[1] = ScrollChain.removeSequencer.selector; - _selectors[2] = ScrollChain.removeProver.selector; - _selectors[3] = ScrollChain.setPause.selector; - owner.updateAccess(L1_SCROLL_CHAIN_PROXY_ADDR, _selectors, SCROLL_MULTISIG_NO_DELAY_ROLE, true); - owner.updateAccess(L1_SCROLL_CHAIN_PROXY_ADDR, _selectors, EMERGENCY_MULTISIG_NO_DELAY_ROLE, true); - - // delay 1 day, scroll multisig - _selectors = new bytes4[](2); - _selectors[0] = ScrollChain.addSequencer.selector; - _selectors[1] = ScrollChain.addProver.selector; - owner.updateAccess(L1_SCROLL_CHAIN_PROXY_ADDR, _selectors, TIMELOCK_1DAY_DELAY_ROLE, true); - - // delay 7 day, scroll multisig - _selectors = new bytes4[](1); - _selectors[0] = ScrollChain.updateMaxNumTxInChunk.selector; - owner.updateAccess(L1_SCROLL_CHAIN_PROXY_ADDR, _selectors, TIMELOCK_7DAY_DELAY_ROLE, true); - } - - function configL1MessageQueue() internal { - bytes4[] memory _selectors; - - // delay 1 day, scroll multisig - _selectors = new bytes4[](2); - _selectors[0] = L1MessageQueue.updateGasOracle.selector; - _selectors[1] = L1MessageQueue.updateMaxGasLimit.selector; - owner.updateAccess(L1_MESSAGE_QUEUE_PROXY_ADDR, _selectors, TIMELOCK_1DAY_DELAY_ROLE, true); - } - - function configL1ScrollMessenger() internal { - bytes4[] memory _selectors; - - // no delay, scroll multisig and emergency multisig - _selectors = new bytes4[](1); - _selectors[0] = ScrollMessengerBase.setPause.selector; - owner.updateAccess(L1_SCROLL_MESSENGER_PROXY_ADDR, _selectors, SCROLL_MULTISIG_NO_DELAY_ROLE, true); - owner.updateAccess(L1_SCROLL_MESSENGER_PROXY_ADDR, _selectors, EMERGENCY_MULTISIG_NO_DELAY_ROLE, true); - - // delay 1 day, scroll multisig - _selectors = new bytes4[](1); - _selectors[0] = L1ScrollMessenger.updateMaxReplayTimes.selector; - owner.updateAccess(L1_SCROLL_MESSENGER_PROXY_ADDR, _selectors, TIMELOCK_1DAY_DELAY_ROLE, true); - } - - function configL2GasPriceOracle() internal { - bytes4[] memory _selectors; - - // no delay, scroll multisig and emergency multisig - _selectors = new bytes4[](1); - _selectors[0] = L2GasPriceOracle.setIntrinsicParams.selector; - owner.updateAccess(L2_GAS_PRICE_ORACLE_PROXY_ADDR, _selectors, SCROLL_MULTISIG_NO_DELAY_ROLE, true); - owner.updateAccess(L2_GAS_PRICE_ORACLE_PROXY_ADDR, _selectors, EMERGENCY_MULTISIG_NO_DELAY_ROLE, true); - } - - function configL1Whitelist() internal { - bytes4[] memory _selectors; - - // delay 1 day, scroll multisig - _selectors = new bytes4[](1); - _selectors[0] = Whitelist.updateWhitelistStatus.selector; - owner.updateAccess(L1_WHITELIST_ADDR, _selectors, TIMELOCK_1DAY_DELAY_ROLE, true); - } - - function configMultipleVersionRollupVerifier() internal { - bytes4[] memory _selectors; - - // no delay, security council - _selectors = new bytes4[](1); - _selectors[0] = MultipleVersionRollupVerifier.updateVerifier.selector; - owner.updateAccess(L1_MULTIPLE_VERSION_ROLLUP_VERIFIER_ADDR, _selectors, SECURITY_COUNCIL_NO_DELAY_ROLE, true); - - // delay 7 day, scroll multisig - _selectors = new bytes4[](1); - _selectors[0] = MultipleVersionRollupVerifier.updateVerifier.selector; - owner.updateAccess(L1_MULTIPLE_VERSION_ROLLUP_VERIFIER_ADDR, _selectors, TIMELOCK_7DAY_DELAY_ROLE, true); - } - - function configL1GatewayRouter() internal { - bytes4[] memory _selectors; - - // delay 1 day, scroll multisig - _selectors = new bytes4[](1); - _selectors[0] = L1GatewayRouter.setERC20Gateway.selector; - owner.updateAccess(L1_GATEWAY_ROUTER_PROXY_ADDR, _selectors, TIMELOCK_1DAY_DELAY_ROLE, true); - } - - function configL1CustomERC20Gateway() internal { - bytes4[] memory _selectors; - - // delay 1 day, scroll multisig - _selectors = new bytes4[](1); - _selectors[0] = L1CustomERC20Gateway.updateTokenMapping.selector; - owner.updateAccess(L1_CUSTOM_ERC20_GATEWAY_PROXY_ADDR, _selectors, TIMELOCK_1DAY_DELAY_ROLE, true); - } - - function configL1ERC721Gateway() internal { - bytes4[] memory _selectors; - - // delay 1 day, scroll multisig - _selectors = new bytes4[](1); - _selectors[0] = L1ERC721Gateway.updateTokenMapping.selector; - owner.updateAccess(L1_ERC721_GATEWAY_PROXY_ADDR, _selectors, TIMELOCK_1DAY_DELAY_ROLE, true); - } - - function configL1ERC1155Gateway() internal { - bytes4[] memory _selectors; - - // delay 1 day, scroll multisig - _selectors = new bytes4[](1); - _selectors[0] = L1ERC1155Gateway.updateTokenMapping.selector; - owner.updateAccess(L1_ERC1155_GATEWAY_PROXY_ADDR, _selectors, TIMELOCK_1DAY_DELAY_ROLE, true); - } - - function configL1USDCGateway() internal { - bytes4[] memory _selectors; - - // delay 7 day, scroll multisig - _selectors = new bytes4[](3); - _selectors[0] = L1USDCGateway.updateCircleCaller.selector; - _selectors[1] = L1USDCGateway.pauseDeposit.selector; - _selectors[2] = L1USDCGateway.pauseWithdraw.selector; - owner.updateAccess(L1_USDC_GATEWAY_PROXY_ADDR, _selectors, TIMELOCK_7DAY_DELAY_ROLE, true); - } - - function configEnforcedTxGateway() internal { - bytes4[] memory _selectors; - - // no delay, scroll multisig and emergency multisig - _selectors = new bytes4[](1); - _selectors[0] = EnforcedTxGateway.setPause.selector; - owner.updateAccess(L1_ENFORCED_TX_GATEWAY_PROXY_ADDR, _selectors, SCROLL_MULTISIG_NO_DELAY_ROLE, true); - owner.updateAccess(L1_ENFORCED_TX_GATEWAY_PROXY_ADDR, _selectors, EMERGENCY_MULTISIG_NO_DELAY_ROLE, true); - } -} diff --git a/contracts/scripts/foundry/InitializeL2BridgeContracts.s.sol b/contracts/scripts/foundry/InitializeL2BridgeContracts.s.sol deleted file mode 100644 index da522335f..000000000 --- a/contracts/scripts/foundry/InitializeL2BridgeContracts.s.sol +++ /dev/null @@ -1,180 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity =0.8.24; - -import {Script} from "forge-std/Script.sol"; - -import {ProxyAdmin} from "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol"; -import {ITransparentUpgradeableProxy} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; - -import {L2ScrollMessenger} from "../../src/L2/L2ScrollMessenger.sol"; -import {L2CustomERC20Gateway} from "../../src/L2/gateways/L2CustomERC20Gateway.sol"; -import {L2ERC1155Gateway} from "../../src/L2/gateways/L2ERC1155Gateway.sol"; -import {L2ERC721Gateway} from "../../src/L2/gateways/L2ERC721Gateway.sol"; -import {L2ETHGateway} from "../../src/L2/gateways/L2ETHGateway.sol"; -import {L2GatewayRouter} from "../../src/L2/gateways/L2GatewayRouter.sol"; -import {L2StandardERC20Gateway} from "../../src/L2/gateways/L2StandardERC20Gateway.sol"; -import {L2WETHGateway} from "../../src/L2/gateways/L2WETHGateway.sol"; -import {L2MessageQueue} from "../../src/L2/predeploys/L2MessageQueue.sol"; -import {L2TxFeeVault} from "../../src/L2/predeploys/L2TxFeeVault.sol"; -import {L1GasPriceOracle} from "../../src/L2/predeploys/L1GasPriceOracle.sol"; -import {Whitelist} from "../../src/L2/predeploys/Whitelist.sol"; -import {ScrollStandardERC20Factory} from "../../src/libraries/token/ScrollStandardERC20Factory.sol"; - -// solhint-disable max-states-count -// solhint-disable state-visibility -// solhint-disable var-name-mixedcase - -contract InitializeL2BridgeContracts is Script { - uint256 deployerPrivateKey = vm.envUint("L2_DEPLOYER_PRIVATE_KEY"); - - address L2_WETH_ADDR = vm.envAddress("L2_WETH_ADDR"); - address L2_PROXY_ADMIN_ADDR = vm.envAddress("L2_PROXY_ADMIN_ADDR"); - - address L1_SCROLL_MESSENGER_PROXY_ADDR = vm.envAddress("L1_SCROLL_MESSENGER_PROXY_ADDR"); - address L1_GATEWAY_ROUTER_PROXY_ADDR = vm.envAddress("L1_GATEWAY_ROUTER_PROXY_ADDR"); - address L1_CUSTOM_ERC20_GATEWAY_PROXY_ADDR = vm.envAddress("L1_CUSTOM_ERC20_GATEWAY_PROXY_ADDR"); - address L1_ERC721_GATEWAY_PROXY_ADDR = vm.envAddress("L1_ERC721_GATEWAY_PROXY_ADDR"); - address L1_ERC1155_GATEWAY_PROXY_ADDR = vm.envAddress("L1_ERC1155_GATEWAY_PROXY_ADDR"); - address L1_ETH_GATEWAY_PROXY_ADDR = vm.envAddress("L1_ETH_GATEWAY_PROXY_ADDR"); - address L1_STANDARD_ERC20_GATEWAY_PROXY_ADDR = vm.envAddress("L1_STANDARD_ERC20_GATEWAY_PROXY_ADDR"); - address L1_WETH_GATEWAY_PROXY_ADDR = vm.envAddress("L1_WETH_GATEWAY_PROXY_ADDR"); - - address L2_TX_FEE_VAULT_ADDR = vm.envAddress("L2_TX_FEE_VAULT_ADDR"); - address L1_GAS_PRICE_ORACLE_ADDR = vm.envAddress("L1_GAS_PRICE_ORACLE_ADDR"); - address L2_WHITELIST_ADDR = vm.envAddress("L2_WHITELIST_ADDR"); - address L2_MESSAGE_QUEUE_ADDR = vm.envAddress("L2_MESSAGE_QUEUE_ADDR"); - - address L2_SCROLL_MESSENGER_PROXY_ADDR = vm.envAddress("L2_SCROLL_MESSENGER_PROXY_ADDR"); - address L2_SCROLL_MESSENGER_IMPLEMENTATION_ADDR = vm.envAddress("L2_SCROLL_MESSENGER_IMPLEMENTATION_ADDR"); - address L2_GATEWAY_ROUTER_PROXY_ADDR = vm.envAddress("L2_GATEWAY_ROUTER_PROXY_ADDR"); - address L2_CUSTOM_ERC20_GATEWAY_PROXY_ADDR = vm.envAddress("L2_CUSTOM_ERC20_GATEWAY_PROXY_ADDR"); - address L2_CUSTOM_ERC20_GATEWAY_IMPLEMENTATION_ADDR = vm.envAddress("L2_CUSTOM_ERC20_GATEWAY_IMPLEMENTATION_ADDR"); - address L2_ERC721_GATEWAY_PROXY_ADDR = vm.envAddress("L2_ERC721_GATEWAY_PROXY_ADDR"); - address L2_ERC721_GATEWAY_IMPLEMENTATION_ADDR = vm.envAddress("L2_ERC721_GATEWAY_IMPLEMENTATION_ADDR"); - address L2_ERC1155_GATEWAY_PROXY_ADDR = vm.envAddress("L2_ERC1155_GATEWAY_PROXY_ADDR"); - address L2_ERC1155_GATEWAY_IMPLEMENTATION_ADDR = vm.envAddress("L2_ERC1155_GATEWAY_IMPLEMENTATION_ADDR"); - address L2_ETH_GATEWAY_PROXY_ADDR = vm.envAddress("L2_ETH_GATEWAY_PROXY_ADDR"); - address L2_ETH_GATEWAY_IMPLEMENTATION_ADDR = vm.envAddress("L2_ETH_GATEWAY_IMPLEMENTATION_ADDR"); - address L2_STANDARD_ERC20_GATEWAY_PROXY_ADDR = vm.envAddress("L2_STANDARD_ERC20_GATEWAY_PROXY_ADDR"); - address L2_STANDARD_ERC20_GATEWAY_IMPLEMENTATION_ADDR = - vm.envAddress("L2_STANDARD_ERC20_GATEWAY_IMPLEMENTATION_ADDR"); - address L2_WETH_GATEWAY_PROXY_ADDR = vm.envAddress("L2_WETH_GATEWAY_PROXY_ADDR"); - address L2_WETH_GATEWAY_IMPLEMENTATION_ADDR = vm.envAddress("L2_WETH_GATEWAY_IMPLEMENTATION_ADDR"); - address L2_SCROLL_STANDARD_ERC20_FACTORY_ADDR = vm.envAddress("L2_SCROLL_STANDARD_ERC20_FACTORY_ADDR"); - - function run() external { - ProxyAdmin proxyAdmin = ProxyAdmin(L2_PROXY_ADMIN_ADDR); - - vm.startBroadcast(deployerPrivateKey); - - // note: we use call upgrade(...) and initialize(...) instead of upgradeAndCall(...), - // otherwise the contract owner would become ProxyAdmin. - - // initialize L2MessageQueue - L2MessageQueue(L2_MESSAGE_QUEUE_ADDR).initialize(L2_SCROLL_MESSENGER_PROXY_ADDR); - - // initialize L2TxFeeVault - L2TxFeeVault(payable(L2_TX_FEE_VAULT_ADDR)).updateMessenger(L2_SCROLL_MESSENGER_PROXY_ADDR); - - // initialize L1GasPriceOracle - L1GasPriceOracle(L1_GAS_PRICE_ORACLE_ADDR).updateWhitelist(L2_WHITELIST_ADDR); - - // initialize L2ScrollMessenger - proxyAdmin.upgrade( - ITransparentUpgradeableProxy(L2_SCROLL_MESSENGER_PROXY_ADDR), - L2_SCROLL_MESSENGER_IMPLEMENTATION_ADDR - ); - - L2ScrollMessenger(payable(L2_SCROLL_MESSENGER_PROXY_ADDR)).initialize(L1_SCROLL_MESSENGER_PROXY_ADDR); - - // initialize L2GatewayRouter - L2GatewayRouter(L2_GATEWAY_ROUTER_PROXY_ADDR).initialize( - L2_ETH_GATEWAY_PROXY_ADDR, - L2_STANDARD_ERC20_GATEWAY_PROXY_ADDR - ); - - // initialize L2CustomERC20Gateway - proxyAdmin.upgrade( - ITransparentUpgradeableProxy(L2_CUSTOM_ERC20_GATEWAY_PROXY_ADDR), - L2_CUSTOM_ERC20_GATEWAY_IMPLEMENTATION_ADDR - ); - - L2CustomERC20Gateway(L2_CUSTOM_ERC20_GATEWAY_PROXY_ADDR).initialize( - L1_CUSTOM_ERC20_GATEWAY_PROXY_ADDR, - L2_GATEWAY_ROUTER_PROXY_ADDR, - L2_SCROLL_MESSENGER_PROXY_ADDR - ); - - // initialize L2ERC1155Gateway - proxyAdmin.upgrade( - ITransparentUpgradeableProxy(L2_ERC1155_GATEWAY_PROXY_ADDR), - L2_ERC1155_GATEWAY_IMPLEMENTATION_ADDR - ); - - L2ERC1155Gateway(L2_ERC1155_GATEWAY_PROXY_ADDR).initialize( - L1_ERC1155_GATEWAY_PROXY_ADDR, - L2_SCROLL_MESSENGER_PROXY_ADDR - ); - - // initialize L2ERC721Gateway - proxyAdmin.upgrade( - ITransparentUpgradeableProxy(L2_ERC721_GATEWAY_PROXY_ADDR), - L2_ERC721_GATEWAY_IMPLEMENTATION_ADDR - ); - - L2ERC721Gateway(L2_ERC721_GATEWAY_PROXY_ADDR).initialize( - L1_ERC721_GATEWAY_PROXY_ADDR, - L2_SCROLL_MESSENGER_PROXY_ADDR - ); - - // initialize L2ETHGateway - proxyAdmin.upgrade(ITransparentUpgradeableProxy(L2_ETH_GATEWAY_PROXY_ADDR), L2_ETH_GATEWAY_IMPLEMENTATION_ADDR); - - L2ETHGateway(L2_ETH_GATEWAY_PROXY_ADDR).initialize( - L1_ETH_GATEWAY_PROXY_ADDR, - L2_GATEWAY_ROUTER_PROXY_ADDR, - L2_SCROLL_MESSENGER_PROXY_ADDR - ); - - // initialize L2StandardERC20Gateway - proxyAdmin.upgrade( - ITransparentUpgradeableProxy(L2_STANDARD_ERC20_GATEWAY_PROXY_ADDR), - L2_STANDARD_ERC20_GATEWAY_IMPLEMENTATION_ADDR - ); - - L2StandardERC20Gateway(L2_STANDARD_ERC20_GATEWAY_PROXY_ADDR).initialize( - L1_STANDARD_ERC20_GATEWAY_PROXY_ADDR, - L2_GATEWAY_ROUTER_PROXY_ADDR, - L2_SCROLL_MESSENGER_PROXY_ADDR, - L2_SCROLL_STANDARD_ERC20_FACTORY_ADDR - ); - - // initialize L2WETHGateway - proxyAdmin.upgrade( - ITransparentUpgradeableProxy(L2_WETH_GATEWAY_PROXY_ADDR), - L2_WETH_GATEWAY_IMPLEMENTATION_ADDR - ); - - L2WETHGateway(payable(L2_WETH_GATEWAY_PROXY_ADDR)).initialize( - L1_WETH_GATEWAY_PROXY_ADDR, - L2_GATEWAY_ROUTER_PROXY_ADDR, - L2_SCROLL_MESSENGER_PROXY_ADDR - ); - - // set WETH gateway in router - { - address[] memory _tokens = new address[](1); - _tokens[0] = L2_WETH_ADDR; - address[] memory _gateways = new address[](1); - _gateways[0] = L2_WETH_GATEWAY_PROXY_ADDR; - L2GatewayRouter(L2_GATEWAY_ROUTER_PROXY_ADDR).setERC20Gateway(_tokens, _gateways); - } - - // initialize ScrollStandardERC20Factory - ScrollStandardERC20Factory(L2_SCROLL_STANDARD_ERC20_FACTORY_ADDR).transferOwnership( - L2_STANDARD_ERC20_GATEWAY_PROXY_ADDR - ); - - vm.stopBroadcast(); - } -} diff --git a/contracts/scripts/foundry/InitializeL2ScrollOwner.s.sol b/contracts/scripts/foundry/InitializeL2ScrollOwner.s.sol deleted file mode 100644 index f01e8cbfd..000000000 --- a/contracts/scripts/foundry/InitializeL2ScrollOwner.s.sol +++ /dev/null @@ -1,228 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity =0.8.24; - -import {Script} from "forge-std/Script.sol"; - -import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; -import {AccessControl} from "@openzeppelin/contracts/access/AccessControl.sol"; -import {AccessControlEnumerable} from "@openzeppelin/contracts/access/AccessControlEnumerable.sol"; -import {ProxyAdmin} from "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol"; - -import {L2USDCGateway} from "../../src/L2/gateways/usdc/L2USDCGateway.sol"; -import {L2CustomERC20Gateway} from "../../src/L2/gateways/L2CustomERC20Gateway.sol"; -import {L2CustomERC20Gateway} from "../../src/L2/gateways/L2CustomERC20Gateway.sol"; -import {L2ERC1155Gateway} from "../../src/L2/gateways/L2ERC1155Gateway.sol"; -import {L2ERC721Gateway} from "../../src/L2/gateways/L2ERC721Gateway.sol"; -import {L2GatewayRouter} from "../../src/L2/gateways/L2GatewayRouter.sol"; -import {ScrollMessengerBase} from "../../src/libraries/ScrollMessengerBase.sol"; -import {L1GasPriceOracle} from "../../src/L2/predeploys/L1GasPriceOracle.sol"; -import {L2TxFeeVault} from "../../src/L2/predeploys/L2TxFeeVault.sol"; -import {Whitelist} from "../../src/L2/predeploys/Whitelist.sol"; -import {ScrollOwner} from "../../src/misc/ScrollOwner.sol"; - -// solhint-disable max-states-count -// solhint-disable state-visibility -// solhint-disable var-name-mixedcase - -contract InitializeL2ScrollOwner is Script { - uint256 L2_DEPLOYER_PRIVATE_KEY = vm.envUint("L2_DEPLOYER_PRIVATE_KEY"); - - bytes32 constant SECURITY_COUNCIL_NO_DELAY_ROLE = keccak256("SECURITY_COUNCIL_NO_DELAY_ROLE"); - bytes32 constant SCROLL_MULTISIG_NO_DELAY_ROLE = keccak256("SCROLL_MULTISIG_NO_DELAY_ROLE"); - bytes32 constant EMERGENCY_MULTISIG_NO_DELAY_ROLE = keccak256("EMERGENCY_MULTISIG_NO_DELAY_ROLE"); - - bytes32 constant TIMELOCK_1DAY_DELAY_ROLE = keccak256("TIMELOCK_1DAY_DELAY_ROLE"); - bytes32 constant TIMELOCK_7DAY_DELAY_ROLE = keccak256("TIMELOCK_7DAY_DELAY_ROLE"); - - address SCROLL_MULTISIG_ADDR = vm.envAddress("L2_SCROLL_MULTISIG_ADDR"); - address SECURITY_COUNCIL_ADDR = vm.envAddress("L2_SECURITY_COUNCIL_ADDR"); - address EMERGENCY_MULTISIG_ADDR = vm.envAddress("L2_EMERGENCY_MULTISIG_ADDR"); - - address L2_SCROLL_OWNER_ADDR = vm.envAddress("L2_SCROLL_OWNER_ADDR"); - address L2_1D_TIMELOCK_ADDR = vm.envAddress("L2_1D_TIMELOCK_ADDR"); - address L2_7D_TIMELOCK_ADDR = vm.envAddress("L2_7D_TIMELOCK_ADDR"); - address L2_14D_TIMELOCK_ADDR = vm.envAddress("L2_14D_TIMELOCK_ADDR"); - - address L2_PROXY_ADMIN_ADDR = vm.envAddress("L2_PROXY_ADMIN_ADDR"); - address L2_TX_FEE_VAULT_ADDR = vm.envAddress("L2_TX_FEE_VAULT_ADDR"); - address L1_GAS_PRICE_ORACLE_ADDR = vm.envAddress("L1_GAS_PRICE_ORACLE_ADDR"); - address L2_WHITELIST_ADDR = vm.envAddress("L2_WHITELIST_ADDR"); - address L2_MESSAGE_QUEUE_ADDR = vm.envAddress("L2_MESSAGE_QUEUE_ADDR"); - - address L2_SCROLL_MESSENGER_PROXY_ADDR = vm.envAddress("L2_SCROLL_MESSENGER_PROXY_ADDR"); - address L2_GATEWAY_ROUTER_PROXY_ADDR = vm.envAddress("L2_GATEWAY_ROUTER_PROXY_ADDR"); - address L2_CUSTOM_ERC20_GATEWAY_PROXY_ADDR = vm.envAddress("L2_CUSTOM_ERC20_GATEWAY_PROXY_ADDR"); - address L2_DAI_GATEWAY_PROXY_ADDR = vm.envAddress("L2_DAI_GATEWAY_PROXY_ADDR"); - address L2_LIDO_GATEWAY_PROXY_ADDR = vm.envAddress("L2_LIDO_GATEWAY_PROXY_ADDR"); - address L2_ETH_GATEWAY_PROXY_ADDR = vm.envAddress("L2_ETH_GATEWAY_PROXY_ADDR"); - address L2_STANDARD_ERC20_GATEWAY_PROXY_ADDR = vm.envAddress("L2_STANDARD_ERC20_GATEWAY_PROXY_ADDR"); - address L2_USDC_GATEWAY_PROXY_ADDR = vm.envAddress("L2_USDC_GATEWAY_PROXY_ADDR"); - address L2_WETH_GATEWAY_PROXY_ADDR = vm.envAddress("L2_WETH_GATEWAY_PROXY_ADDR"); - address L2_ERC721_GATEWAY_PROXY_ADDR = vm.envAddress("L2_ERC721_GATEWAY_PROXY_ADDR"); - address L2_ERC1155_GATEWAY_PROXY_ADDR = vm.envAddress("L2_ERC1155_GATEWAY_PROXY_ADDR"); - - address L2_USDC_PROXY_ADDR = vm.envAddress("L2_USDC_PROXY_ADDR"); - address L2_USDC_MASTER_MINTER_ADDR = vm.envAddress("L2_USDC_MASTER_MINTER_ADDR"); - - ScrollOwner owner; - - function run() external { - vm.startBroadcast(L2_DEPLOYER_PRIVATE_KEY); - - owner = ScrollOwner(payable(L2_SCROLL_OWNER_ADDR)); - - // @note we don't config 14D access, since the default admin is a 14D timelock which can access all methods. - configProxyAdmin(); - configL1GasPriceOracle(); - configL2TxFeeVault(); - configL2Whitelist(); - configL2ScrollMessenger(); - configL2GatewayRouter(); - configL2CustomERC20Gateway(); - configL2ERC721Gateway(); - configL2ERC1155Gateway(); - - configL2USDCGateway(); - - grantRoles(); - transferOwnership(); - - vm.stopBroadcast(); - } - - function transferOwnership() internal { - Ownable(L2_PROXY_ADMIN_ADDR).transferOwnership(address(owner)); - Ownable(L2_MESSAGE_QUEUE_ADDR).transferOwnership(address(owner)); - Ownable(L1_GAS_PRICE_ORACLE_ADDR).transferOwnership(address(owner)); - Ownable(L2_TX_FEE_VAULT_ADDR).transferOwnership(address(owner)); - Ownable(L2_WHITELIST_ADDR).transferOwnership(address(owner)); - Ownable(L2_SCROLL_MESSENGER_PROXY_ADDR).transferOwnership(address(owner)); - Ownable(L2_GATEWAY_ROUTER_PROXY_ADDR).transferOwnership(address(owner)); - Ownable(L2_CUSTOM_ERC20_GATEWAY_PROXY_ADDR).transferOwnership(address(owner)); - Ownable(L2_DAI_GATEWAY_PROXY_ADDR).transferOwnership(address(owner)); - Ownable(L2_LIDO_GATEWAY_PROXY_ADDR).transferOwnership(address(owner)); - Ownable(L2_ETH_GATEWAY_PROXY_ADDR).transferOwnership(address(owner)); - Ownable(L2_STANDARD_ERC20_GATEWAY_PROXY_ADDR).transferOwnership(address(owner)); - Ownable(L2_WETH_GATEWAY_PROXY_ADDR).transferOwnership(address(owner)); - Ownable(L2_ERC721_GATEWAY_PROXY_ADDR).transferOwnership(address(owner)); - Ownable(L2_ERC1155_GATEWAY_PROXY_ADDR).transferOwnership(address(owner)); - - Ownable(L2_USDC_GATEWAY_PROXY_ADDR).transferOwnership(address(owner)); - Ownable(L2_USDC_PROXY_ADDR).transferOwnership(address(owner)); - Ownable(L2_USDC_MASTER_MINTER_ADDR).transferOwnership(address(owner)); - } - - function grantRoles() internal { - owner.grantRole(SECURITY_COUNCIL_NO_DELAY_ROLE, SECURITY_COUNCIL_ADDR); - owner.grantRole(SCROLL_MULTISIG_NO_DELAY_ROLE, SCROLL_MULTISIG_ADDR); - owner.grantRole(EMERGENCY_MULTISIG_NO_DELAY_ROLE, EMERGENCY_MULTISIG_ADDR); - owner.grantRole(TIMELOCK_1DAY_DELAY_ROLE, L2_1D_TIMELOCK_ADDR); - owner.grantRole(TIMELOCK_7DAY_DELAY_ROLE, L2_7D_TIMELOCK_ADDR); - - owner.grantRole(owner.DEFAULT_ADMIN_ROLE(), L2_14D_TIMELOCK_ADDR); - owner.revokeRole(owner.DEFAULT_ADMIN_ROLE(), vm.addr(L2_DEPLOYER_PRIVATE_KEY)); - } - - function configProxyAdmin() internal { - bytes4[] memory _selectors; - - // no delay, security council - _selectors = new bytes4[](2); - _selectors[0] = ProxyAdmin.upgrade.selector; - _selectors[1] = ProxyAdmin.upgradeAndCall.selector; - owner.updateAccess(L2_PROXY_ADMIN_ADDR, _selectors, SECURITY_COUNCIL_NO_DELAY_ROLE, true); - } - - function configL1GasPriceOracle() internal { - bytes4[] memory _selectors; - - // no delay, scroll multisig and emergency multisig - _selectors = new bytes4[](2); - _selectors[0] = L1GasPriceOracle.setOverhead.selector; - _selectors[1] = L1GasPriceOracle.setScalar.selector; - owner.updateAccess(L1_GAS_PRICE_ORACLE_ADDR, _selectors, SCROLL_MULTISIG_NO_DELAY_ROLE, true); - owner.updateAccess(L1_GAS_PRICE_ORACLE_ADDR, _selectors, EMERGENCY_MULTISIG_NO_DELAY_ROLE, true); - } - - function configL2TxFeeVault() internal { - bytes4[] memory _selectors; - - // no delay, scroll multisig and emergency multisig - _selectors = new bytes4[](1); - _selectors[0] = L2TxFeeVault.updateMinWithdrawAmount.selector; - owner.updateAccess(L2_TX_FEE_VAULT_ADDR, _selectors, SCROLL_MULTISIG_NO_DELAY_ROLE, true); - owner.updateAccess(L2_TX_FEE_VAULT_ADDR, _selectors, EMERGENCY_MULTISIG_NO_DELAY_ROLE, true); - } - - function configL2Whitelist() internal { - bytes4[] memory _selectors; - - // delay 1 day, scroll multisig - _selectors = new bytes4[](1); - _selectors[0] = Whitelist.updateWhitelistStatus.selector; - owner.updateAccess(L2_WHITELIST_ADDR, _selectors, TIMELOCK_1DAY_DELAY_ROLE, true); - } - - function configL2ScrollMessenger() internal { - bytes4[] memory _selectors; - - // no delay, scroll multisig and emergency multisig - _selectors = new bytes4[](1); - _selectors[0] = ScrollMessengerBase.setPause.selector; - owner.updateAccess(L2_SCROLL_MESSENGER_PROXY_ADDR, _selectors, SCROLL_MULTISIG_NO_DELAY_ROLE, true); - owner.updateAccess(L2_SCROLL_MESSENGER_PROXY_ADDR, _selectors, EMERGENCY_MULTISIG_NO_DELAY_ROLE, true); - } - - function configL2GatewayRouter() internal { - bytes4[] memory _selectors; - - // delay 1 day, scroll multisig - _selectors = new bytes4[](1); - _selectors[0] = L2GatewayRouter.setERC20Gateway.selector; - owner.updateAccess(L2_GATEWAY_ROUTER_PROXY_ADDR, _selectors, TIMELOCK_1DAY_DELAY_ROLE, true); - } - - function configL2CustomERC20Gateway() internal { - bytes4[] memory _selectors; - - // delay 1 day, scroll multisig - _selectors = new bytes4[](1); - _selectors[0] = L2CustomERC20Gateway.updateTokenMapping.selector; - owner.updateAccess(L2_CUSTOM_ERC20_GATEWAY_PROXY_ADDR, _selectors, TIMELOCK_1DAY_DELAY_ROLE, true); - } - - function configL2ERC721Gateway() internal { - bytes4[] memory _selectors; - - // delay 1 day, scroll multisig - _selectors = new bytes4[](1); - _selectors[0] = L2ERC721Gateway.updateTokenMapping.selector; - owner.updateAccess(L2_ERC721_GATEWAY_PROXY_ADDR, _selectors, TIMELOCK_1DAY_DELAY_ROLE, true); - } - - function configL2ERC1155Gateway() internal { - bytes4[] memory _selectors; - - // delay 1 day, scroll multisig - _selectors = new bytes4[](1); - _selectors[0] = L2ERC1155Gateway.updateTokenMapping.selector; - owner.updateAccess(L2_ERC1155_GATEWAY_PROXY_ADDR, _selectors, TIMELOCK_1DAY_DELAY_ROLE, true); - } - - function configL2USDCGateway() internal { - bytes4[] memory _selectors; - - // delay 7 day, scroll multisig - _selectors = new bytes4[](3); - _selectors[0] = L2USDCGateway.updateCircleCaller.selector; - _selectors[1] = L2USDCGateway.pauseDeposit.selector; - _selectors[2] = L2USDCGateway.pauseWithdraw.selector; - owner.updateAccess(L2_USDC_GATEWAY_PROXY_ADDR, _selectors, TIMELOCK_7DAY_DELAY_ROLE, true); - - // delay 7 day, scroll multisig - _selectors = new bytes4[](1); - _selectors[0] = Ownable.transferOwnership.selector; - owner.updateAccess(L2_USDC_PROXY_ADDR, _selectors, TIMELOCK_7DAY_DELAY_ROLE, true); - owner.updateAccess(L2_USDC_MASTER_MINTER_ADDR, _selectors, TIMELOCK_7DAY_DELAY_ROLE, true); - } -} diff --git a/contracts/scripts/import_genesis_block.ts b/contracts/scripts/import_genesis_block.ts deleted file mode 100644 index a521a6b98..000000000 --- a/contracts/scripts/import_genesis_block.ts +++ /dev/null @@ -1,37 +0,0 @@ -/* eslint-disable node/no-missing-import */ -import * as dotenv from "dotenv"; - -import * as hre from "hardhat"; -import { ethers } from "hardhat"; -import fs from "fs"; -import { selectAddressFile } from "./utils"; - -dotenv.config(); - -const GENESIS_FILE_PATH = process.env.GENESIS_FILE_PATH || "genesis.json"; - -async function main() { - const addressFile = selectAddressFile(hre.network.name); - - const [deployer] = await ethers.getSigners(); - - const rollupAddr = process.env.L1_SCROLL_CHAIN_PROXY_ADDR || addressFile.get("ScrollChain.proxy") || "0x"; - console.log("Using rollup proxy address:", rollupAddr); - - const ScrollChain = await ethers.getContractAt("ScrollChain", rollupAddr, deployer); - const genesis = JSON.parse(fs.readFileSync(GENESIS_FILE_PATH, "utf8")); - console.log("Using genesis block:", genesis.blockHash); - - const tx = await ScrollChain.importGenesisBatch(genesis); - - console.log("importGenesisBatch ScrollChain, hash:", tx.hash); - const receipt = await tx.wait(); - console.log(`✅ Done, gas used: ${receipt.gasUsed}`); -} - -// We recommend this pattern to be able to use async/await everywhere -// and properly handle errors. -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); diff --git a/contracts/scripts/index.ts b/contracts/scripts/index.ts deleted file mode 100644 index e69de29bb..000000000 diff --git a/contracts/scripts/initialize_l1_custom_erc20_gateway.ts b/contracts/scripts/initialize_l1_custom_erc20_gateway.ts deleted file mode 100644 index 931226d80..000000000 --- a/contracts/scripts/initialize_l1_custom_erc20_gateway.ts +++ /dev/null @@ -1,43 +0,0 @@ -/* eslint-disable node/no-missing-import */ -import * as dotenv from "dotenv"; - -import { constants } from "ethers"; -import * as hre from "hardhat"; -import { ethers } from "hardhat"; -import { selectAddressFile } from "./utils"; - -dotenv.config(); - -async function main() { - const addressFile = selectAddressFile(hre.network.name); - - const [deployer] = await ethers.getSigners(); - - const L1CustomERC20Gateway = await ethers.getContractAt( - "L1CustomERC20Gateway", - addressFile.get("L1CustomERC20Gateway.proxy"), - deployer - ); - - const L1GatewayRouterAddress = addressFile.get("L1GatewayRouter.proxy"); - const L1ScrollMessengerAddress = addressFile.get("L1ScrollMessenger.proxy"); - const L2CustomERC20GatewayAddress = process.env.L2_CUSTOM_ERC20_GATEWAY_PROXY_ADDR!; - - if ((await L1CustomERC20Gateway.counterpart()) === constants.AddressZero) { - const tx = await L1CustomERC20Gateway.initialize( - L2CustomERC20GatewayAddress, - L1GatewayRouterAddress, - L1ScrollMessengerAddress - ); - console.log("initialize L1CustomERC20Gateway, hash:", tx.hash); - const receipt = await tx.wait(); - console.log(`✅ Done, gas used: ${receipt.gasUsed}`); - } -} - -// We recommend this pattern to be able to use async/await everywhere -// and properly handle errors. -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); diff --git a/contracts/scripts/initialize_l1_erc1155_gateway.ts b/contracts/scripts/initialize_l1_erc1155_gateway.ts deleted file mode 100644 index 8cb3e0c9a..000000000 --- a/contracts/scripts/initialize_l1_erc1155_gateway.ts +++ /dev/null @@ -1,38 +0,0 @@ -/* eslint-disable node/no-missing-import */ -import * as dotenv from "dotenv"; - -import { constants } from "ethers"; -import * as hre from "hardhat"; -import { ethers } from "hardhat"; -import { selectAddressFile } from "./utils"; - -dotenv.config(); - -async function main() { - const addressFile = selectAddressFile(hre.network.name); - - const [deployer] = await ethers.getSigners(); - - const L1ERC1155Gateway = await ethers.getContractAt( - "L1ERC1155Gateway", - addressFile.get("L1ERC1155Gateway.proxy"), - deployer - ); - - const L1ScrollMessengerAddress = addressFile.get("L1ScrollMessenger.proxy"); - const L2ERC1155GatewayAddress = process.env.L2_ERC1155_GATEWAY_PROXY_ADDR!; - - if ((await L1ERC1155Gateway.counterpart()) === constants.AddressZero) { - const tx = await L1ERC1155Gateway.initialize(L2ERC1155GatewayAddress, L1ScrollMessengerAddress); - console.log("initialize L1ERC1155Gateway, hash:", tx.hash); - const receipt = await tx.wait(); - console.log(`✅ Done, gas used: ${receipt.gasUsed}`); - } -} - -// We recommend this pattern to be able to use async/await everywhere -// and properly handle errors. -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); diff --git a/contracts/scripts/initialize_l1_erc20_gateway.ts b/contracts/scripts/initialize_l1_erc20_gateway.ts deleted file mode 100644 index 0a82ed4a9..000000000 --- a/contracts/scripts/initialize_l1_erc20_gateway.ts +++ /dev/null @@ -1,47 +0,0 @@ -/* eslint-disable node/no-missing-import */ -import * as dotenv from "dotenv"; - -import { constants } from "ethers"; -import * as hre from "hardhat"; -import { ethers } from "hardhat"; -import { selectAddressFile } from "./utils"; - -dotenv.config(); - -async function main() { - const addressFile = selectAddressFile(hre.network.name); - - const [deployer] = await ethers.getSigners(); - - const L1StandardERC20Gateway = await ethers.getContractAt( - "L1StandardERC20Gateway", - addressFile.get("L1StandardERC20Gateway.proxy"), - deployer - ); - - const L1GatewayRouterAddress = addressFile.get("L1GatewayRouter.proxy"); - const L1ScrollMessengerAddress = addressFile.get("L1ScrollMessenger.proxy"); - const L2StandardERC20GatewayAddress = process.env.L2_STANDARD_ERC20_GATEWAY_PROXY_ADDR!; - const L2StandardERC20Impl = process.env.L2_SCROLL_STANDARD_ERC20_ADDR!; - const L2StandardERC20FactoryAddress = process.env.L2_SCROLL_STANDARD_ERC20_FACTORY_ADDR!; - - if ((await L1StandardERC20Gateway.counterpart()) === constants.AddressZero) { - const tx = await L1StandardERC20Gateway.initialize( - L2StandardERC20GatewayAddress, - L1GatewayRouterAddress, - L1ScrollMessengerAddress, - L2StandardERC20Impl, - L2StandardERC20FactoryAddress - ); - console.log("initialize L1StandardERC20Gateway, hash:", tx.hash); - const receipt = await tx.wait(); - console.log(`✅ Done, gas used: ${receipt.gasUsed}`); - } -} - -// We recommend this pattern to be able to use async/await everywhere -// and properly handle errors. -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); diff --git a/contracts/scripts/initialize_l1_erc721_gateway.ts b/contracts/scripts/initialize_l1_erc721_gateway.ts deleted file mode 100644 index 6355c58fe..000000000 --- a/contracts/scripts/initialize_l1_erc721_gateway.ts +++ /dev/null @@ -1,38 +0,0 @@ -/* eslint-disable node/no-missing-import */ -import * as dotenv from "dotenv"; - -import { constants } from "ethers"; -import * as hre from "hardhat"; -import { ethers } from "hardhat"; -import { selectAddressFile } from "./utils"; - -dotenv.config(); - -async function main() { - const addressFile = selectAddressFile(hre.network.name); - - const [deployer] = await ethers.getSigners(); - - const L1ERC721Gateway = await ethers.getContractAt( - "L1ERC721Gateway", - addressFile.get("L1ERC721Gateway.proxy"), - deployer - ); - - const L1ScrollMessengerAddress = addressFile.get("L1ScrollMessenger.proxy"); - const L2ERC721GatewayAddress = process.env.L2_ERC721_GATEWAY_PROXY_ADDR!; - - if ((await L1ERC721Gateway.counterpart()) === constants.AddressZero) { - const tx = await L1ERC721Gateway.initialize(L2ERC721GatewayAddress, L1ScrollMessengerAddress); - console.log("initialize L1ERC721Gateway, hash:", tx.hash); - const receipt = await tx.wait(); - console.log(`✅ Done, gas used: ${receipt.gasUsed}`); - } -} - -// We recommend this pattern to be able to use async/await everywhere -// and properly handle errors. -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); diff --git a/contracts/scripts/initialize_l1_gateway_router.ts b/contracts/scripts/initialize_l1_gateway_router.ts deleted file mode 100644 index c8f70febc..000000000 --- a/contracts/scripts/initialize_l1_gateway_router.ts +++ /dev/null @@ -1,43 +0,0 @@ -/* eslint-disable node/no-missing-import */ -import * as dotenv from "dotenv"; - -import { constants } from "ethers"; -import * as hre from "hardhat"; -import { ethers } from "hardhat"; -import { selectAddressFile } from "./utils"; - -dotenv.config(); - -async function main() { - const addressFile = selectAddressFile(hre.network.name); - - const [deployer] = await ethers.getSigners(); - - const L1GatewayRouter = await ethers.getContractAt( - "L1GatewayRouter", - addressFile.get("L1GatewayRouter.proxy"), - deployer - ); - - const L1StandardERC20GatewayAddress = addressFile.get("L1StandardERC20Gateway.proxy"); - const L1ScrollMessengerAddress = addressFile.get("L1ScrollMessenger.proxy"); - const L2GatewayRouterAddress = process.env.L2_GATEWAY_ROUTER_PROXY_ADDR!; - - if ((await L1GatewayRouter.counterpart()) === constants.AddressZero) { - const tx = await L1GatewayRouter.initialize( - L1StandardERC20GatewayAddress, - L2GatewayRouterAddress, - L1ScrollMessengerAddress - ); - console.log("initialize L1StandardERC20Gateway, hash:", tx.hash); - const receipt = await tx.wait(); - console.log(`✅ Done, gas used: ${receipt.gasUsed}`); - } -} - -// We recommend this pattern to be able to use async/await everywhere -// and properly handle errors. -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); diff --git a/contracts/scripts/initialize_l1_messenger.ts b/contracts/scripts/initialize_l1_messenger.ts deleted file mode 100644 index 0df64fb62..000000000 --- a/contracts/scripts/initialize_l1_messenger.ts +++ /dev/null @@ -1,37 +0,0 @@ -/* eslint-disable node/no-missing-import */ -import * as dotenv from "dotenv"; - -import { constants } from "ethers"; -import * as hre from "hardhat"; -import { ethers } from "hardhat"; -import { selectAddressFile } from "./utils"; - -dotenv.config(); - -async function main() { - const addressFile = selectAddressFile(hre.network.name); - - const [deployer] = await ethers.getSigners(); - - const L1ScrollMessenger = await ethers.getContractAt( - "L1ScrollMessenger", - addressFile.get("L1ScrollMessenger.proxy"), - deployer - ); - - const ZKRollupAddress = addressFile.get("ZKRollup.proxy"); - - if ((await L1ScrollMessenger.rollup()) === constants.AddressZero) { - const tx = await L1ScrollMessenger.initialize(ZKRollupAddress); - console.log("initialize L1StandardERC20Gateway, hash:", tx.hash); - const receipt = await tx.wait(); - console.log(`✅ Done, gas used: ${receipt.gasUsed}`); - } -} - -// We recommend this pattern to be able to use async/await everywhere -// and properly handle errors. -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); diff --git a/contracts/scripts/initialize_l2_custom_erc20_gateway.ts b/contracts/scripts/initialize_l2_custom_erc20_gateway.ts deleted file mode 100644 index c0cf1e9bb..000000000 --- a/contracts/scripts/initialize_l2_custom_erc20_gateway.ts +++ /dev/null @@ -1,43 +0,0 @@ -/* eslint-disable node/no-missing-import */ -import * as dotenv from "dotenv"; - -import { constants } from "ethers"; -import * as hre from "hardhat"; -import { ethers } from "hardhat"; -import { selectAddressFile } from "./utils"; - -dotenv.config(); - -async function main() { - const addressFile = selectAddressFile(hre.network.name); - - const [deployer] = await ethers.getSigners(); - - const L2CustomERC20Gateway = await ethers.getContractAt( - "L2CustomERC20Gateway", - addressFile.get("L2CustomERC20Gateway.proxy"), - deployer - ); - - const L2GatewayRouterAddress = addressFile.get("L2GatewayRouter.proxy"); - const L2ScrollMessengerAddress = addressFile.get("L2ScrollMessenger"); - const L1CustomERC20GatewayAddress = process.env.L1_CUSTOM_ERC20_GATEWAY_PROXY_ADDR!; - - if ((await L2CustomERC20Gateway.counterpart()) === constants.AddressZero) { - const tx = await L2CustomERC20Gateway.initialize( - L1CustomERC20GatewayAddress, - L2GatewayRouterAddress, - L2ScrollMessengerAddress - ); - console.log("initialize L2CustomERC20Gateway, hash:", tx.hash); - const receipt = await tx.wait(); - console.log(`✅ Done, gas used: ${receipt.gasUsed}`); - } -} - -// We recommend this pattern to be able to use async/await everywhere -// and properly handle errors. -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); diff --git a/contracts/scripts/initialize_l2_erc1155_gateway.ts b/contracts/scripts/initialize_l2_erc1155_gateway.ts deleted file mode 100644 index 521aa7f47..000000000 --- a/contracts/scripts/initialize_l2_erc1155_gateway.ts +++ /dev/null @@ -1,38 +0,0 @@ -/* eslint-disable node/no-missing-import */ -import * as dotenv from "dotenv"; - -import { constants } from "ethers"; -import * as hre from "hardhat"; -import { ethers } from "hardhat"; -import { selectAddressFile } from "./utils"; - -dotenv.config(); - -async function main() { - const addressFile = selectAddressFile(hre.network.name); - - const [deployer] = await ethers.getSigners(); - - const L2ERC1155Gateway = await ethers.getContractAt( - "L2ERC1155Gateway", - addressFile.get("L2ERC1155Gateway.proxy"), - deployer - ); - - const L2ScrollMessengerAddress = addressFile.get("L2ScrollMessenger"); - const L1ERC1155GatewayAddress = process.env.L1_ERC1155_GATEWAY_PROXY_ADDR!; - - if ((await L2ERC1155Gateway.counterpart()) === constants.AddressZero) { - const tx = await L2ERC1155Gateway.initialize(L1ERC1155GatewayAddress, L2ScrollMessengerAddress); - console.log("initialize L2ERC1155Gateway, hash:", tx.hash); - const receipt = await tx.wait(); - console.log(`✅ Done, gas used: ${receipt.gasUsed}`); - } -} - -// We recommend this pattern to be able to use async/await everywhere -// and properly handle errors. -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); diff --git a/contracts/scripts/initialize_l2_erc20_gateway.ts b/contracts/scripts/initialize_l2_erc20_gateway.ts deleted file mode 100644 index d2b823d72..000000000 --- a/contracts/scripts/initialize_l2_erc20_gateway.ts +++ /dev/null @@ -1,45 +0,0 @@ -/* eslint-disable node/no-missing-import */ -import * as dotenv from "dotenv"; - -import { constants } from "ethers"; -import * as hre from "hardhat"; -import { ethers } from "hardhat"; -import { selectAddressFile } from "./utils"; - -dotenv.config(); - -async function main() { - const addressFile = selectAddressFile(hre.network.name); - - const [deployer] = await ethers.getSigners(); - - const L2StandardERC20Gateway = await ethers.getContractAt( - "L2StandardERC20Gateway", - addressFile.get("L2StandardERC20Gateway.proxy"), - deployer - ); - - const L2GatewayRouterAddress = addressFile.get("L2GatewayRouter.proxy"); - const L2ScrollMessengerAddress = addressFile.get("L2ScrollMessenger"); - const L2StandardERC20FactoryAddress = addressFile.get("ScrollStandardERC20Factory"); - const L1StandardERC20GatewayAddress = process.env.L1_STANDARD_ERC20_GATEWAY_PROXY_ADDR!; - - if ((await L2StandardERC20Gateway.counterpart()) === constants.AddressZero) { - const tx = await L2StandardERC20Gateway.initialize( - L1StandardERC20GatewayAddress, - L2GatewayRouterAddress, - L2ScrollMessengerAddress, - L2StandardERC20FactoryAddress - ); - console.log("initialize L2StandardERC20Gateway, hash:", tx.hash); - const receipt = await tx.wait(); - console.log(`✅ Done, gas used: ${receipt.gasUsed}`); - } -} - -// We recommend this pattern to be able to use async/await everywhere -// and properly handle errors. -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); diff --git a/contracts/scripts/initialize_l2_erc721_gateway.ts b/contracts/scripts/initialize_l2_erc721_gateway.ts deleted file mode 100644 index 97f7564ab..000000000 --- a/contracts/scripts/initialize_l2_erc721_gateway.ts +++ /dev/null @@ -1,38 +0,0 @@ -/* eslint-disable node/no-missing-import */ -import * as dotenv from "dotenv"; - -import { constants } from "ethers"; -import * as hre from "hardhat"; -import { ethers } from "hardhat"; -import { selectAddressFile } from "./utils"; - -dotenv.config(); - -async function main() { - const addressFile = selectAddressFile(hre.network.name); - - const [deployer] = await ethers.getSigners(); - - const L2ERC721Gateway = await ethers.getContractAt( - "L2ERC721Gateway", - addressFile.get("L2ERC721Gateway.proxy"), - deployer - ); - - const L2ScrollMessengerAddress = addressFile.get("L2ScrollMessenger"); - const L1ERC721GatewayAddress = process.env.L1_ERC721_GATEWAY_PROXY_ADDR!; - - if ((await L2ERC721Gateway.counterpart()) === constants.AddressZero) { - const tx = await L2ERC721Gateway.initialize(L1ERC721GatewayAddress, L2ScrollMessengerAddress); - console.log("initialize L2ERC721Gateway, hash:", tx.hash); - const receipt = await tx.wait(); - console.log(`✅ Done, gas used: ${receipt.gasUsed}`); - } -} - -// We recommend this pattern to be able to use async/await everywhere -// and properly handle errors. -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); diff --git a/contracts/scripts/initialize_l2_gateway_router.ts b/contracts/scripts/initialize_l2_gateway_router.ts deleted file mode 100644 index a1bcda581..000000000 --- a/contracts/scripts/initialize_l2_gateway_router.ts +++ /dev/null @@ -1,43 +0,0 @@ -/* eslint-disable node/no-missing-import */ -import * as dotenv from "dotenv"; - -import { constants } from "ethers"; -import * as hre from "hardhat"; -import { ethers } from "hardhat"; -import { selectAddressFile } from "./utils"; - -dotenv.config(); - -async function main() { - const addressFile = selectAddressFile(hre.network.name); - - const [deployer] = await ethers.getSigners(); - - const L2GatewayRouter = await ethers.getContractAt( - "L2GatewayRouter", - addressFile.get("L2GatewayRouter.proxy"), - deployer - ); - - const L2StandardERC20GatewayAddress = addressFile.get("L2StandardERC20Gateway.proxy"); - const L2ScrollMessengerAddress = addressFile.get("L2ScrollMessenger"); - const L1GatewayRouterAddress = process.env.L1_GATEWAY_ROUTER_PROXY_ADDR!; - - if ((await L2GatewayRouter.counterpart()) === constants.AddressZero) { - const tx = await L2GatewayRouter.initialize( - L2StandardERC20GatewayAddress, - L1GatewayRouterAddress, - L2ScrollMessengerAddress - ); - console.log("initialize L1StandardERC20Gateway, hash:", tx.hash); - const receipt = await tx.wait(); - console.log(`✅ Done, gas used: ${receipt.gasUsed}`); - } -} - -// We recommend this pattern to be able to use async/await everywhere -// and properly handle errors. -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); diff --git a/contracts/scripts/initialize_l2_token_factory.ts b/contracts/scripts/initialize_l2_token_factory.ts deleted file mode 100644 index 471a30557..000000000 --- a/contracts/scripts/initialize_l2_token_factory.ts +++ /dev/null @@ -1,36 +0,0 @@ -/* eslint-disable node/no-missing-import */ -import * as dotenv from "dotenv"; - -import * as hre from "hardhat"; -import { ethers } from "hardhat"; -import { selectAddressFile } from "./utils"; - -dotenv.config(); - -async function main() { - const addressFile = selectAddressFile(hre.network.name); - - const [deployer] = await ethers.getSigners(); - - const ScrollStandardERC20Factory = await ethers.getContractAt( - "ScrollStandardERC20Factory", - addressFile.get("ScrollStandardERC20Factory"), - deployer - ); - - const L2StandardERC20GatewayAddress = addressFile.get("L2StandardERC20Gateway.proxy"); - - // if ((await ScrollStandardERC20Factory.owner()) !== L2StandardERC20GatewayAddress) { - const tx = await ScrollStandardERC20Factory.transferOwnership(L2StandardERC20GatewayAddress); - console.log("transfer ownernship ScrollStandardERC20Factory, hash:", tx.hash); - const receipt = await tx.wait(); - console.log(`✅ Done, gas used: ${receipt.gasUsed}`); - // } -} - -// We recommend this pattern to be able to use async/await everywhere -// and properly handle errors. -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); diff --git a/contracts/scripts/initialize_zkrollup.ts b/contracts/scripts/initialize_zkrollup.ts deleted file mode 100644 index 6c3187887..000000000 --- a/contracts/scripts/initialize_zkrollup.ts +++ /dev/null @@ -1,42 +0,0 @@ -/* eslint-disable node/no-missing-import */ -import * as dotenv from "dotenv"; -import { constants } from "ethers"; - -import * as hre from "hardhat"; -import { ethers } from "hardhat"; -import { selectAddressFile } from "./utils"; - -dotenv.config(); - -const L1_MESSAGE_QUEUE = process.env.L1_MESSAGE_QUEUE || "none"; - -async function main() { - const addressFile = selectAddressFile(hre.network.name); - - const [deployer] = await ethers.getSigners(); - - const ScrollChain = await ethers.getContractAt("ScrollChain", addressFile.get("ScrollChain.proxy"), deployer); - - if ((await ScrollChain.owner()) === constants.AddressZero) { - const tx = await ScrollChain.initialize(L1_MESSAGE_QUEUE, constants.AddressZero); - console.log("initialize ScrollChain, hash:", tx.hash); - const receipt = await tx.wait(); - console.log(`✅ Done, gas used: ${receipt.gasUsed}`); - } - - const L1RollupOperatorAddress = process.env.L1_ROLLUP_OPERATOR_ADDR!; - if ((await ScrollChain.isBatchFinalized(L1RollupOperatorAddress)) === false) { - console.log("L1_ROLLUP_OPERATOR_ADDR", L1RollupOperatorAddress); - const tx = await ScrollChain.updateSequencer(L1RollupOperatorAddress, true); - console.log("updateOperator ScrollChain, hash:", tx.hash); - const receipt = await tx.wait(); - console.log(`✅ Done, gas used: ${receipt.gasUsed}`); - } -} - -// We recommend this pattern to be able to use async/await everywhere -// and properly handle errors. -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); diff --git a/contracts/scripts/poseidon.ts b/contracts/scripts/poseidon.ts deleted file mode 100644 index 274746ba4..000000000 --- a/contracts/scripts/poseidon.ts +++ /dev/null @@ -1,202 +0,0 @@ -/* eslint-disable node/no-missing-import */ -import { ethers, keccak256 } from "ethers"; - -import Contract from "circomlib/src/evmasm"; -import * as constants from "circomlib/src/poseidon_constants"; - -const N_ROUNDS_F = 8; -const N_ROUNDS_P = [56, 57, 56, 60, 60, 63, 64, 63]; - -export function createCode(nInputs: number) { - if (nInputs < 1 || nInputs > 8) throw new Error("Invalid number of inputs. Must be 1<=nInputs<=8"); - const t = nInputs + 1; - const nRoundsF = N_ROUNDS_F; - const nRoundsP = N_ROUNDS_P[t - 2]; - - const C = new Contract(); - - function saveM() { - for (let i = 0; i < t; i++) { - for (let j = 0; j < t; j++) { - C.push(constants.M[t - 2][i][j]); - C.push((1 + i * t + j) * 32); - C.mstore(); - } - } - } - - function ark(r: number) { - // st, q - for (let i = 0; i < t; i++) { - C.dup(t); // q, st, q - C.push(constants.C[t - 2][r * t + i]); // K, q, st, q - C.dup(2 + i); // st[i], K, q, st, q - C.addmod(); // newSt[i], st, q - C.swap(1 + i); // xx, st, q - C.pop(); - } - } - - function sigma(p: number) { - // sq, q - C.dup(t); // q, st, q - C.dup(1 + p); // st[p] , q , st, q - C.dup(1); // q, st[p] , q , st, q - C.dup(0); // q, q, st[p] , q , st, q - C.dup(2); // st[p] , q, q, st[p] , q , st, q - C.dup(0); // st[p] , st[p] , q, q, st[p] , q , st, q - C.mulmod(); // st2[p], q, st[p] , q , st, q - C.dup(0); // st2[p], st2[p], q, st[p] , q , st, q - C.mulmod(); // st4[p], st[p] , q , st, q - C.mulmod(); // st5[p], st, q - C.swap(1 + p); - C.pop(); // newst, q - } - - function mix() { - C.label("mix"); - for (let i = 0; i < t; i++) { - for (let j = 0; j < t; j++) { - if (j === 0) { - C.dup(i + t); // q, newSt, oldSt, q - C.push((1 + i * t + j) * 32); - C.mload(); // M, q, newSt, oldSt, q - C.dup(2 + i + j); // oldSt[j], M, q, newSt, oldSt, q - C.mulmod(); // acc, newSt, oldSt, q - } else { - C.dup(1 + i + t); // q, acc, newSt, oldSt, q - C.push((1 + i * t + j) * 32); - C.mload(); // M, q, acc, newSt, oldSt, q - C.dup(3 + i + j); // oldSt[j], M, q, acc, newSt, oldSt, q - C.mulmod(); // aux, acc, newSt, oldSt, q - C.dup(2 + i + t); // q, aux, acc, newSt, oldSt, q - C.swap(2); // acc, aux, q, newSt, oldSt, q - C.addmod(); // acc, newSt, oldSt, q - } - } - } - for (let i = 0; i < t; i++) { - C.swap(t - i + (t - i - 1)); - C.pop(); - } - C.push(0); - C.mload(); - C.jmp(); - } - - // Check selector - C.push("0x0100000000000000000000000000000000000000000000000000000000"); - C.push(0); - C.calldataload(); - C.div(); - C.dup(0); - C.push(keccak256(ethers.toUtf8Bytes(`poseidon(uint256[${nInputs}],uint256)`)).slice(0, 10)); // poseidon(uint256[n],uint256) - C.eq(); - C.swap(1); - C.push(keccak256(ethers.toUtf8Bytes(`poseidon(bytes32[${nInputs}],bytes32)`)).slice(0, 10)); // poseidon(bytes32[n],bytes32) - C.eq(); - C.or(); - C.jmpi("start"); - C.invalid(); - - C.label("start"); - - saveM(); - - C.push("0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001"); // q - - // Load t values from the call data. - // The function has a single array param param - // [Selector (4)] [item1 (32)] [item2 (32)] .... [doman (32)] - // Stack positions 0-nInputs. - for (let i = 0; i < nInputs; i++) { - C.push(0x04 + 0x20 * (nInputs - i - 1)); - C.calldataload(); - } - C.push(0x04 + 0x20 * nInputs); - C.calldataload(); - - for (let i = 0; i < nRoundsF + nRoundsP; i++) { - ark(i); - if (i < nRoundsF / 2 || i >= nRoundsP + nRoundsF / 2) { - for (let j = 0; j < t; j++) { - sigma(j); - } - } else { - sigma(0); - } - const strLabel = "aferMix" + i; - C._pushLabel(strLabel); - C.push(0); - C.mstore(); - C.jmp("mix"); - C.label(strLabel); - } - - C.push("0x00"); - C.mstore(); // Save it to pos 0; - C.push("0x20"); - C.push("0x00"); - C.return(); - - mix(); - - return C.createTxData(); -} - -export function generateABI(nInputs: number) { - return [ - { - constant: true, - inputs: [ - { - internalType: `bytes32[${nInputs}]`, - name: "input", - type: `bytes32[${nInputs}]`, - }, - { - internalType: "bytes32", - name: "domain", - type: "bytes32", - }, - ], - name: "poseidon", - outputs: [ - { - internalType: "bytes32", - name: "", - type: "bytes32", - }, - ], - payable: false, - stateMutability: "pure", - type: "function", - }, - { - constant: true, - inputs: [ - { - internalType: `uint256[${nInputs}]`, - name: "input", - type: `uint256[${nInputs}]`, - }, - { - internalType: "uint256", - name: "domain", - type: "uint256", - }, - ], - name: "poseidon", - outputs: [ - { - internalType: "uint256", - name: "", - type: "uint256", - }, - ], - payable: false, - stateMutability: "pure", - type: "function", - }, - ]; -} diff --git a/contracts/scripts/transfer_ownership.ts b/contracts/scripts/transfer_ownership.ts deleted file mode 100644 index 57e4455db..000000000 --- a/contracts/scripts/transfer_ownership.ts +++ /dev/null @@ -1,36 +0,0 @@ -/* eslint-disable node/no-missing-import */ -import * as dotenv from "dotenv"; - -import * as hre from "hardhat"; -import { ethers } from "hardhat"; -import { selectAddressFile } from "./utils"; - -dotenv.config(); - -async function main() { - const addressFile = selectAddressFile(hre.network.name); - - const [deployer] = await ethers.getSigners(); - - if (process.env.CONTRACT_NAME === undefined) { - throw new Error("env CONTRACT_NAME undefined"); - } - const contractName = process.env.CONTRACT_NAME!; - const contractAddress = addressFile.get(`${contractName}.proxy`) || addressFile.get(`${contractName}`); - const Contract = await ethers.getContractAt(contractName, contractAddress, deployer); - - const owner = process.env.CONTRACT_OWNER || deployer.address; - if ((await Contract.owner()).toLowerCase() !== owner.toLowerCase()) { - const tx = await Contract.transferOwnership(owner); - console.log(`${contractName} transfer ownership to ${owner}, hash: ${tx.hash}`); - const receipt = await tx.wait(); - console.log(`✅ Done, gas used: ${receipt.gasUsed}`); - } -} - -// We recommend this pattern to be able to use async/await everywhere -// and properly handle errors. -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); diff --git a/contracts/scripts/upgrade_impl.ts b/contracts/scripts/upgrade_impl.ts deleted file mode 100644 index aa6f99596..000000000 --- a/contracts/scripts/upgrade_impl.ts +++ /dev/null @@ -1,34 +0,0 @@ -/* eslint-disable node/no-missing-import */ -import * as dotenv from "dotenv"; - -import * as hre from "hardhat"; -import { ethers } from "hardhat"; -import { selectAddressFile } from "./utils"; - -dotenv.config(); - -async function main() { - const addressFile = selectAddressFile(hre.network.name); - - const [deployer] = await ethers.getSigners(); - - const contractName = process.env.CONTRACT_NAME_TO_UPGRADE!; - - const ProxyAdmin = await ethers.getContractAt("ProxyAdmin", addressFile.get("ProxyAdmin"), deployer); - const proxy = await ethers.getContractAt(contractName, addressFile.get(`${contractName}.proxy`), deployer); - const contractImplAddress = addressFile.get(`${contractName}.implementation`); - - if ((await ProxyAdmin.getProxyImplementation(proxy.address)) !== contractImplAddress) { - const tx = await ProxyAdmin.upgrade(proxy.address, contractImplAddress); - console.log(`upgrade impl for ${contractName}, hash:`, tx.hash); - const receipt = await tx.wait(); - console.log(`✅ Done, gas used: ${receipt.gasUsed}`); - } -} - -// We recommend this pattern to be able to use async/await everywhere -// and properly handle errors. -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); diff --git a/contracts/scripts/utils.ts b/contracts/scripts/utils.ts deleted file mode 100644 index d8fe33021..000000000 --- a/contracts/scripts/utils.ts +++ /dev/null @@ -1,25 +0,0 @@ -import * as fs from "fs"; -import * as path from "path"; -import editJsonFile from "edit-json-file"; - -const CONFIG_FILE_DIR = path.join(__dirname, "../", "deployments"); - -export function selectAddressFile(network: string) { - if (!fs.existsSync(CONFIG_FILE_DIR)) { - fs.mkdirSync(CONFIG_FILE_DIR, { recursive: true }); - } - - let filename: string; - if (["hardhat", "l1geth", "l2geth"].includes(network)) { - filename = path.join(CONFIG_FILE_DIR, `${network}.json`); - } else { - throw new Error(`network ${network} not supported yet`); - } - - const addressFile = editJsonFile(filename, { - stringify_eol: true, - autosave: true, - }); - - return addressFile; -} diff --git a/contracts/src/External.sol b/contracts/src/External.sol deleted file mode 100644 index 5201e8c11..000000000 --- a/contracts/src/External.sol +++ /dev/null @@ -1,8 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {TimelockController} from "@openzeppelin/contracts/governance/TimelockController.sol"; -import {ProxyAdmin} from "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol"; -import {TransparentUpgradeableProxy} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; -import {MinimalForwarder} from "@openzeppelin/contracts/metatx/MinimalForwarder.sol"; diff --git a/contracts/src/L1/IL1ScrollMessenger.sol b/contracts/src/L1/IL1ScrollMessenger.sol deleted file mode 100644 index 4a8f2b9f8..000000000 --- a/contracts/src/L1/IL1ScrollMessenger.sol +++ /dev/null @@ -1,79 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.24; - -import {IScrollMessenger} from "../libraries/IScrollMessenger.sol"; - -interface IL1ScrollMessenger is IScrollMessenger { - /********** - * Events * - **********/ - - /// @notice Emitted when the maximum number of times each message can be replayed is updated. - /// @param oldMaxReplayTimes The old maximum number of times each message can be replayed. - /// @param newMaxReplayTimes The new maximum number of times each message can be replayed. - event UpdateMaxReplayTimes(uint256 oldMaxReplayTimes, uint256 newMaxReplayTimes); - - /*********** - * Structs * - ***********/ - - struct L2MessageProof { - // The index of the batch where the message belongs to. - uint256 batchIndex; - // Concatenation of merkle proof for withdraw merkle trie. - bytes merkleProof; - } - - /***************************** - * Public Mutating Functions * - *****************************/ - - /// @notice Relay a L2 => L1 message with message proof. - /// @param from The address of the sender of the message. - /// @param to The address of the recipient of the message. - /// @param value The msg.value passed to the message call. - /// @param nonce The nonce of the message to avoid replay attack. - /// @param message The content of the message. - /// @param proof The proof used to verify the correctness of the transaction. - function relayMessageWithProof( - address from, - address to, - uint256 value, - uint256 nonce, - bytes memory message, - L2MessageProof memory proof - ) external; - - /// @notice Replay an existing message. - /// @param from The address of the sender of the message. - /// @param to The address of the recipient of the message. - /// @param value The msg.value passed to the message call. - /// @param messageNonce The nonce for the message to replay. - /// @param message The content of the message. - /// @param newGasLimit New gas limit to be used for this message. - /// @param refundAddress The address of account who will receive the refunded fee. - function replayMessage( - address from, - address to, - uint256 value, - uint256 messageNonce, - bytes memory message, - uint32 newGasLimit, - address refundAddress - ) external payable; - - /// @notice Drop a skipped message. - /// @param from The address of the sender of the message. - /// @param to The address of the recipient of the message. - /// @param value The msg.value passed to the message call. - /// @param messageNonce The nonce for the message to drop. - /// @param message The content of the message. - function dropMessage( - address from, - address to, - uint256 value, - uint256 messageNonce, - bytes memory message - ) external; -} diff --git a/contracts/src/L1/L1ScrollMessenger.sol b/contracts/src/L1/L1ScrollMessenger.sol deleted file mode 100644 index a5405a9ea..000000000 --- a/contracts/src/L1/L1ScrollMessenger.sol +++ /dev/null @@ -1,371 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {IScrollChain} from "./rollup/IScrollChain.sol"; -import {IL1MessageQueue} from "./rollup/IL1MessageQueue.sol"; -import {IL1ScrollMessenger} from "./IL1ScrollMessenger.sol"; -import {ScrollConstants} from "../libraries/constants/ScrollConstants.sol"; -import {IScrollMessenger} from "../libraries/IScrollMessenger.sol"; -import {ScrollMessengerBase} from "../libraries/ScrollMessengerBase.sol"; -import {WithdrawTrieVerifier} from "../libraries/verifier/WithdrawTrieVerifier.sol"; - -import {IMessageDropCallback} from "../libraries/callbacks/IMessageDropCallback.sol"; - -// solhint-disable avoid-low-level-calls -// solhint-disable not-rely-on-time -// solhint-disable reason-string - -/// @title L1ScrollMessenger -/// @notice The `L1ScrollMessenger` contract can: -/// -/// 1. send messages from layer 1 to layer 2; -/// 2. relay messages from layer 2 layer 1; -/// 3. replay failed message by replacing the gas limit; -/// 4. drop expired message due to sequencer problems. -/// -/// @dev All deposited Ether (including `WETH` deposited throng `L1WETHGateway`) will locked in -/// this contract. -contract L1ScrollMessenger is ScrollMessengerBase, IL1ScrollMessenger { - /************* - * Constants * - *************/ - - /// @notice The address of Rollup contract. - address public immutable rollup; - - /// @notice The address of L1MessageQueue contract. - address public immutable messageQueue; - - /*********** - * Structs * - ***********/ - - struct ReplayState { - // The number of replayed times. - uint128 times; - // The queue index of latest replayed one. If it is zero, it means the message has not been replayed. - uint128 lastIndex; - } - - /************* - * Variables * - *************/ - - /// @notice Mapping from L1 message hash to the timestamp when the message is sent. - mapping(bytes32 => uint256) public messageSendTimestamp; - - /// @notice Mapping from L2 message hash to a boolean value indicating if the message has been successfully executed. - mapping(bytes32 => bool) public isL2MessageExecuted; - - /// @notice Mapping from L1 message hash to drop status. - mapping(bytes32 => bool) public isL1MessageDropped; - - /// @dev The storage slot used as Rollup contract, which is deprecated now. - address private __rollup; - - /// @dev The storage slot used as L1MessageQueue contract, which is deprecated now. - address private __messageQueue; - - /// @notice The maximum number of times each L1 message can be replayed. - uint256 public maxReplayTimes; - - /// @notice Mapping from L1 message hash to replay state. - mapping(bytes32 => ReplayState) public replayStates; - - /// @notice Mapping from queue index to previous replay queue index. - /// - /// @dev If a message `x` was replayed 3 times with index `q1`, `q2` and `q3`, the - /// value of `prevReplayIndex` and `replayStates` will be `replayStates[hash(x)].lastIndex = q3`, - /// `replayStates[hash(x)].times = 3`, `prevReplayIndex[q3] = q2`, `prevReplayIndex[q2] = q1`, - /// `prevReplayIndex[q1] = x` and `prevReplayIndex[x]=nil`. - /// - /// @dev The index `x` that `prevReplayIndex[x]=nil` is used as the termination of the list. - /// Usually we use `0` to represent `nil`, but we cannot distinguish it with the first message - /// with index zero. So a nonzero offset `1` is added to the value of `prevReplayIndex[x]` to - /// avoid such situation. - mapping(uint256 => uint256) public prevReplayIndex; - - /*************** - * Constructor * - ***************/ - - constructor( - address _counterpart, - address _rollup, - address _messageQueue - ) ScrollMessengerBase(_counterpart) { - if (_rollup == address(0) || _messageQueue == address(0)) { - revert ErrorZeroAddress(); - } - - _disableInitializers(); - - rollup = _rollup; - messageQueue = _messageQueue; - } - - /// @notice Initialize the storage of L1ScrollMessenger. - /// - /// @dev The parameters `_counterpart`, `_rollup` and `_messageQueue` are no longer used. - /// - /// @param _counterpart The address of L2ScrollMessenger contract in L2. - /// @param _feeVault The address of fee vault, which will be used to collect relayer fee. - /// @param _rollup The address of ScrollChain contract. - /// @param _messageQueue The address of L1MessageQueue contract. - function initialize( - address _counterpart, - address _feeVault, - address _rollup, - address _messageQueue - ) public initializer { - ScrollMessengerBase.__ScrollMessengerBase_init(_counterpart, _feeVault); - - __rollup = _rollup; - __messageQueue = _messageQueue; - - maxReplayTimes = 3; - emit UpdateMaxReplayTimes(0, 3); - } - - /***************************** - * Public Mutating Functions * - *****************************/ - - /// @inheritdoc IScrollMessenger - function sendMessage( - address _to, - uint256 _value, - bytes memory _message, - uint256 _gasLimit - ) external payable override whenNotPaused { - _sendMessage(_to, _value, _message, _gasLimit, _msgSender()); - } - - /// @inheritdoc IScrollMessenger - function sendMessage( - address _to, - uint256 _value, - bytes calldata _message, - uint256 _gasLimit, - address _refundAddress - ) external payable override whenNotPaused { - _sendMessage(_to, _value, _message, _gasLimit, _refundAddress); - } - - /// @inheritdoc IL1ScrollMessenger - function relayMessageWithProof( - address _from, - address _to, - uint256 _value, - uint256 _nonce, - bytes memory _message, - L2MessageProof memory _proof - ) external override whenNotPaused notInExecution { - bytes32 _xDomainCalldataHash = keccak256(_encodeXDomainCalldata(_from, _to, _value, _nonce, _message)); - require(!isL2MessageExecuted[_xDomainCalldataHash], "Message was already successfully executed"); - - { - require(IScrollChain(rollup).isBatchFinalized(_proof.batchIndex), "Batch is not finalized"); - bytes32 _messageRoot = IScrollChain(rollup).withdrawRoots(_proof.batchIndex); - require( - WithdrawTrieVerifier.verifyMerkleProof(_messageRoot, _xDomainCalldataHash, _nonce, _proof.merkleProof), - "Invalid proof" - ); - } - - // @note check more `_to` address to avoid attack in the future when we add more gateways. - require(_to != messageQueue, "Forbid to call message queue"); - _validateTargetAddress(_to); - - // @note This usually will never happen, just in case. - require(_from != xDomainMessageSender, "Invalid message sender"); - - xDomainMessageSender = _from; - (bool success, ) = _to.call{value: _value}(_message); - // reset value to refund gas. - xDomainMessageSender = ScrollConstants.DEFAULT_XDOMAIN_MESSAGE_SENDER; - - if (success) { - isL2MessageExecuted[_xDomainCalldataHash] = true; - emit RelayedMessage(_xDomainCalldataHash); - } else { - emit FailedRelayedMessage(_xDomainCalldataHash); - } - } - - /// @inheritdoc IL1ScrollMessenger - function replayMessage( - address _from, - address _to, - uint256 _value, - uint256 _messageNonce, - bytes memory _message, - uint32 _newGasLimit, - address _refundAddress - ) external payable override whenNotPaused notInExecution { - // We will use a different `queueIndex` for the replaced message. However, the original `queueIndex` or `nonce` - // is encoded in the `_message`. We will check the `xDomainCalldata` on layer 2 to avoid duplicated execution. - // So, only one message will succeed on layer 2. If one of the message is executed successfully, the other one - // will revert with "Message was already successfully executed". - bytes memory _xDomainCalldata = _encodeXDomainCalldata(_from, _to, _value, _messageNonce, _message); - bytes32 _xDomainCalldataHash = keccak256(_xDomainCalldata); - - require(messageSendTimestamp[_xDomainCalldataHash] > 0, "Provided message has not been enqueued"); - // cannot replay dropped message - require(!isL1MessageDropped[_xDomainCalldataHash], "Message already dropped"); - - // compute and deduct the messaging fee to fee vault. - uint256 _fee = IL1MessageQueue(messageQueue).estimateCrossDomainMessageFee(_newGasLimit); - - // charge relayer fee - require(msg.value >= _fee, "Insufficient msg.value for fee"); - if (_fee > 0) { - (bool _success, ) = feeVault.call{value: _fee}(""); - require(_success, "Failed to deduct the fee"); - } - - // enqueue the new transaction - uint256 _nextQueueIndex = IL1MessageQueue(messageQueue).nextCrossDomainMessageIndex(); - IL1MessageQueue(messageQueue).appendCrossDomainMessage(counterpart, _newGasLimit, _xDomainCalldata); - - ReplayState memory _replayState = replayStates[_xDomainCalldataHash]; - // update the replayed message chain. - unchecked { - if (_replayState.lastIndex == 0) { - // the message has not been replayed before. - prevReplayIndex[_nextQueueIndex] = _messageNonce + 1; - } else { - prevReplayIndex[_nextQueueIndex] = _replayState.lastIndex + 1; - } - } - _replayState.lastIndex = uint128(_nextQueueIndex); - - // update replay times - require(_replayState.times < maxReplayTimes, "Exceed maximum replay times"); - unchecked { - _replayState.times += 1; - } - replayStates[_xDomainCalldataHash] = _replayState; - - // refund fee to `_refundAddress` - unchecked { - uint256 _refund = msg.value - _fee; - if (_refund > 0) { - (bool _success, ) = _refundAddress.call{value: _refund}(""); - require(_success, "Failed to refund the fee"); - } - } - } - - /// @inheritdoc IL1ScrollMessenger - function dropMessage( - address _from, - address _to, - uint256 _value, - uint256 _messageNonce, - bytes memory _message - ) external override whenNotPaused notInExecution { - // The criteria for dropping a message: - // 1. The message is a L1 message. - // 2. The message has not been dropped before. - // 3. the message and all of its replacement are finalized in L1. - // 4. the message and all of its replacement are skipped. - // - // Possible denial of service attack: - // + replayMessage is called every time someone want to drop the message. - // + replayMessage is called so many times for a skipped message, thus results a long list. - // - // We limit the number of `replayMessage` calls of each message, which may solve the above problem. - - // check message exists - bytes memory _xDomainCalldata = _encodeXDomainCalldata(_from, _to, _value, _messageNonce, _message); - bytes32 _xDomainCalldataHash = keccak256(_xDomainCalldata); - require(messageSendTimestamp[_xDomainCalldataHash] > 0, "Provided message has not been enqueued"); - - // check message not dropped - require(!isL1MessageDropped[_xDomainCalldataHash], "Message already dropped"); - - // check message is finalized - uint256 _lastIndex = replayStates[_xDomainCalldataHash].lastIndex; - if (_lastIndex == 0) _lastIndex = _messageNonce; - - // check message is skipped and drop it. - // @note If the list is very long, the message may never be dropped. - while (true) { - IL1MessageQueue(messageQueue).dropCrossDomainMessage(_lastIndex); - _lastIndex = prevReplayIndex[_lastIndex]; - if (_lastIndex == 0) break; - unchecked { - _lastIndex = _lastIndex - 1; - } - } - - isL1MessageDropped[_xDomainCalldataHash] = true; - - // set execution context - xDomainMessageSender = ScrollConstants.DROP_XDOMAIN_MESSAGE_SENDER; - IMessageDropCallback(_from).onDropMessage{value: _value}(_message); - // clear execution context - xDomainMessageSender = ScrollConstants.DEFAULT_XDOMAIN_MESSAGE_SENDER; - } - - /************************ - * Restricted Functions * - ************************/ - - /// @notice Update max replay times. - /// @dev This function can only called by contract owner. - /// @param _newMaxReplayTimes The new max replay times. - function updateMaxReplayTimes(uint256 _newMaxReplayTimes) external onlyOwner { - uint256 _oldMaxReplayTimes = maxReplayTimes; - maxReplayTimes = _newMaxReplayTimes; - - emit UpdateMaxReplayTimes(_oldMaxReplayTimes, _newMaxReplayTimes); - } - - /********************** - * Internal Functions * - **********************/ - - function _sendMessage( - address _to, - uint256 _value, - bytes memory _message, - uint256 _gasLimit, - address _refundAddress - ) internal nonReentrant { - // compute the actual cross domain message calldata. - uint256 _messageNonce = IL1MessageQueue(messageQueue).nextCrossDomainMessageIndex(); - bytes memory _xDomainCalldata = _encodeXDomainCalldata(_msgSender(), _to, _value, _messageNonce, _message); - - // compute and deduct the messaging fee to fee vault. - uint256 _fee = IL1MessageQueue(messageQueue).estimateCrossDomainMessageFee(_gasLimit); - require(msg.value >= _fee + _value, "Insufficient msg.value"); - if (_fee > 0) { - (bool _success, ) = feeVault.call{value: _fee}(""); - require(_success, "Failed to deduct the fee"); - } - - // append message to L1MessageQueue - IL1MessageQueue(messageQueue).appendCrossDomainMessage(counterpart, _gasLimit, _xDomainCalldata); - - // record the message hash for future use. - bytes32 _xDomainCalldataHash = keccak256(_xDomainCalldata); - - // normally this won't happen, since each message has different nonce, but just in case. - require(messageSendTimestamp[_xDomainCalldataHash] == 0, "Duplicated message"); - messageSendTimestamp[_xDomainCalldataHash] = block.timestamp; - - emit SentMessage(_msgSender(), _to, _value, _messageNonce, _gasLimit, _message); - - // refund fee to `_refundAddress` - unchecked { - uint256 _refund = msg.value - _fee - _value; - if (_refund > 0) { - (bool _success, ) = _refundAddress.call{value: _refund}(""); - require(_success, "Failed to refund the fee"); - } - } - } -} diff --git a/contracts/src/L1/gateways/EnforcedTxGateway.sol b/contracts/src/L1/gateways/EnforcedTxGateway.sol deleted file mode 100644 index 14b718e96..000000000 --- a/contracts/src/L1/gateways/EnforcedTxGateway.sol +++ /dev/null @@ -1,204 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; -import {ECDSAUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.sol"; -import {EIP712Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/EIP712Upgradeable.sol"; -import {ReentrancyGuardUpgradeable} from "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol"; -import {PausableUpgradeable} from "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol"; - -import {IL1MessageQueue} from "../rollup/IL1MessageQueue.sol"; - -// solhint-disable reason-string - -contract EnforcedTxGateway is OwnableUpgradeable, ReentrancyGuardUpgradeable, PausableUpgradeable, EIP712Upgradeable { - /********** - * Events * - **********/ - - /// @notice Emitted when owner updates fee vault contract. - /// @param _oldFeeVault The address of old fee vault contract. - /// @param _newFeeVault The address of new fee vault contract. - event UpdateFeeVault(address _oldFeeVault, address _newFeeVault); - - /************* - * Constants * - *************/ - - // solhint-disable-next-line var-name-mixedcase - bytes32 private constant _ENFORCED_TX_TYPEHASH = - keccak256( - "EnforcedTransaction(address sender,address target,uint256 value,uint256 gasLimit,bytes data,uint256 nonce,uint256 deadline)" - ); - - /************* - * Variables * - *************/ - - /// @notice The address of L1MessageQueue contract. - address public messageQueue; - - /// @notice The address of fee vault contract. - address public feeVault; - - /// @notice Mapping from EOA address to current nonce. - /// @dev Every successful call to `sendTransaction` with signature increases `_sender`'s nonce by one. - /// This prevents a signature from being used multiple times. - mapping(address => uint256) public nonces; - - /*************** - * Constructor * - ***************/ - - constructor() { - _disableInitializers(); - } - - function initialize(address _queue, address _feeVault) external initializer { - OwnableUpgradeable.__Ownable_init(); - ReentrancyGuardUpgradeable.__ReentrancyGuard_init(); - PausableUpgradeable.__Pausable_init(); - EIP712Upgradeable.__EIP712_init("EnforcedTxGateway", "1"); - - messageQueue = _queue; - feeVault = _feeVault; - } - - /************************* - * Public View Functions * - *************************/ - - /// @notice return the domain separator for the typed transaction - // solhint-disable-next-line func-name-mixedcase - function DOMAIN_SEPARATOR() external view returns (bytes32) { - return _domainSeparatorV4(); - } - - /***************************** - * Public Mutating Functions * - *****************************/ - - /// @notice Add an enforced transaction to L2. - /// @dev The caller should be EOA only. - /// @param _target The address of target contract to call in L2. - /// @param _value The value passed - /// @param _gasLimit The maximum gas should be used for this transaction in L2. - /// @param _data The calldata passed to target contract. - function sendTransaction( - address _target, - uint256 _value, - uint256 _gasLimit, - bytes calldata _data - ) external payable whenNotPaused { - // solhint-disable-next-line avoid-tx-origin - require(msg.sender == tx.origin, "Only EOA senders are allowed to send enforced transaction"); - - _sendTransaction(msg.sender, _target, _value, _gasLimit, _data, msg.sender); - } - - /// @notice Add an enforced transaction to L2. - /// @dev The `_sender` should be EOA and match with the signature. - /// @param _sender The address of sender who will initiate this transaction in L2. - /// @param _target The address of target contract to call in L2. - /// @param _value The value passed - /// @param _gasLimit The maximum gas should be used for this transaction in L2. - /// @param _data The calldata passed to target contract. - /// @param _deadline The deadline of the signature. - /// @param _signature The signature for the transaction. - /// @param _refundAddress The address to refund exceeded fee. - function sendTransaction( - address _sender, - address _target, - uint256 _value, - uint256 _gasLimit, - bytes calldata _data, - uint256 _deadline, - bytes memory _signature, - address _refundAddress - ) external payable whenNotPaused { - // solhint-disable-next-line not-rely-on-time - require(block.timestamp <= _deadline, "signature expired"); - - uint256 _nonce = nonces[_sender]; - bytes32 _structHash = keccak256( - abi.encode(_ENFORCED_TX_TYPEHASH, _sender, _target, _value, _gasLimit, keccak256(_data), _nonce, _deadline) - ); - unchecked { - nonces[_sender] = _nonce + 1; - } - - bytes32 _hash = _hashTypedDataV4(_structHash); - address _signer = ECDSAUpgradeable.recover(_hash, _signature); - - // no need to check `_signer != address(0)`, since it is checked in `recover`. - require(_signer == _sender, "Incorrect signature"); - - _sendTransaction(_sender, _target, _value, _gasLimit, _data, _refundAddress); - } - - /************************ - * Restricted Functions * - ************************/ - - /// @notice Update the address of fee vault. - /// @param _newFeeVault The address to update. - function updateFeeVault(address _newFeeVault) external onlyOwner { - address _oldFeeVault = feeVault; - feeVault = _newFeeVault; - - emit UpdateFeeVault(_oldFeeVault, _newFeeVault); - } - - /// @notice Pause or unpause this contract. - /// @param _status Pause this contract if it is true, otherwise unpause this contract. - function setPause(bool _status) external onlyOwner { - if (_status) { - _pause(); - } else { - _unpause(); - } - } - - /********************** - * Internal Functions * - **********************/ - - /// @dev Internal function to charge fee and add enforced transaction. - /// @param _sender The address of sender who will initiate this transaction in L2. - /// @param _target The address of target contract to call in L2. - /// @param _value The value passed - /// @param _gasLimit The maximum gas should be used for this transaction in L2. - /// @param _data The calldata passed to target contract. - /// @param _refundAddress The address to refund exceeded fee. - function _sendTransaction( - address _sender, - address _target, - uint256 _value, - uint256 _gasLimit, - bytes calldata _data, - address _refundAddress - ) internal nonReentrant { - address _messageQueue = messageQueue; - - // charge fee - uint256 _fee = IL1MessageQueue(_messageQueue).estimateCrossDomainMessageFee(_gasLimit); - require(msg.value >= _fee, "Insufficient value for fee"); - if (_fee > 0) { - (bool _success, ) = feeVault.call{value: _fee}(""); - require(_success, "Failed to deduct the fee"); - } - - // append transaction - IL1MessageQueue(_messageQueue).appendEnforcedTransaction(_sender, _target, _value, _gasLimit, _data); - - // refund fee to `_refundAddress` - unchecked { - uint256 _refund = msg.value - _fee; - if (_refund > 0) { - (bool _success, ) = _refundAddress.call{value: _refund}(""); - require(_success, "Failed to refund the fee"); - } - } - } -} diff --git a/contracts/src/L1/gateways/IL1ERC1155Gateway.sol b/contracts/src/L1/gateways/IL1ERC1155Gateway.sol deleted file mode 100644 index 4a16b3a80..000000000 --- a/contracts/src/L1/gateways/IL1ERC1155Gateway.sol +++ /dev/null @@ -1,180 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.24; - -/// @title The interface for the ERC1155 cross chain gateway on layer 1. -interface IL1ERC1155Gateway { - /********** - * Events * - **********/ - - /// @notice Emitted when the ERC1155 NFT is transferred to recipient on layer 1. - /// @param _l1Token The address of ERC1155 NFT on layer 1. - /// @param _l2Token The address of ERC1155 NFT on layer 2. - /// @param _from The address of sender on layer 2. - /// @param _to The address of recipient on layer 1. - /// @param _tokenId The token id of the ERC1155 NFT to withdraw from layer 2. - /// @param _amount The number of token to withdraw from layer 2. - event FinalizeWithdrawERC1155( - address indexed _l1Token, - address indexed _l2Token, - address indexed _from, - address _to, - uint256 _tokenId, - uint256 _amount - ); - - /// @notice Emitted when the ERC1155 NFT is batch transferred to recipient on layer 1. - /// @param _l1Token The address of ERC1155 NFT on layer 1. - /// @param _l2Token The address of ERC1155 NFT on layer 2. - /// @param _from The address of sender on layer 2. - /// @param _to The address of recipient on layer 1. - /// @param _tokenIds The list of token ids of the ERC1155 NFT to withdraw from layer 2. - /// @param _amounts The list of corresponding number of token to withdraw from layer 2. - event FinalizeBatchWithdrawERC1155( - address indexed _l1Token, - address indexed _l2Token, - address indexed _from, - address _to, - uint256[] _tokenIds, - uint256[] _amounts - ); - - /// @notice Emitted when the ERC1155 NFT is deposited to gateway on layer 1. - /// @param _l1Token The address of ERC1155 NFT on layer 1. - /// @param _l2Token The address of ERC1155 NFT on layer 2. - /// @param _from The address of sender on layer 1. - /// @param _to The address of recipient on layer 2. - /// @param _tokenId The token id of the ERC1155 NFT to deposit on layer 1. - /// @param _amount The number of token to deposit on layer 1. - event DepositERC1155( - address indexed _l1Token, - address indexed _l2Token, - address indexed _from, - address _to, - uint256 _tokenId, - uint256 _amount - ); - - /// @notice Emitted when the ERC1155 NFT is batch deposited to gateway on layer 1. - /// @param _l1Token The address of ERC1155 NFT on layer 1. - /// @param _l2Token The address of ERC1155 NFT on layer 2. - /// @param _from The address of sender on layer 1. - /// @param _to The address of recipient on layer 2. - /// @param _tokenIds The list of token ids of the ERC1155 NFT to deposit on layer 1. - /// @param _amounts The list of corresponding number of token to deposit on layer 1. - event BatchDepositERC1155( - address indexed _l1Token, - address indexed _l2Token, - address indexed _from, - address _to, - uint256[] _tokenIds, - uint256[] _amounts - ); - - /// @notice Emitted when some ERC1155 token is refunded. - /// @param token The address of the token in L1. - /// @param recipient The address of receiver in L1. - /// @param tokenId The id of token refunded. - /// @param amount The amount of token refunded. - event RefundERC1155(address indexed token, address indexed recipient, uint256 tokenId, uint256 amount); - - /// @notice Emitted when some ERC1155 token is refunded. - /// @param token The address of the token in L1. - /// @param recipient The address of receiver in L1. - /// @param tokenIds The list of ids of token refunded. - /// @param amounts The list of amount of token refunded. - event BatchRefundERC1155(address indexed token, address indexed recipient, uint256[] tokenIds, uint256[] amounts); - - /************************* - * Public View Functions * - *************************/ - - /// @notice Deposit some ERC1155 NFT to caller's account on layer 2. - /// @param _token The address of ERC1155 NFT on layer 1. - /// @param _tokenId The token id to deposit. - /// @param _amount The amount of token to deposit. - /// @param _gasLimit Estimated gas limit required to complete the deposit on layer 2. - function depositERC1155( - address _token, - uint256 _tokenId, - uint256 _amount, - uint256 _gasLimit - ) external payable; - - /// @notice Deposit some ERC1155 NFT to a recipient's account on layer 2. - /// @param _token The address of ERC1155 NFT on layer 1. - /// @param _to The address of recipient on layer 2. - /// @param _tokenId The token id to deposit. - /// @param _amount The amount of token to deposit. - /// @param _gasLimit Estimated gas limit required to complete the deposit on layer 2. - function depositERC1155( - address _token, - address _to, - uint256 _tokenId, - uint256 _amount, - uint256 _gasLimit - ) external payable; - - /// @notice Deposit a list of some ERC1155 NFT to caller's account on layer 2. - /// @param _token The address of ERC1155 NFT on layer 1. - /// @param _tokenIds The list of token ids to deposit. - /// @param _amounts The list of corresponding number of token to deposit. - /// @param _gasLimit Estimated gas limit required to complete the deposit on layer 2. - function batchDepositERC1155( - address _token, - uint256[] calldata _tokenIds, - uint256[] calldata _amounts, - uint256 _gasLimit - ) external payable; - - /// @notice Deposit a list of some ERC1155 NFT to a recipient's account on layer 2. - /// @param _token The address of ERC1155 NFT on layer 1. - /// @param _to The address of recipient on layer 2. - /// @param _tokenIds The list of token ids to deposit. - /// @param _amounts The list of corresponding number of token to deposit. - /// @param _gasLimit Estimated gas limit required to complete the deposit on layer 2. - function batchDepositERC1155( - address _token, - address _to, - uint256[] calldata _tokenIds, - uint256[] calldata _amounts, - uint256 _gasLimit - ) external payable; - - /// @notice Complete ERC1155 withdraw from layer 2 to layer 1 and send fund to recipient's account on layer 1. - /// The function should only be called by L1ScrollMessenger. - /// The function should also only be called by L2ERC1155Gateway on layer 2. - /// @param _l1Token The address of corresponding layer 1 token. - /// @param _l2Token The address of corresponding layer 2 token. - /// @param _from The address of account who withdraw the token on layer 2. - /// @param _to The address of recipient on layer 1 to receive the token. - /// @param _tokenId The token id to withdraw. - /// @param _amount The amount of token to withdraw. - function finalizeWithdrawERC1155( - address _l1Token, - address _l2Token, - address _from, - address _to, - uint256 _tokenId, - uint256 _amount - ) external; - - /// @notice Complete ERC1155 batch withdraw from layer 2 to layer 1 and send fund to recipient's account on layer 1. - /// The function should only be called by L1ScrollMessenger. - /// The function should also only be called by L2ERC1155Gateway on layer 2. - /// @param _l1Token The address of corresponding layer 1 token. - /// @param _l2Token The address of corresponding layer 2 token. - /// @param _from The address of account who withdraw the token on layer 2. - /// @param _to The address of recipient on layer 1 to receive the token. - /// @param _tokenIds The list of token ids to withdraw. - /// @param _amounts The list of corresponding number of token to withdraw. - function finalizeBatchWithdrawERC1155( - address _l1Token, - address _l2Token, - address _from, - address _to, - uint256[] calldata _tokenIds, - uint256[] calldata _amounts - ) external; -} diff --git a/contracts/src/L1/gateways/IL1ERC20Gateway.sol b/contracts/src/L1/gateways/IL1ERC20Gateway.sol deleted file mode 100644 index 6b551b70f..000000000 --- a/contracts/src/L1/gateways/IL1ERC20Gateway.sol +++ /dev/null @@ -1,117 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.24; - -interface IL1ERC20Gateway { - /********** - * Events * - **********/ - - /// @notice Emitted when ERC20 token is withdrawn from L2 to L1 and transfer to recipient. - /// @param l1Token The address of the token in L1. - /// @param l2Token The address of the token in L2. - /// @param from The address of sender in L2. - /// @param to The address of recipient in L1. - /// @param amount The amount of token withdrawn from L2 to L1. - /// @param data The optional calldata passed to recipient in L1. - event FinalizeWithdrawERC20( - address indexed l1Token, - address indexed l2Token, - address indexed from, - address to, - uint256 amount, - bytes data - ); - - /// @notice Emitted when someone deposit ERC20 token from L1 to L2. - /// @param l1Token The address of the token in L1. - /// @param l2Token The address of the token in L2. - /// @param from The address of sender in L1. - /// @param to The address of recipient in L2. - /// @param amount The amount of token will be deposited from L1 to L2. - /// @param data The optional calldata passed to recipient in L2. - event DepositERC20( - address indexed l1Token, - address indexed l2Token, - address indexed from, - address to, - uint256 amount, - bytes data - ); - - /// @notice Emitted when some ERC20 token is refunded. - /// @param token The address of the token in L1. - /// @param recipient The address of receiver in L1. - /// @param amount The amount of token refunded to receiver. - event RefundERC20(address indexed token, address indexed recipient, uint256 amount); - - /************************* - * Public View Functions * - *************************/ - - /// @notice Return the corresponding l2 token address given l1 token address. - /// @param _l1Token The address of l1 token. - function getL2ERC20Address(address _l1Token) external view returns (address); - - /***************************** - * Public Mutating Functions * - *****************************/ - - /// @notice Deposit some token to a caller's account on L2. - /// @dev Make this function payable to send relayer fee in Ether. - /// @param _token The address of token in L1. - /// @param _amount The amount of token to transfer. - /// @param _gasLimit Gas limit required to complete the deposit on L2. - function depositERC20( - address _token, - uint256 _amount, - uint256 _gasLimit - ) external payable; - - /// @notice Deposit some token to a recipient's account on L2. - /// @dev Make this function payable to send relayer fee in Ether. - /// @param _token The address of token in L1. - /// @param _to The address of recipient's account on L2. - /// @param _amount The amount of token to transfer. - /// @param _gasLimit Gas limit required to complete the deposit on L2. - function depositERC20( - address _token, - address _to, - uint256 _amount, - uint256 _gasLimit - ) external payable; - - /// @notice Deposit some token to a recipient's account on L2 and call. - /// @dev Make this function payable to send relayer fee in Ether. - /// @param _token The address of token in L1. - /// @param _to The address of recipient's account on L2. - /// @param _amount The amount of token to transfer. - /// @param _data Optional data to forward to recipient's account. - /// @param _gasLimit Gas limit required to complete the deposit on L2. - function depositERC20AndCall( - address _token, - address _to, - uint256 _amount, - bytes memory _data, - uint256 _gasLimit - ) external payable; - - /// @notice Complete ERC20 withdraw from L2 to L1 and send fund to recipient's account in L1. - /// @dev Make this function payable to handle WETH deposit/withdraw. - /// The function should only be called by L1ScrollMessenger. - /// The function should also only be called by L2ERC20Gateway in L2. - /// @param _l1Token The address of corresponding L1 token. - /// @param _l2Token The address of corresponding L2 token. - /// @param _from The address of account who withdraw the token in L2. - /// @param _to The address of recipient in L1 to receive the token. - /// @param _amount The amount of the token to withdraw. - /// @param _data Optional data to forward to recipient's account. - function finalizeWithdrawERC20( - address _l1Token, - address _l2Token, - address _from, - address _to, - uint256 _amount, - bytes calldata _data - ) external payable; -} diff --git a/contracts/src/L1/gateways/IL1ERC721Gateway.sol b/contracts/src/L1/gateways/IL1ERC721Gateway.sol deleted file mode 100644 index e6a027aa2..000000000 --- a/contracts/src/L1/gateways/IL1ERC721Gateway.sol +++ /dev/null @@ -1,160 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.24; - -/// @title The interface for the ERC721 cross chain gateway on layer 1. -interface IL1ERC721Gateway { - /********** - * Events * - **********/ - - /// @notice Emitted when the ERC721 NFT is transferred to recipient on layer 1. - /// @param _l1Token The address of ERC721 NFT on layer 1. - /// @param _l2Token The address of ERC721 NFT on layer 2. - /// @param _from The address of sender on layer 2. - /// @param _to The address of recipient on layer 1. - /// @param _tokenId The token id of the ERC721 NFT to withdraw from layer 2. - event FinalizeWithdrawERC721( - address indexed _l1Token, - address indexed _l2Token, - address indexed _from, - address _to, - uint256 _tokenId - ); - - /// @notice Emitted when the ERC721 NFT is batch transferred to recipient on layer 1. - /// @param _l1Token The address of ERC721 NFT on layer 1. - /// @param _l2Token The address of ERC721 NFT on layer 2. - /// @param _from The address of sender on layer 2. - /// @param _to The address of recipient on layer 1. - /// @param _tokenIds The list of token ids of the ERC721 NFT to withdraw from layer 2. - event FinalizeBatchWithdrawERC721( - address indexed _l1Token, - address indexed _l2Token, - address indexed _from, - address _to, - uint256[] _tokenIds - ); - - /// @notice Emitted when the ERC721 NFT is deposited to gateway on layer 1. - /// @param _l1Token The address of ERC721 NFT on layer 1. - /// @param _l2Token The address of ERC721 NFT on layer 2. - /// @param _from The address of sender on layer 1. - /// @param _to The address of recipient on layer 2. - /// @param _tokenId The token id of the ERC721 NFT to deposit on layer 1. - event DepositERC721( - address indexed _l1Token, - address indexed _l2Token, - address indexed _from, - address _to, - uint256 _tokenId - ); - - /// @notice Emitted when the ERC721 NFT is batch deposited to gateway on layer 1. - /// @param _l1Token The address of ERC721 NFT on layer 1. - /// @param _l2Token The address of ERC721 NFT on layer 2. - /// @param _from The address of sender on layer 1. - /// @param _to The address of recipient on layer 2. - /// @param _tokenIds The list of token ids of the ERC721 NFT to deposit on layer 1. - event BatchDepositERC721( - address indexed _l1Token, - address indexed _l2Token, - address indexed _from, - address _to, - uint256[] _tokenIds - ); - - /// @notice Emitted when some ERC721 token is refunded. - /// @param token The address of the token in L1. - /// @param recipient The address of receiver in L1. - /// @param tokenId The id of token refunded. - event RefundERC721(address indexed token, address indexed recipient, uint256 tokenId); - - /// @notice Emitted when a batch of ERC721 tokens are refunded. - /// @param token The address of the token in L1. - /// @param recipient The address of receiver in L1. - /// @param tokenIds The list of token ids of the ERC721 NFT refunded. - event BatchRefundERC721(address indexed token, address indexed recipient, uint256[] tokenIds); - - /***************************** - * Public Mutating Functions * - *****************************/ - - /// @notice Deposit some ERC721 NFT to caller's account on layer 2. - /// @param _token The address of ERC721 NFT on layer 1. - /// @param _tokenId The token id to deposit. - /// @param _gasLimit Estimated gas limit required to complete the deposit on layer 2. - function depositERC721( - address _token, - uint256 _tokenId, - uint256 _gasLimit - ) external payable; - - /// @notice Deposit some ERC721 NFT to a recipient's account on layer 2. - /// @param _token The address of ERC721 NFT on layer 1. - /// @param _to The address of recipient on layer 2. - /// @param _tokenId The token id to deposit. - /// @param _gasLimit Estimated gas limit required to complete the deposit on layer 2. - function depositERC721( - address _token, - address _to, - uint256 _tokenId, - uint256 _gasLimit - ) external payable; - - /// @notice Deposit a list of some ERC721 NFT to caller's account on layer 2. - /// @param _token The address of ERC721 NFT on layer 1. - /// @param _tokenIds The list of token ids to deposit. - /// @param _gasLimit Estimated gas limit required to complete the deposit on layer 2. - function batchDepositERC721( - address _token, - uint256[] calldata _tokenIds, - uint256 _gasLimit - ) external payable; - - /// @notice Deposit a list of some ERC721 NFT to a recipient's account on layer 2. - /// @param _token The address of ERC721 NFT on layer 1. - /// @param _to The address of recipient on layer 2. - /// @param _tokenIds The list of token ids to deposit. - /// @param _gasLimit Estimated gas limit required to complete the deposit on layer 2. - function batchDepositERC721( - address _token, - address _to, - uint256[] calldata _tokenIds, - uint256 _gasLimit - ) external payable; - - /// @notice Complete ERC721 withdraw from layer 2 to layer 1 and send NFT to recipient's account on layer 1. - /// @dev Requirements: - /// - The function should only be called by L1ScrollMessenger. - /// - The function should also only be called by L2ERC721Gateway on layer 2. - /// @param _l1Token The address of corresponding layer 1 token. - /// @param _l2Token The address of corresponding layer 2 token. - /// @param _from The address of account who withdraw the token on layer 2. - /// @param _to The address of recipient on layer 1 to receive the token. - /// @param _tokenId The token id to withdraw. - function finalizeWithdrawERC721( - address _l1Token, - address _l2Token, - address _from, - address _to, - uint256 _tokenId - ) external; - - /// @notice Complete ERC721 batch withdraw from layer 2 to layer 1 and send NFT to recipient's account on layer 1. - /// @dev Requirements: - /// - The function should only be called by L1ScrollMessenger. - /// - The function should also only be called by L2ERC721Gateway on layer 2. - /// @param _l1Token The address of corresponding layer 1 token. - /// @param _l2Token The address of corresponding layer 2 token. - /// @param _from The address of account who withdraw the token on layer 2. - /// @param _to The address of recipient on layer 1 to receive the token. - /// @param _tokenIds The list of token ids to withdraw. - function finalizeBatchWithdrawERC721( - address _l1Token, - address _l2Token, - address _from, - address _to, - uint256[] calldata _tokenIds - ) external; -} diff --git a/contracts/src/L1/gateways/IL1ETHGateway.sol b/contracts/src/L1/gateways/IL1ETHGateway.sol deleted file mode 100644 index 16721996c..000000000 --- a/contracts/src/L1/gateways/IL1ETHGateway.sol +++ /dev/null @@ -1,73 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.24; - -interface IL1ETHGateway { - /********** - * Events * - **********/ - - /// @notice Emitted when ETH is withdrawn from L2 to L1 and transfer to recipient. - /// @param from The address of sender in L2. - /// @param to The address of recipient in L1. - /// @param amount The amount of ETH withdrawn from L2 to L1. - /// @param data The optional calldata passed to recipient in L1. - event FinalizeWithdrawETH(address indexed from, address indexed to, uint256 amount, bytes data); - - /// @notice Emitted when someone deposit ETH from L1 to L2. - /// @param from The address of sender in L1. - /// @param to The address of recipient in L2. - /// @param amount The amount of ETH will be deposited from L1 to L2. - /// @param data The optional calldata passed to recipient in L2. - event DepositETH(address indexed from, address indexed to, uint256 amount, bytes data); - - /// @notice Emitted when some ETH is refunded. - /// @param recipient The address of receiver in L1. - /// @param amount The amount of ETH refunded to receiver. - event RefundETH(address indexed recipient, uint256 amount); - - /***************************** - * Public Mutating Functions * - *****************************/ - - /// @notice Deposit ETH to caller's account in L2. - /// @param amount The amount of ETH to be deposited. - /// @param gasLimit Gas limit required to complete the deposit on L2. - function depositETH(uint256 amount, uint256 gasLimit) external payable; - - /// @notice Deposit ETH to some recipient's account in L2. - /// @param to The address of recipient's account on L2. - /// @param amount The amount of ETH to be deposited. - /// @param gasLimit Gas limit required to complete the deposit on L2. - function depositETH( - address to, - uint256 amount, - uint256 gasLimit - ) external payable; - - /// @notice Deposit ETH to some recipient's account in L2 and call the target contract. - /// @param to The address of recipient's account on L2. - /// @param amount The amount of ETH to be deposited. - /// @param data Optional data to forward to recipient's account. - /// @param gasLimit Gas limit required to complete the deposit on L2. - function depositETHAndCall( - address to, - uint256 amount, - bytes calldata data, - uint256 gasLimit - ) external payable; - - /// @notice Complete ETH withdraw from L2 to L1 and send fund to recipient's account in L1. - /// @dev This function should only be called by L1ScrollMessenger. - /// This function should also only be called by L1ETHGateway in L2. - /// @param from The address of account who withdraw ETH in L2. - /// @param to The address of recipient in L1 to receive ETH. - /// @param amount The amount of ETH to withdraw. - /// @param data Optional data to forward to recipient's account. - function finalizeWithdrawETH( - address from, - address to, - uint256 amount, - bytes calldata data - ) external payable; -} diff --git a/contracts/src/L1/gateways/IL1GatewayRouter.sol b/contracts/src/L1/gateways/IL1GatewayRouter.sol deleted file mode 100644 index fd0aef9e6..000000000 --- a/contracts/src/L1/gateways/IL1GatewayRouter.sol +++ /dev/null @@ -1,70 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.24; - -import {IL1ETHGateway} from "./IL1ETHGateway.sol"; -import {IL1ERC20Gateway} from "./IL1ERC20Gateway.sol"; - -interface IL1GatewayRouter is IL1ETHGateway, IL1ERC20Gateway { - /********** - * Events * - **********/ - - /// @notice Emitted when the address of ETH Gateway is updated. - /// @param oldETHGateway The address of the old ETH Gateway. - /// @param newEthGateway The address of the new ETH Gateway. - event SetETHGateway(address indexed oldETHGateway, address indexed newEthGateway); - - /// @notice Emitted when the address of default ERC20 Gateway is updated. - /// @param oldDefaultERC20Gateway The address of the old default ERC20 Gateway. - /// @param newDefaultERC20Gateway The address of the new default ERC20 Gateway. - event SetDefaultERC20Gateway(address indexed oldDefaultERC20Gateway, address indexed newDefaultERC20Gateway); - - /// @notice Emitted when the `gateway` for `token` is updated. - /// @param token The address of token updated. - /// @param oldGateway The corresponding address of the old gateway. - /// @param newGateway The corresponding address of the new gateway. - event SetERC20Gateway(address indexed token, address indexed oldGateway, address indexed newGateway); - - /************************* - * Public View Functions * - *************************/ - - /// @notice Return the corresponding gateway address for given token address. - /// @param _token The address of token to query. - function getERC20Gateway(address _token) external view returns (address); - - /***************************** - * Public Mutating Functions * - *****************************/ - - /// @notice Request ERC20 token transfer from users to gateways. - /// @param sender The address of sender to request fund. - /// @param token The address of token to request. - /// @param amount The amount of token to request. - function requestERC20( - address sender, - address token, - uint256 amount - ) external returns (uint256); - - /************************ - * Restricted Functions * - ************************/ - - /// @notice Update the address of ETH gateway contract. - /// @dev This function should only be called by contract owner. - /// @param _ethGateway The address to update. - function setETHGateway(address _ethGateway) external; - - /// @notice Update the address of default ERC20 gateway contract. - /// @dev This function should only be called by contract owner. - /// @param _defaultERC20Gateway The address to update. - function setDefaultERC20Gateway(address _defaultERC20Gateway) external; - - /// @notice Update the mapping from token address to gateway address. - /// @dev This function should only be called by contract owner. - /// @param _tokens The list of addresses of tokens to update. - /// @param _gateways The list of addresses of gateways to update. - function setERC20Gateway(address[] calldata _tokens, address[] calldata _gateways) external; -} diff --git a/contracts/src/L1/gateways/L1CustomERC20Gateway.sol b/contracts/src/L1/gateways/L1CustomERC20Gateway.sol deleted file mode 100644 index e3af654a9..000000000 --- a/contracts/src/L1/gateways/L1CustomERC20Gateway.sol +++ /dev/null @@ -1,151 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {IERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; -import {SafeERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol"; - -import {IL2ERC20Gateway} from "../../L2/gateways/IL2ERC20Gateway.sol"; -import {IL1ScrollMessenger} from "../IL1ScrollMessenger.sol"; -import {IL1ERC20Gateway} from "./IL1ERC20Gateway.sol"; - -import {ScrollGatewayBase} from "../../libraries/gateway/ScrollGatewayBase.sol"; -import {L1ERC20Gateway} from "./L1ERC20Gateway.sol"; - -/// @title L1CustomERC20Gateway -/// @notice The `L1CustomERC20Gateway` is used to deposit custom ERC20 compatible tokens on layer 1 and -/// finalize withdraw the tokens from layer 2. -/// @dev The deposited tokens are held in this gateway. On finalizing withdraw, the corresponding -/// tokens will be transfer to the recipient directly. -contract L1CustomERC20Gateway is L1ERC20Gateway { - using SafeERC20Upgradeable for IERC20Upgradeable; - - /********** - * Events * - **********/ - - /// @notice Emitted when token mapping for ERC20 token is updated. - /// @param l1Token The address of ERC20 token in layer 1. - /// @param oldL2Token The address of the old corresponding ERC20 token in layer 2. - /// @param newL2Token The address of the new corresponding ERC20 token in layer 2. - event UpdateTokenMapping(address indexed l1Token, address indexed oldL2Token, address indexed newL2Token); - - /************* - * Variables * - *************/ - - /// @notice Mapping from l1 token address to l2 token address for ERC20 token. - mapping(address => address) public tokenMapping; - - /*************** - * Constructor * - ***************/ - - /// @notice Constructor for `L1CustomERC20Gateway` implementation contract. - /// - /// @param _counterpart The address of `L2USDCGateway` contract in L2. - /// @param _router The address of `L1GatewayRouter` contract in L1. - /// @param _messenger The address of `L1ScrollMessenger` contract L1. - constructor( - address _counterpart, - address _router, - address _messenger - ) ScrollGatewayBase(_counterpart, _router, _messenger) { - if (_router == address(0)) revert ErrorZeroAddress(); - _disableInitializers(); - } - - /// @notice Initialize the storage of L1CustomERC20Gateway. - /// - /// @dev The parameters `_counterpart`, `_router` and `_messenger` are no longer used. - /// - /// @param _counterpart The address of L2CustomERC20Gateway in L2. - /// @param _router The address of L1GatewayRouter in L1. - /// @param _messenger The address of L1ScrollMessenger in L1. - function initialize( - address _counterpart, - address _router, - address _messenger - ) external initializer { - ScrollGatewayBase._initialize(_counterpart, _router, _messenger); - } - - /************************* - * Public View Functions * - *************************/ - - /// @inheritdoc IL1ERC20Gateway - function getL2ERC20Address(address _l1Token) public view override returns (address) { - return tokenMapping[_l1Token]; - } - - /************************ - * Restricted Functions * - ************************/ - - /// @notice Update layer 1 to layer 2 token mapping. - /// @param _l1Token The address of ERC20 token on layer 1. - /// @param _l2Token The address of corresponding ERC20 token on layer 2. - function updateTokenMapping(address _l1Token, address _l2Token) external onlyOwner { - require(_l2Token != address(0), "token address cannot be 0"); - - address _oldL2Token = tokenMapping[_l1Token]; - tokenMapping[_l1Token] = _l2Token; - - emit UpdateTokenMapping(_l1Token, _oldL2Token, _l2Token); - } - - /********************** - * Internal Functions * - **********************/ - - /// @inheritdoc L1ERC20Gateway - function _beforeFinalizeWithdrawERC20( - address _l1Token, - address _l2Token, - address, - address, - uint256, - bytes calldata - ) internal virtual override { - require(msg.value == 0, "nonzero msg.value"); - require(_l2Token != address(0), "token address cannot be 0"); - require(_l2Token == tokenMapping[_l1Token], "l2 token mismatch"); - } - - /// @inheritdoc L1ERC20Gateway - function _beforeDropMessage( - address, - address, - uint256 - ) internal virtual override { - require(msg.value == 0, "nonzero msg.value"); - } - - /// @inheritdoc L1ERC20Gateway - function _deposit( - address _token, - address _to, - uint256 _amount, - bytes memory _data, - uint256 _gasLimit - ) internal virtual override nonReentrant { - address _l2Token = tokenMapping[_token]; - require(_l2Token != address(0), "no corresponding l2 token"); - - // 1. Transfer token into this contract. - address _from; - (_from, _amount, _data) = _transferERC20In(_token, _amount, _data); - - // 2. Generate message passed to L2CustomERC20Gateway. - bytes memory _message = abi.encodeCall( - IL2ERC20Gateway.finalizeDepositERC20, - (_token, _l2Token, _from, _to, _amount, _data) - ); - - // 3. Send message to L1ScrollMessenger. - IL1ScrollMessenger(messenger).sendMessage{value: msg.value}(counterpart, 0, _message, _gasLimit, _from); - - emit DepositERC20(_token, _l2Token, _from, _to, _amount, _data); - } -} diff --git a/contracts/src/L1/gateways/L1ERC1155Gateway.sol b/contracts/src/L1/gateways/L1ERC1155Gateway.sol deleted file mode 100644 index 794d43ce5..000000000 --- a/contracts/src/L1/gateways/L1ERC1155Gateway.sol +++ /dev/null @@ -1,261 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {IERC1155Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol"; -import {ERC1155HolderUpgradeable, ERC1155ReceiverUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC1155/utils/ERC1155HolderUpgradeable.sol"; - -import {IL2ERC1155Gateway} from "../../L2/gateways/IL2ERC1155Gateway.sol"; -import {IL1ScrollMessenger} from "../IL1ScrollMessenger.sol"; -import {IL1ERC1155Gateway} from "./IL1ERC1155Gateway.sol"; - -import {IMessageDropCallback} from "../../libraries/callbacks/IMessageDropCallback.sol"; -import {ScrollGatewayBase} from "../../libraries/gateway/ScrollGatewayBase.sol"; - -/// @title L1ERC1155Gateway -/// @notice The `L1ERC1155Gateway` is used to deposit ERC1155 compatible NFT on layer 1 and -/// finalize withdraw the NFTs from layer 2. -/// @dev The deposited NFTs are held in this gateway. On finalizing withdraw, the corresponding -/// NFT will be transfer to the recipient directly. -/// -/// This will be changed if we have more specific scenarios. -contract L1ERC1155Gateway is ERC1155HolderUpgradeable, ScrollGatewayBase, IL1ERC1155Gateway, IMessageDropCallback { - /********** - * Events * - **********/ - - /// @notice Emitted when token mapping for ERC1155 token is updated. - /// @param l1Token The address of ERC1155 token in layer 1. - /// @param oldL2Token The address of the old corresponding ERC1155 token in layer 2. - /// @param newL2Token The address of the new corresponding ERC1155 token in layer 2. - event UpdateTokenMapping(address indexed l1Token, address indexed oldL2Token, address indexed newL2Token); - - /************* - * Variables * - *************/ - - /// @notice Mapping from l1 token address to l2 token address for ERC1155 NFT. - mapping(address => address) public tokenMapping; - - /*************** - * Constructor * - ***************/ - - /// @notice Constructor for `L1ERC1155Gateway` implementation contract. - /// - /// @param _counterpart The address of `L1ERC1155Gateway` contract in L2. - /// @param _messenger The address of `L1ScrollMessenger` contract in L1. - constructor(address _counterpart, address _messenger) ScrollGatewayBase(_counterpart, address(0), _messenger) { - _disableInitializers(); - } - - /// @notice Initialize the storage of L1ERC1155Gateway. - /// @param _counterpart The address of L2ERC1155Gateway in L2. - /// @param _messenger The address of L1ScrollMessenger in L1. - function initialize(address _counterpart, address _messenger) external initializer { - ERC1155HolderUpgradeable.__ERC1155Holder_init(); - ERC1155ReceiverUpgradeable.__ERC1155Receiver_init(); - - ScrollGatewayBase._initialize(_counterpart, address(0), _messenger); - } - - /***************************** - * Public Mutating Functions * - *****************************/ - - /// @inheritdoc IL1ERC1155Gateway - function depositERC1155( - address _token, - uint256 _tokenId, - uint256 _amount, - uint256 _gasLimit - ) external payable override { - _depositERC1155(_token, _msgSender(), _tokenId, _amount, _gasLimit); - } - - /// @inheritdoc IL1ERC1155Gateway - function depositERC1155( - address _token, - address _to, - uint256 _tokenId, - uint256 _amount, - uint256 _gasLimit - ) external payable override { - _depositERC1155(_token, _to, _tokenId, _amount, _gasLimit); - } - - /// @inheritdoc IL1ERC1155Gateway - function batchDepositERC1155( - address _token, - uint256[] calldata _tokenIds, - uint256[] calldata _amounts, - uint256 _gasLimit - ) external payable override { - _batchDepositERC1155(_token, _msgSender(), _tokenIds, _amounts, _gasLimit); - } - - /// @inheritdoc IL1ERC1155Gateway - function batchDepositERC1155( - address _token, - address _to, - uint256[] calldata _tokenIds, - uint256[] calldata _amounts, - uint256 _gasLimit - ) external payable override { - _batchDepositERC1155(_token, _to, _tokenIds, _amounts, _gasLimit); - } - - /// @inheritdoc IL1ERC1155Gateway - function finalizeWithdrawERC1155( - address _l1Token, - address _l2Token, - address _from, - address _to, - uint256 _tokenId, - uint256 _amount - ) external virtual onlyCallByCounterpart nonReentrant { - require(_l2Token != address(0), "token address cannot be 0"); - require(_l2Token == tokenMapping[_l1Token], "l2 token mismatch"); - - IERC1155Upgradeable(_l1Token).safeTransferFrom(address(this), _to, _tokenId, _amount, ""); - - emit FinalizeWithdrawERC1155(_l1Token, _l2Token, _from, _to, _tokenId, _amount); - } - - /// @inheritdoc IL1ERC1155Gateway - function finalizeBatchWithdrawERC1155( - address _l1Token, - address _l2Token, - address _from, - address _to, - uint256[] calldata _tokenIds, - uint256[] calldata _amounts - ) external virtual onlyCallByCounterpart nonReentrant { - require(_l2Token != address(0), "token address cannot be 0"); - require(_l2Token == tokenMapping[_l1Token], "l2 token mismatch"); - - IERC1155Upgradeable(_l1Token).safeBatchTransferFrom(address(this), _to, _tokenIds, _amounts, ""); - - emit FinalizeBatchWithdrawERC1155(_l1Token, _l2Token, _from, _to, _tokenIds, _amounts); - } - - /// @inheritdoc IMessageDropCallback - function onDropMessage(bytes calldata _message) external payable virtual onlyInDropContext nonReentrant { - require(msg.value == 0, "nonzero msg.value"); - - if (bytes4(_message[0:4]) == IL2ERC1155Gateway.finalizeDepositERC1155.selector) { - (address _token, , address _sender, , uint256 _tokenId, uint256 _amount) = abi.decode( - _message[4:], - (address, address, address, address, uint256, uint256) - ); - IERC1155Upgradeable(_token).safeTransferFrom(address(this), _sender, _tokenId, _amount, ""); - - emit RefundERC1155(_token, _sender, _tokenId, _amount); - } else if (bytes4(_message[0:4]) == IL2ERC1155Gateway.finalizeBatchDepositERC1155.selector) { - (address _token, , address _sender, , uint256[] memory _tokenIds, uint256[] memory _amounts) = abi.decode( - _message[4:], - (address, address, address, address, uint256[], uint256[]) - ); - IERC1155Upgradeable(_token).safeBatchTransferFrom(address(this), _sender, _tokenIds, _amounts, ""); - - emit BatchRefundERC1155(_token, _sender, _tokenIds, _amounts); - } else { - revert("invalid selector"); - } - } - - /************************ - * Restricted Functions * - ************************/ - - /// @notice Update layer 2 to layer 2 token mapping. - /// @param _l1Token The address of ERC1155 token on layer 1. - /// @param _l2Token The address of corresponding ERC1155 token on layer 2. - function updateTokenMapping(address _l1Token, address _l2Token) external onlyOwner { - require(_l2Token != address(0), "token address cannot be 0"); - - address _oldL2Token = tokenMapping[_l1Token]; - tokenMapping[_l1Token] = _l2Token; - - emit UpdateTokenMapping(_l1Token, _oldL2Token, _l2Token); - } - - /********************** - * Internal Functions * - **********************/ - - /// @dev Internal function to deposit ERC1155 NFT to layer 2. - /// @param _token The address of ERC1155 NFT on layer 1. - /// @param _to The address of recipient on layer 2. - /// @param _tokenId The token id to deposit. - /// @param _amount The amount of token to deposit. - /// @param _gasLimit Estimated gas limit required to complete the deposit on layer 2. - function _depositERC1155( - address _token, - address _to, - uint256 _tokenId, - uint256 _amount, - uint256 _gasLimit - ) internal virtual nonReentrant { - require(_amount > 0, "deposit zero amount"); - - address _l2Token = tokenMapping[_token]; - require(_l2Token != address(0), "no corresponding l2 token"); - - address _sender = _msgSender(); - - // 1. transfer token to this contract - IERC1155Upgradeable(_token).safeTransferFrom(_sender, address(this), _tokenId, _amount, ""); - - // 2. Generate message passed to L2ERC1155Gateway. - bytes memory _message = abi.encodeCall( - IL2ERC1155Gateway.finalizeDepositERC1155, - (_token, _l2Token, _sender, _to, _tokenId, _amount) - ); - - // 3. Send message to L1ScrollMessenger. - IL1ScrollMessenger(messenger).sendMessage{value: msg.value}(counterpart, 0, _message, _gasLimit, _sender); - - emit DepositERC1155(_token, _l2Token, _sender, _to, _tokenId, _amount); - } - - /// @dev Internal function to batch deposit ERC1155 NFT to layer 2. - /// @param _token The address of ERC1155 NFT on layer 1. - /// @param _to The address of recipient on layer 2. - /// @param _tokenIds The list of token ids to deposit. - /// @param _amounts The list of corresponding number of token to deposit. - /// @param _gasLimit Estimated gas limit required to complete the deposit on layer 2. - function _batchDepositERC1155( - address _token, - address _to, - uint256[] calldata _tokenIds, - uint256[] calldata _amounts, - uint256 _gasLimit - ) internal virtual nonReentrant { - require(_tokenIds.length > 0, "no token to deposit"); - require(_tokenIds.length == _amounts.length, "length mismatch"); - - for (uint256 i = 0; i < _amounts.length; i++) { - require(_amounts[i] > 0, "deposit zero amount"); - } - - address _l2Token = tokenMapping[_token]; - require(_l2Token != address(0), "no corresponding l2 token"); - - address _sender = _msgSender(); - - // 1. transfer token to this contract - IERC1155Upgradeable(_token).safeBatchTransferFrom(_sender, address(this), _tokenIds, _amounts, ""); - - // 2. Generate message passed to L2ERC1155Gateway. - bytes memory _message = abi.encodeCall( - IL2ERC1155Gateway.finalizeBatchDepositERC1155, - (_token, _l2Token, _sender, _to, _tokenIds, _amounts) - ); - - // 3. Send message to L1ScrollMessenger. - IL1ScrollMessenger(messenger).sendMessage{value: msg.value}(counterpart, 0, _message, _gasLimit, _sender); - - emit BatchDepositERC1155(_token, _l2Token, _sender, _to, _tokenIds, _amounts); - } -} diff --git a/contracts/src/L1/gateways/L1ERC20Gateway.sol b/contracts/src/L1/gateways/L1ERC20Gateway.sol deleted file mode 100644 index f94035dce..000000000 --- a/contracts/src/L1/gateways/L1ERC20Gateway.sol +++ /dev/null @@ -1,181 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.24; - -import {IERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; -import {SafeERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol"; - -import {IL1ERC20Gateway} from "./IL1ERC20Gateway.sol"; -import {IL1GatewayRouter} from "./IL1GatewayRouter.sol"; - -import {IL2ERC20Gateway} from "../../L2/gateways/IL2ERC20Gateway.sol"; -import {ScrollGatewayBase} from "../../libraries/gateway/ScrollGatewayBase.sol"; -import {IMessageDropCallback} from "../../libraries/callbacks/IMessageDropCallback.sol"; - -/// @title L1ERC20Gateway -/// @notice The `L1ERC20Gateway` as a base contract for ERC20 gateways in L1. -/// It has implementation of common used functions for ERC20 gateways. -abstract contract L1ERC20Gateway is IL1ERC20Gateway, IMessageDropCallback, ScrollGatewayBase { - using SafeERC20Upgradeable for IERC20Upgradeable; - - /************* - * Variables * - *************/ - - /// @dev The storage slots for future usage. - uint256[50] private __gap; - - /***************************** - * Public Mutating Functions * - *****************************/ - - /// @inheritdoc IL1ERC20Gateway - function depositERC20( - address _token, - uint256 _amount, - uint256 _gasLimit - ) external payable override { - _deposit(_token, _msgSender(), _amount, new bytes(0), _gasLimit); - } - - /// @inheritdoc IL1ERC20Gateway - function depositERC20( - address _token, - address _to, - uint256 _amount, - uint256 _gasLimit - ) external payable override { - _deposit(_token, _to, _amount, new bytes(0), _gasLimit); - } - - /// @inheritdoc IL1ERC20Gateway - function depositERC20AndCall( - address _token, - address _to, - uint256 _amount, - bytes memory _data, - uint256 _gasLimit - ) external payable override { - _deposit(_token, _to, _amount, _data, _gasLimit); - } - - /// @inheritdoc IL1ERC20Gateway - function finalizeWithdrawERC20( - address _l1Token, - address _l2Token, - address _from, - address _to, - uint256 _amount, - bytes calldata _data - ) external payable virtual override onlyCallByCounterpart nonReentrant { - _beforeFinalizeWithdrawERC20(_l1Token, _l2Token, _from, _to, _amount, _data); - - // @note can possible trigger reentrant call to this contract or messenger, - // but it seems not a big problem. - IERC20Upgradeable(_l1Token).safeTransfer(_to, _amount); - - _doCallback(_to, _data); - - emit FinalizeWithdrawERC20(_l1Token, _l2Token, _from, _to, _amount, _data); - } - - /// @inheritdoc IMessageDropCallback - function onDropMessage(bytes calldata _message) external payable virtual onlyInDropContext nonReentrant { - // _message should start with 0x8431f5c1 => finalizeDepositERC20(address,address,address,address,uint256,bytes) - require(bytes4(_message[0:4]) == IL2ERC20Gateway.finalizeDepositERC20.selector, "invalid selector"); - - // decode (token, receiver, amount) - (address _token, , address _receiver, , uint256 _amount, ) = abi.decode( - _message[4:], - (address, address, address, address, uint256, bytes) - ); - - // do dome check for each custom gateway - _beforeDropMessage(_token, _receiver, _amount); - - IERC20Upgradeable(_token).safeTransfer(_receiver, _amount); - - emit RefundERC20(_token, _receiver, _amount); - } - - /********************** - * Internal Functions * - **********************/ - - /// @dev Internal function hook to perform checks and actions before finalizing the withdrawal. - /// @param _l1Token The address of corresponding L1 token in L1. - /// @param _l2Token The address of corresponding L2 token in L2. - /// @param _from The address of account who withdraw the token in L2. - /// @param _to The address of recipient in L1 to receive the token. - /// @param _amount The amount of the token to withdraw. - /// @param _data Optional data to forward to recipient's account. - function _beforeFinalizeWithdrawERC20( - address _l1Token, - address _l2Token, - address _from, - address _to, - uint256 _amount, - bytes calldata _data - ) internal virtual; - - /// @dev Internal function hook to perform checks and actions before dropping the message. - /// @param _token The L1 token address. - /// @param _receiver The recipient address on L1. - /// @param _amount The amount of token to refund. - function _beforeDropMessage( - address _token, - address _receiver, - uint256 _amount - ) internal virtual; - - /// @dev Internal function to transfer ERC20 token to this contract. - /// @param _token The address of token to transfer. - /// @param _amount The amount of token to transfer. - /// @param _data The data passed by caller. - function _transferERC20In( - address _token, - uint256 _amount, - bytes memory _data - ) - internal - returns ( - address, - uint256, - bytes memory - ) - { - address _sender = _msgSender(); - address _from = _sender; - if (router == _sender) { - // Extract real sender if this call is from L1GatewayRouter. - (_from, _data) = abi.decode(_data, (address, bytes)); - _amount = IL1GatewayRouter(_sender).requestERC20(_from, _token, _amount); - } else { - // common practice to handle fee on transfer token. - uint256 _before = IERC20Upgradeable(_token).balanceOf(address(this)); - IERC20Upgradeable(_token).safeTransferFrom(_from, address(this), _amount); - uint256 _after = IERC20Upgradeable(_token).balanceOf(address(this)); - // no unchecked here, since some weird token may return arbitrary balance. - _amount = _after - _before; - } - // ignore weird fee on transfer token - require(_amount > 0, "deposit zero amount"); - - return (_from, _amount, _data); - } - - /// @dev Internal function to do all the deposit operations. - /// - /// @param _token The token to deposit. - /// @param _to The recipient address to receive the token in L2. - /// @param _amount The amount of token to deposit. - /// @param _data Optional data to forward to recipient's account. - /// @param _gasLimit Gas limit required to complete the deposit on L2. - function _deposit( - address _token, - address _to, - uint256 _amount, - bytes memory _data, - uint256 _gasLimit - ) internal virtual; -} diff --git a/contracts/src/L1/gateways/L1ERC721Gateway.sol b/contracts/src/L1/gateways/L1ERC721Gateway.sol deleted file mode 100644 index f8ee61131..000000000 --- a/contracts/src/L1/gateways/L1ERC721Gateway.sol +++ /dev/null @@ -1,251 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {IERC721Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol"; -import {ERC721HolderUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC721/utils/ERC721HolderUpgradeable.sol"; - -import {IL2ERC721Gateway} from "../../L2/gateways/IL2ERC721Gateway.sol"; -import {IL1ScrollMessenger} from "../IL1ScrollMessenger.sol"; -import {IL1ERC721Gateway} from "./IL1ERC721Gateway.sol"; - -import {IMessageDropCallback} from "../../libraries/callbacks/IMessageDropCallback.sol"; -import {ScrollGatewayBase} from "../../libraries/gateway/ScrollGatewayBase.sol"; - -/// @title L1ERC721Gateway -/// @notice The `L1ERC721Gateway` is used to deposit ERC721 compatible NFT on layer 1 and -/// finalize withdraw the NFTs from layer 2. -/// @dev The deposited NFTs are held in this gateway. On finalizing withdraw, the corresponding -/// NFT will be transfer to the recipient directly. -/// -/// This will be changed if we have more specific scenarios. -contract L1ERC721Gateway is ERC721HolderUpgradeable, ScrollGatewayBase, IL1ERC721Gateway, IMessageDropCallback { - /********** - * Events * - **********/ - - /// @notice Emitted when token mapping for ERC721 token is updated. - /// @param l1Token The address of ERC721 token in layer 1. - /// @param oldL2Token The address of the old corresponding ERC721 token in layer 2. - /// @param newL2Token The address of the new corresponding ERC721 token in layer 2. - event UpdateTokenMapping(address indexed l1Token, address indexed oldL2Token, address indexed newL2Token); - - /************* - * Variables * - *************/ - - /// @notice Mapping from l1 token address to l2 token address for ERC721 NFT. - mapping(address => address) public tokenMapping; - - /*************** - * Constructor * - ***************/ - - /// @notice Constructor for `L2ERC721Gateway` implementation contract. - /// - /// @param _counterpart The address of `L2ERC721Gateway` contract in L2. - /// @param _messenger The address of `L1ScrollMessenger` contract in L1. - constructor(address _counterpart, address _messenger) ScrollGatewayBase(_counterpart, address(0), _messenger) { - _disableInitializers(); - } - - /// @notice Initialize the storage of L1ERC721Gateway. - /// - /// @dev The parameters `_counterpart` and `_messenger` are no longer used. - /// - /// @param _counterpart The address of L2ERC721Gateway in L2. - /// @param _messenger The address of L1ScrollMessenger in L1. - function initialize(address _counterpart, address _messenger) external initializer { - ERC721HolderUpgradeable.__ERC721Holder_init(); - - ScrollGatewayBase._initialize(_counterpart, address(0), _messenger); - } - - /***************************** - * Public Mutating Functions * - *****************************/ - - /// @inheritdoc IL1ERC721Gateway - function depositERC721( - address _token, - uint256 _tokenId, - uint256 _gasLimit - ) external payable override { - _depositERC721(_token, _msgSender(), _tokenId, _gasLimit); - } - - /// @inheritdoc IL1ERC721Gateway - function depositERC721( - address _token, - address _to, - uint256 _tokenId, - uint256 _gasLimit - ) external payable override { - _depositERC721(_token, _to, _tokenId, _gasLimit); - } - - /// @inheritdoc IL1ERC721Gateway - function batchDepositERC721( - address _token, - uint256[] calldata _tokenIds, - uint256 _gasLimit - ) external payable override { - _batchDepositERC721(_token, _msgSender(), _tokenIds, _gasLimit); - } - - /// @inheritdoc IL1ERC721Gateway - function batchDepositERC721( - address _token, - address _to, - uint256[] calldata _tokenIds, - uint256 _gasLimit - ) external payable override { - _batchDepositERC721(_token, _to, _tokenIds, _gasLimit); - } - - /// @inheritdoc IL1ERC721Gateway - function finalizeWithdrawERC721( - address _l1Token, - address _l2Token, - address _from, - address _to, - uint256 _tokenId - ) external virtual onlyCallByCounterpart nonReentrant { - require(_l2Token != address(0), "token address cannot be 0"); - require(_l2Token == tokenMapping[_l1Token], "l2 token mismatch"); - - IERC721Upgradeable(_l1Token).safeTransferFrom(address(this), _to, _tokenId); - - emit FinalizeWithdrawERC721(_l1Token, _l2Token, _from, _to, _tokenId); - } - - /// @inheritdoc IL1ERC721Gateway - function finalizeBatchWithdrawERC721( - address _l1Token, - address _l2Token, - address _from, - address _to, - uint256[] calldata _tokenIds - ) external virtual onlyCallByCounterpart nonReentrant { - require(_l2Token != address(0), "token address cannot be 0"); - require(_l2Token == tokenMapping[_l1Token], "l2 token mismatch"); - - for (uint256 i = 0; i < _tokenIds.length; i++) { - IERC721Upgradeable(_l1Token).safeTransferFrom(address(this), _to, _tokenIds[i]); - } - - emit FinalizeBatchWithdrawERC721(_l1Token, _l2Token, _from, _to, _tokenIds); - } - - /// @inheritdoc IMessageDropCallback - function onDropMessage(bytes calldata _message) external payable virtual onlyInDropContext nonReentrant { - require(msg.value == 0, "nonzero msg.value"); - - if (bytes4(_message[0:4]) == IL2ERC721Gateway.finalizeDepositERC721.selector) { - (address _token, , address _receiver, , uint256 _tokenId) = abi.decode( - _message[4:], - (address, address, address, address, uint256) - ); - IERC721Upgradeable(_token).safeTransferFrom(address(this), _receiver, _tokenId); - - emit RefundERC721(_token, _receiver, _tokenId); - } else if (bytes4(_message[0:4]) == IL2ERC721Gateway.finalizeBatchDepositERC721.selector) { - (address _token, , address _receiver, , uint256[] memory _tokenIds) = abi.decode( - _message[4:], - (address, address, address, address, uint256[]) - ); - for (uint256 i = 0; i < _tokenIds.length; i++) { - IERC721Upgradeable(_token).safeTransferFrom(address(this), _receiver, _tokenIds[i]); - } - emit BatchRefundERC721(_token, _receiver, _tokenIds); - } else { - revert("invalid selector"); - } - } - - /************************ - * Restricted Functions * - ************************/ - - /// @notice Update layer 2 to layer 2 token mapping. - /// @param _l1Token The address of ERC721 token on layer 1. - /// @param _l2Token The address of corresponding ERC721 token on layer 2. - function updateTokenMapping(address _l1Token, address _l2Token) external onlyOwner { - require(_l2Token != address(0), "token address cannot be 0"); - - address _oldL2Token = tokenMapping[_l1Token]; - tokenMapping[_l1Token] = _l2Token; - - emit UpdateTokenMapping(_l1Token, _oldL2Token, _l2Token); - } - - /********************** - * Internal Functions * - **********************/ - - /// @dev Internal function to deposit ERC721 NFT to layer 2. - /// @param _token The address of ERC721 NFT on layer 1. - /// @param _to The address of recipient on layer 2. - /// @param _tokenId The token id to deposit. - /// @param _gasLimit Estimated gas limit required to complete the deposit on layer 2. - function _depositERC721( - address _token, - address _to, - uint256 _tokenId, - uint256 _gasLimit - ) internal virtual nonReentrant { - address _l2Token = tokenMapping[_token]; - require(_l2Token != address(0), "no corresponding l2 token"); - - address _sender = _msgSender(); - - // 1. transfer token to this contract - IERC721Upgradeable(_token).safeTransferFrom(_sender, address(this), _tokenId); - - // 2. Generate message passed to L2ERC721Gateway. - bytes memory _message = abi.encodeCall( - IL2ERC721Gateway.finalizeDepositERC721, - (_token, _l2Token, _sender, _to, _tokenId) - ); - - // 3. Send message to L1ScrollMessenger. - IL1ScrollMessenger(messenger).sendMessage{value: msg.value}(counterpart, 0, _message, _gasLimit, _sender); - - emit DepositERC721(_token, _l2Token, _sender, _to, _tokenId); - } - - /// @dev Internal function to batch deposit ERC721 NFT to layer 2. - /// @param _token The address of ERC721 NFT on layer 1. - /// @param _to The address of recipient on layer 2. - /// @param _tokenIds The list of token ids to deposit. - /// @param _gasLimit Estimated gas limit required to complete the deposit on layer 2. - function _batchDepositERC721( - address _token, - address _to, - uint256[] calldata _tokenIds, - uint256 _gasLimit - ) internal virtual nonReentrant { - require(_tokenIds.length > 0, "no token to deposit"); - - address _l2Token = tokenMapping[_token]; - require(_l2Token != address(0), "no corresponding l2 token"); - - address _sender = _msgSender(); - - // 1. transfer token to this contract - for (uint256 i = 0; i < _tokenIds.length; i++) { - IERC721Upgradeable(_token).safeTransferFrom(_sender, address(this), _tokenIds[i]); - } - - // 2. Generate message passed to L2ERC721Gateway. - bytes memory _message = abi.encodeCall( - IL2ERC721Gateway.finalizeBatchDepositERC721, - (_token, _l2Token, _sender, _to, _tokenIds) - ); - - // 3. Send message to L1ScrollMessenger. - IL1ScrollMessenger(messenger).sendMessage{value: msg.value}(counterpart, 0, _message, _gasLimit, _sender); - - emit BatchDepositERC721(_token, _l2Token, _sender, _to, _tokenIds); - } -} diff --git a/contracts/src/L1/gateways/L1ETHGateway.sol b/contracts/src/L1/gateways/L1ETHGateway.sol deleted file mode 100644 index c268a1ba0..000000000 --- a/contracts/src/L1/gateways/L1ETHGateway.sol +++ /dev/null @@ -1,150 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {IL2ETHGateway} from "../../L2/gateways/IL2ETHGateway.sol"; -import {IL1ScrollMessenger} from "../IL1ScrollMessenger.sol"; -import {IL1ETHGateway} from "./IL1ETHGateway.sol"; - -import {IMessageDropCallback} from "../../libraries/callbacks/IMessageDropCallback.sol"; -import {ScrollGatewayBase} from "../../libraries/gateway/ScrollGatewayBase.sol"; - -// solhint-disable avoid-low-level-calls - -/// @title L1ETHGateway -/// @notice The `L1ETHGateway` is used to deposit ETH on layer 1 and -/// finalize withdraw ETH from layer 2. -/// @dev The deposited ETH tokens are held in this gateway. On finalizing withdraw, the corresponding -/// ETH will be transfer to the recipient directly. -contract L1ETHGateway is ScrollGatewayBase, IL1ETHGateway, IMessageDropCallback { - /*************** - * Constructor * - ***************/ - - /// @notice Constructor for `L1ETHGateway` implementation contract. - /// - /// @param _counterpart The address of `L2ETHGateway` contract in L2. - /// @param _router The address of `L1GatewayRouter` contract in L1. - /// @param _messenger The address of `L1ScrollMessenger` contract in L1. - constructor( - address _counterpart, - address _router, - address _messenger - ) ScrollGatewayBase(_counterpart, _router, _messenger) { - if (_router == address(0)) revert ErrorZeroAddress(); - - _disableInitializers(); - } - - /// @notice Initialize the storage of L1ETHGateway. - /// - /// @dev The parameters `_counterpart`, `_router` and `_messenger` are no longer used. - /// - /// @param _counterpart The address of L2ETHGateway in L2. - /// @param _router The address of L1GatewayRouter in L1. - /// @param _messenger The address of L1ScrollMessenger in L1. - function initialize( - address _counterpart, - address _router, - address _messenger - ) external initializer { - ScrollGatewayBase._initialize(_counterpart, _router, _messenger); - } - - /***************************** - * Public Mutating Functions * - *****************************/ - - /// @inheritdoc IL1ETHGateway - function depositETH(uint256 _amount, uint256 _gasLimit) external payable override { - _deposit(_msgSender(), _amount, new bytes(0), _gasLimit); - } - - /// @inheritdoc IL1ETHGateway - function depositETH( - address _to, - uint256 _amount, - uint256 _gasLimit - ) external payable override { - _deposit(_to, _amount, new bytes(0), _gasLimit); - } - - /// @inheritdoc IL1ETHGateway - function depositETHAndCall( - address _to, - uint256 _amount, - bytes calldata _data, - uint256 _gasLimit - ) external payable override { - _deposit(_to, _amount, _data, _gasLimit); - } - - /// @inheritdoc IL1ETHGateway - function finalizeWithdrawETH( - address _from, - address _to, - uint256 _amount, - bytes calldata _data - ) external payable override onlyCallByCounterpart nonReentrant { - require(msg.value == _amount, "msg.value mismatch"); - - // @note can possible trigger reentrant call to messenger, - // but it seems not a big problem. - (bool _success, ) = _to.call{value: _amount}(""); - require(_success, "ETH transfer failed"); - - _doCallback(_to, _data); - - emit FinalizeWithdrawETH(_from, _to, _amount, _data); - } - - /// @inheritdoc IMessageDropCallback - function onDropMessage(bytes calldata _message) external payable virtual onlyInDropContext nonReentrant { - // _message should start with 0x232e8748 => finalizeDepositETH(address,address,uint256,bytes) - require(bytes4(_message[0:4]) == IL2ETHGateway.finalizeDepositETH.selector, "invalid selector"); - - // decode (receiver, amount) - (address _receiver, , uint256 _amount, ) = abi.decode(_message[4:], (address, address, uint256, bytes)); - - require(_amount == msg.value, "msg.value mismatch"); - - (bool _success, ) = _receiver.call{value: _amount}(""); - require(_success, "ETH transfer failed"); - - emit RefundETH(_receiver, _amount); - } - - /********************** - * Internal Functions * - **********************/ - - /// @dev The internal ETH deposit implementation. - /// @param _to The address of recipient's account on L2. - /// @param _amount The amount of ETH to be deposited. - /// @param _data Optional data to forward to recipient's account. - /// @param _gasLimit Gas limit required to complete the deposit on L2. - function _deposit( - address _to, - uint256 _amount, - bytes memory _data, - uint256 _gasLimit - ) internal virtual nonReentrant { - require(_amount > 0, "deposit zero eth"); - - // 1. Extract real sender if this call is from L1GatewayRouter. - address _from = _msgSender(); - - if (router == _from) { - (_from, _data) = abi.decode(_data, (address, bytes)); - } - - // @note no rate limit here, since ETH is limited in messenger - - // 2. Generate message passed to L1ScrollMessenger. - bytes memory _message = abi.encodeCall(IL2ETHGateway.finalizeDepositETH, (_from, _to, _amount, _data)); - - IL1ScrollMessenger(messenger).sendMessage{value: msg.value}(counterpart, _amount, _message, _gasLimit, _from); - - emit DepositETH(_from, _to, _amount, _data); - } -} diff --git a/contracts/src/L1/gateways/L1GatewayRouter.sol b/contracts/src/L1/gateways/L1GatewayRouter.sol deleted file mode 100644 index 83f15e4f9..000000000 --- a/contracts/src/L1/gateways/L1GatewayRouter.sol +++ /dev/null @@ -1,253 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; -import {IERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; -import {SafeERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol"; - -import {IL1ETHGateway} from "./IL1ETHGateway.sol"; -import {IL1ERC20Gateway} from "./IL1ERC20Gateway.sol"; -import {IL1GatewayRouter} from "./IL1GatewayRouter.sol"; - -/// @title L1GatewayRouter -/// @notice The `L1GatewayRouter` is the main entry for depositing Ether and ERC20 tokens. -/// All deposited tokens are routed to corresponding gateways. -/// @dev One can also use this contract to query L1/L2 token address mapping. -/// In the future, ERC-721 and ERC-1155 tokens will be added to the router too. -contract L1GatewayRouter is OwnableUpgradeable, IL1GatewayRouter { - using SafeERC20Upgradeable for IERC20Upgradeable; - - /************* - * Variables * - *************/ - - /// @notice The address of L1ETHGateway. - address public ethGateway; - - /// @notice The address of default ERC20 gateway, normally the L1StandardERC20Gateway contract. - address public defaultERC20Gateway; - - /// @notice Mapping from ERC20 token address to corresponding L1ERC20Gateway. - // solhint-disable-next-line var-name-mixedcase - mapping(address => address) public ERC20Gateway; - - /// @notice The address of gateway in current execution context. - address public gatewayInContext; - - /********************** - * Function Modifiers * - **********************/ - - modifier onlyNotInContext() { - require(gatewayInContext == address(0), "Only not in context"); - _; - } - - modifier onlyInContext() { - require(_msgSender() == gatewayInContext, "Only in deposit context"); - _; - } - - /*************** - * Constructor * - ***************/ - - constructor() { - _disableInitializers(); - } - - /// @notice Initialize the storage of L1GatewayRouter. - /// @param _ethGateway The address of L1ETHGateway contract. - /// @param _defaultERC20Gateway The address of default ERC20 Gateway contract. - function initialize(address _ethGateway, address _defaultERC20Gateway) external initializer { - OwnableUpgradeable.__Ownable_init(); - - // it can be zero during initialization - if (_defaultERC20Gateway != address(0)) { - defaultERC20Gateway = _defaultERC20Gateway; - emit SetDefaultERC20Gateway(address(0), _defaultERC20Gateway); - } - - // it can be zero during initialization - if (_ethGateway != address(0)) { - ethGateway = _ethGateway; - emit SetETHGateway(address(0), _ethGateway); - } - } - - /************************* - * Public View Functions * - *************************/ - - /// @inheritdoc IL1ERC20Gateway - function getL2ERC20Address(address _l1Address) external view override returns (address) { - address _gateway = getERC20Gateway(_l1Address); - if (_gateway == address(0)) { - return address(0); - } - - return IL1ERC20Gateway(_gateway).getL2ERC20Address(_l1Address); - } - - /// @inheritdoc IL1GatewayRouter - function getERC20Gateway(address _token) public view returns (address) { - address _gateway = ERC20Gateway[_token]; - if (_gateway == address(0)) { - _gateway = defaultERC20Gateway; - } - return _gateway; - } - - /***************************** - * Public Mutating Functions * - *****************************/ - - /// @inheritdoc IL1GatewayRouter - /// @dev All the gateways should have reentrancy guard to prevent potential attack though this function. - function requestERC20( - address _sender, - address _token, - uint256 _amount - ) external onlyInContext returns (uint256) { - address _caller = _msgSender(); - uint256 _balance = IERC20Upgradeable(_token).balanceOf(_caller); - IERC20Upgradeable(_token).safeTransferFrom(_sender, _caller, _amount); - _amount = IERC20Upgradeable(_token).balanceOf(_caller) - _balance; - return _amount; - } - - /************************************************* - * Public Mutating Functions from L1ERC20Gateway * - *************************************************/ - - /// @inheritdoc IL1ERC20Gateway - function depositERC20( - address _token, - uint256 _amount, - uint256 _gasLimit - ) external payable override { - depositERC20AndCall(_token, _msgSender(), _amount, new bytes(0), _gasLimit); - } - - /// @inheritdoc IL1ERC20Gateway - function depositERC20( - address _token, - address _to, - uint256 _amount, - uint256 _gasLimit - ) external payable override { - depositERC20AndCall(_token, _to, _amount, new bytes(0), _gasLimit); - } - - /// @inheritdoc IL1ERC20Gateway - function depositERC20AndCall( - address _token, - address _to, - uint256 _amount, - bytes memory _data, - uint256 _gasLimit - ) public payable override onlyNotInContext { - address _gateway = getERC20Gateway(_token); - require(_gateway != address(0), "no gateway available"); - - // enter deposit context - gatewayInContext = _gateway; - - // encode msg.sender with _data - bytes memory _routerData = abi.encode(_msgSender(), _data); - - IL1ERC20Gateway(_gateway).depositERC20AndCall{value: msg.value}(_token, _to, _amount, _routerData, _gasLimit); - - // leave deposit context - gatewayInContext = address(0); - } - - /// @inheritdoc IL1ERC20Gateway - function finalizeWithdrawERC20( - address, - address, - address, - address, - uint256, - bytes calldata - ) external payable virtual override { - revert("should never be called"); - } - - /*********************************************** - * Public Mutating Functions from L1ETHGateway * - ***********************************************/ - - /// @inheritdoc IL1ETHGateway - function depositETH(uint256 _amount, uint256 _gasLimit) external payable override { - depositETHAndCall(_msgSender(), _amount, new bytes(0), _gasLimit); - } - - /// @inheritdoc IL1ETHGateway - function depositETH( - address _to, - uint256 _amount, - uint256 _gasLimit - ) external payable override { - depositETHAndCall(_to, _amount, new bytes(0), _gasLimit); - } - - /// @inheritdoc IL1ETHGateway - function depositETHAndCall( - address _to, - uint256 _amount, - bytes memory _data, - uint256 _gasLimit - ) public payable override onlyNotInContext { - address _gateway = ethGateway; - require(_gateway != address(0), "eth gateway available"); - - // encode msg.sender with _data - bytes memory _routerData = abi.encode(_msgSender(), _data); - - IL1ETHGateway(_gateway).depositETHAndCall{value: msg.value}(_to, _amount, _routerData, _gasLimit); - } - - /// @inheritdoc IL1ETHGateway - function finalizeWithdrawETH( - address, - address, - uint256, - bytes calldata - ) external payable virtual override { - revert("should never be called"); - } - - /************************ - * Restricted Functions * - ************************/ - - /// @inheritdoc IL1GatewayRouter - function setETHGateway(address _newEthGateway) external onlyOwner { - address _oldETHGateway = ethGateway; - ethGateway = _newEthGateway; - - emit SetETHGateway(_oldETHGateway, _newEthGateway); - } - - /// @inheritdoc IL1GatewayRouter - function setDefaultERC20Gateway(address _newDefaultERC20Gateway) external onlyOwner { - address _oldDefaultERC20Gateway = defaultERC20Gateway; - defaultERC20Gateway = _newDefaultERC20Gateway; - - emit SetDefaultERC20Gateway(_oldDefaultERC20Gateway, _newDefaultERC20Gateway); - } - - /// @inheritdoc IL1GatewayRouter - function setERC20Gateway(address[] memory _tokens, address[] memory _gateways) external onlyOwner { - require(_tokens.length == _gateways.length, "length mismatch"); - - for (uint256 i = 0; i < _tokens.length; i++) { - address _oldGateway = ERC20Gateway[_tokens[i]]; - ERC20Gateway[_tokens[i]] = _gateways[i]; - - emit SetERC20Gateway(_tokens[i], _oldGateway, _gateways[i]); - } - } -} diff --git a/contracts/src/L1/gateways/L1StandardERC20Gateway.sol b/contracts/src/L1/gateways/L1StandardERC20Gateway.sol deleted file mode 100644 index 2b36e2bf6..000000000 --- a/contracts/src/L1/gateways/L1StandardERC20Gateway.sol +++ /dev/null @@ -1,183 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {ClonesUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/ClonesUpgradeable.sol"; -import {IERC20MetadataUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol"; - -import {IL2ERC20Gateway} from "../../L2/gateways/IL2ERC20Gateway.sol"; -import {IL1ScrollMessenger} from "../IL1ScrollMessenger.sol"; -import {IL1ERC20Gateway} from "./IL1ERC20Gateway.sol"; - -import {ScrollGatewayBase} from "../../libraries/gateway/ScrollGatewayBase.sol"; -import {L1ERC20Gateway} from "./L1ERC20Gateway.sol"; - -/// @title L1StandardERC20Gateway -/// @notice The `L1StandardERC20Gateway` is used to deposit standard ERC20 tokens on layer 1 and -/// finalize withdraw the tokens from layer 2. -/// @dev The deposited ERC20 tokens are held in this gateway. On finalizing withdraw, the corresponding -/// token will be transfer to the recipient directly. Any ERC20 that requires non-standard functionality -/// should use a separate gateway. -contract L1StandardERC20Gateway is L1ERC20Gateway { - /************* - * Constants * - *************/ - - /// @notice The address of ScrollStandardERC20 implementation in L2. - address public immutable l2TokenImplementation; - - /// @notice The address of ScrollStandardERC20Factory contract in L2. - address public immutable l2TokenFactory; - - /************* - * Variables * - *************/ - - /// @dev The storage slot used as ScrollStandardERC20 implementation in L2, which is deprecated now. - address private __l2TokenImplementation; - - /// @dev The storage slot used as ScrollStandardERC20Factory contract in L2, which is deprecated now. - address private __l2TokenFactory; - - /// @notice Mapping from l1 token address to l2 token address. - /// @dev This is not necessary, since we can compute the address directly. But, we use this mapping - /// to keep track on whether we have deployed the token in L2 using the L2ScrollStandardERC20Factory and - /// pass deploy data on first call to the token. - mapping(address => address) private tokenMapping; - - /*************** - * Constructor * - ***************/ - - /// @notice Constructor for `L1StandardERC20Gateway` implementation contract. - /// - /// @param _counterpart The address of `L2StandardERC20Gateway` contract in L2. - /// @param _router The address of `L1GatewayRouter` contract in L1. - /// @param _messenger The address of `L1ScrollMessenger` contract in L1. - /// @param _l2TokenImplementation The address of `ScrollStandardERC20` implementation in L2. - /// @param _l2TokenFactory The address of `ScrollStandardERC20Factory` contract in L2. - constructor( - address _counterpart, - address _router, - address _messenger, - address _l2TokenImplementation, - address _l2TokenFactory - ) ScrollGatewayBase(_counterpart, _router, _messenger) { - if (_router == address(0) || _l2TokenImplementation == address(0) || _l2TokenFactory == address(0)) { - revert ErrorZeroAddress(); - } - - _disableInitializers(); - - l2TokenImplementation = _l2TokenImplementation; - l2TokenFactory = _l2TokenFactory; - } - - /// @notice Initialize the storage of L1StandardERC20Gateway. - /// - /// @dev The parameters `_counterpart`, `_router`, `_messenger`, `_l2TokenImplementation` and - /// `_l2TokenFactory` are no longer used. - /// - /// @param _counterpart The address of L2StandardERC20Gateway in L2. - /// @param _router The address of L1GatewayRouter in L1. - /// @param _messenger The address of L1ScrollMessenger in L1. - function initialize( - address _counterpart, - address _router, - address _messenger, - address, /*_l2TokenImplementation*/ - address /*_l2TokenFactory*/ - ) external initializer { - ScrollGatewayBase._initialize(_counterpart, _router, _messenger); - } - - /************************* - * Public View Functions * - *************************/ - - /// @inheritdoc IL1ERC20Gateway - function getL2ERC20Address(address _l1Token) public view override returns (address) { - // In StandardERC20Gateway, all corresponding l2 tokens are deployed by Create2 with salt, - // we can calculate the l2 address directly. - bytes32 _salt = keccak256(abi.encodePacked(counterpart, keccak256(abi.encodePacked(_l1Token)))); - - return ClonesUpgradeable.predictDeterministicAddress(l2TokenImplementation, _salt, l2TokenFactory); - } - - /********************** - * Internal Functions * - **********************/ - - /// @inheritdoc L1ERC20Gateway - function _beforeFinalizeWithdrawERC20( - address _l1Token, - address _l2Token, - address, - address, - uint256, - bytes calldata - ) internal virtual override { - require(msg.value == 0, "nonzero msg.value"); - require(_l2Token != address(0), "token address cannot be 0"); - require(getL2ERC20Address(_l1Token) == _l2Token, "l2 token mismatch"); - - // update `tokenMapping` on first withdraw - address _storedL2Token = tokenMapping[_l1Token]; - if (_storedL2Token == address(0)) { - tokenMapping[_l1Token] = _l2Token; - } else { - require(_storedL2Token == _l2Token, "l2 token mismatch"); - } - } - - /// @inheritdoc L1ERC20Gateway - function _beforeDropMessage( - address, - address, - uint256 - ) internal virtual override { - require(msg.value == 0, "nonzero msg.value"); - } - - /// @inheritdoc L1ERC20Gateway - function _deposit( - address _token, - address _to, - uint256 _amount, - bytes memory _data, - uint256 _gasLimit - ) internal virtual override nonReentrant { - require(_amount > 0, "deposit zero amount"); - - // 1. Transfer token into this contract. - address _from; - (_from, _amount, _data) = _transferERC20In(_token, _amount, _data); - - // 2. Generate message passed to L2StandardERC20Gateway. - address _l2Token = tokenMapping[_token]; - bytes memory _l2Data; - if (_l2Token == address(0)) { - // @note we won't update `tokenMapping` here but update the `tokenMapping` on - // first successful withdraw. This will prevent user to set arbitrary token - // metadata by setting a very small `_gasLimit` on the first tx. - _l2Token = getL2ERC20Address(_token); - - // passing symbol/name/decimal in order to deploy in L2. - string memory _symbol = IERC20MetadataUpgradeable(_token).symbol(); - string memory _name = IERC20MetadataUpgradeable(_token).name(); - uint8 _decimals = IERC20MetadataUpgradeable(_token).decimals(); - _l2Data = abi.encode(true, abi.encode(_data, abi.encode(_symbol, _name, _decimals))); - } else { - _l2Data = abi.encode(false, _data); - } - bytes memory _message = abi.encodeCall( - IL2ERC20Gateway.finalizeDepositERC20, - (_token, _l2Token, _from, _to, _amount, _l2Data) - ); - - // 3. Send message to L1ScrollMessenger. - IL1ScrollMessenger(messenger).sendMessage{value: msg.value}(counterpart, 0, _message, _gasLimit, _from); - - emit DepositERC20(_token, _l2Token, _from, _to, _amount, _data); - } -} diff --git a/contracts/src/L1/gateways/L1WETHGateway.sol b/contracts/src/L1/gateways/L1WETHGateway.sol deleted file mode 100644 index 9adfd7af7..000000000 --- a/contracts/src/L1/gateways/L1WETHGateway.sol +++ /dev/null @@ -1,153 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {IWETH} from "../../interfaces/IWETH.sol"; -import {IL2ERC20Gateway} from "../../L2/gateways/IL2ERC20Gateway.sol"; -import {IL1ScrollMessenger} from "../IL1ScrollMessenger.sol"; -import {IL1ERC20Gateway} from "./IL1ERC20Gateway.sol"; - -import {ScrollGatewayBase} from "../../libraries/gateway/ScrollGatewayBase.sol"; -import {L1ERC20Gateway} from "./L1ERC20Gateway.sol"; - -/// @title L1WETHGateway -/// @notice The `L1WETHGateway` contract is used to deposit `WETH` token on layer 1 and -/// finalize withdraw `WETH` from layer 2. -/// @dev The deposited WETH tokens are not held in the gateway. It will first be unwrapped -/// as Ether and then the Ether will be sent to the `L1ScrollMessenger` contract. -/// On finalizing withdraw, the Ether will be transferred from `L1ScrollMessenger`, then -/// wrapped as WETH and finally transfer to recipient. -contract L1WETHGateway is L1ERC20Gateway { - /************* - * Constants * - *************/ - - /// @notice The address of L2 WETH address. - address public immutable l2WETH; - - /// @notice The address of L1 WETH address. - // solhint-disable-next-line var-name-mixedcase - address public immutable WETH; - - /*************** - * Constructor * - ***************/ - - /// @notice Constructor for `L1WETHGateway` implementation contract. - /// - /// @param _WETH The address of WETH in L1. - /// @param _l2WETH The address of WETH in L2. - /// @param _counterpart The address of `L2WETHGateway` contract in L2. - /// @param _router The address of `L1GatewayRouter` contract in L1. - /// @param _messenger The address of `L1ScrollMessenger` contract in L1. - constructor( - address _WETH, - address _l2WETH, - address _counterpart, - address _router, - address _messenger - ) ScrollGatewayBase(_counterpart, _router, _messenger) { - if (_WETH == address(0) || _l2WETH == address(0) || _router == address(0)) { - revert ErrorZeroAddress(); - } - - _disableInitializers(); - - WETH = _WETH; - l2WETH = _l2WETH; - } - - /// @notice Initialize the storage of L1WETHGateway. - /// - /// @dev The parameters `_counterpart`, `_router` and `_messenger` are no longer used. - /// - /// @param _counterpart The address of L2ETHGateway in L2. - /// @param _router The address of L1GatewayRouter in L1. - /// @param _messenger The address of L1ScrollMessenger in L1. - function initialize( - address _counterpart, - address _router, - address _messenger - ) external initializer { - ScrollGatewayBase._initialize(_counterpart, _router, _messenger); - } - - receive() external payable { - require(_msgSender() == WETH, "only WETH"); - } - - /************************* - * Public View Functions * - *************************/ - - /// @inheritdoc IL1ERC20Gateway - function getL2ERC20Address(address) public view override returns (address) { - return l2WETH; - } - - /********************** - * Internal Functions * - **********************/ - - /// @inheritdoc L1ERC20Gateway - function _beforeFinalizeWithdrawERC20( - address _l1Token, - address _l2Token, - address, - address, - uint256 _amount, - bytes calldata - ) internal virtual override { - require(_l1Token == WETH, "l1 token not WETH"); - require(_l2Token == l2WETH, "l2 token not WETH"); - require(_amount == msg.value, "msg.value mismatch"); - - IWETH(_l1Token).deposit{value: _amount}(); - } - - /// @inheritdoc L1ERC20Gateway - function _beforeDropMessage( - address _token, - address, - uint256 _amount - ) internal virtual override { - require(_token == WETH, "token not WETH"); - require(_amount == msg.value, "msg.value mismatch"); - - IWETH(_token).deposit{value: _amount}(); - } - - /// @inheritdoc L1ERC20Gateway - function _deposit( - address _token, - address _to, - uint256 _amount, - bytes memory _data, - uint256 _gasLimit - ) internal virtual override nonReentrant { - require(_amount > 0, "deposit zero amount"); - require(_token == WETH, "only WETH is allowed"); - - // 1. Transfer token into this contract. - address _from; - (_from, _amount, _data) = _transferERC20In(_token, _amount, _data); - IWETH(_token).withdraw(_amount); - - // 2. Generate message passed to L2WETHGateway. - bytes memory _message = abi.encodeCall( - IL2ERC20Gateway.finalizeDepositERC20, - (_token, l2WETH, _from, _to, _amount, _data) - ); - - // 3. Send message to L1ScrollMessenger. - IL1ScrollMessenger(messenger).sendMessage{value: _amount + msg.value}( - counterpart, - _amount, - _message, - _gasLimit, - _from - ); - - emit DepositERC20(_token, l2WETH, _from, _to, _amount, _data); - } -} diff --git a/contracts/src/L1/gateways/usdc/L1USDCGateway.sol b/contracts/src/L1/gateways/usdc/L1USDCGateway.sol deleted file mode 100644 index bae81de37..000000000 --- a/contracts/src/L1/gateways/usdc/L1USDCGateway.sol +++ /dev/null @@ -1,193 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {IFiatToken} from "../../../interfaces/IFiatToken.sol"; -import {IUSDCBurnableSourceBridge} from "../../../interfaces/IUSDCBurnableSourceBridge.sol"; -import {IL2ERC20Gateway} from "../../../L2/gateways/IL2ERC20Gateway.sol"; -import {IL1ScrollMessenger} from "../../IL1ScrollMessenger.sol"; -import {IL1ERC20Gateway} from "../IL1ERC20Gateway.sol"; - -import {ScrollGatewayBase} from "../../../libraries/gateway/ScrollGatewayBase.sol"; -import {L1ERC20Gateway} from "../L1ERC20Gateway.sol"; - -/// @title L1USDCGateway -/// @notice The `L1USDCGateway` contract is used to deposit `USDC` token in layer 1 and -/// finalize withdraw `USDC` from layer 2, before USDC become native in layer 2. -contract L1USDCGateway is L1ERC20Gateway, IUSDCBurnableSourceBridge { - /************* - * Constants * - *************/ - - /// @notice The address of L1 USDC address. - // solhint-disable-next-line var-name-mixedcase - address public immutable l1USDC; - - /// @notice The address of L2 USDC address. - address public immutable l2USDC; - - /************* - * Variables * - *************/ - - /// @notice The address of caller from Circle. - address public circleCaller; - - /// @notice The flag indicates whether USDC deposit is paused. - bool public depositPaused; - - /// @notice The flag indicates whether USDC withdrawal is paused. - /// @dev This is not necessary to be set `true` since we will set `L2USDCGateway.withdrawPaused` first. - /// This is kept just in case and will be set after all pending messages are relayed. - bool public withdrawPaused; - - /// @notice The total amount of bridged USDC in this contract. - /// @dev Only deposited USDC will count. Accidentally transferred USDC will be ignored. - uint256 public totalBridgedUSDC; - - /*************** - * Constructor * - ***************/ - - /// @notice Constructor for `L1USDCGateway` implementation contract. - /// - /// @param _l1USDC The address of USDC in L1. - /// @param _l2USDC The address of USDC in L2. - /// @param _counterpart The address of `L2USDCGateway` contract in L2. - /// @param _router The address of `L1GatewayRouter` contract in L1. - /// @param _messenger The address of `L1ScrollMessenger` contract in L1. - constructor( - address _l1USDC, - address _l2USDC, - address _counterpart, - address _router, - address _messenger - ) ScrollGatewayBase(_counterpart, _router, _messenger) { - if (_l1USDC == address(0) || _l2USDC == address(0) || _router == address(0)) { - revert ErrorZeroAddress(); - } - - _disableInitializers(); - - l1USDC = _l1USDC; - l2USDC = _l2USDC; - } - - /// @notice Initialize the storage of L1USDCGateway. - /// - /// @dev The parameters `_counterpart`, `_router` and `_messenger` are no longer used. - /// - /// @param _counterpart The address of L2USDCGateway in L2. - /// @param _router The address of L1GatewayRouter in L1. - /// @param _messenger The address of L1ScrollMessenger in L1. - function initialize( - address _counterpart, - address _router, - address _messenger - ) external initializer { - ScrollGatewayBase._initialize(_counterpart, _router, _messenger); - } - - /************************* - * Public View Functions * - *************************/ - - /// @inheritdoc IL1ERC20Gateway - function getL2ERC20Address(address) public view override returns (address) { - return l2USDC; - } - - /******************************* - * Public Restricted Functions * - *******************************/ - - /// @inheritdoc IUSDCBurnableSourceBridge - function burnAllLockedUSDC() external override { - require(_msgSender() == circleCaller, "only circle caller"); - - // @note Only bridged USDC will be burned. We may refund the rest if possible. - uint256 _balance = totalBridgedUSDC; - totalBridgedUSDC = 0; - - IFiatToken(l1USDC).burn(_balance); - } - - /// @notice Update the Circle EOA address. - /// @param _caller The address to update. - function updateCircleCaller(address _caller) external onlyOwner { - circleCaller = _caller; - } - - /// @notice Change the deposit pause status of this contract. - /// @param _paused The new status, `true` means paused and `false` means not paused. - function pauseDeposit(bool _paused) external onlyOwner { - depositPaused = _paused; - } - - /// @notice Change the withdraw pause status of this contract. - /// @param _paused The new status, `true` means paused and `false` means not paused. - function pauseWithdraw(bool _paused) external onlyOwner { - withdrawPaused = _paused; - } - - /********************** - * Internal Functions * - **********************/ - - /// @inheritdoc L1ERC20Gateway - function _beforeFinalizeWithdrawERC20( - address _l1Token, - address _l2Token, - address, - address, - uint256 _amount, - bytes calldata - ) internal virtual override { - require(msg.value == 0, "nonzero msg.value"); - require(_l1Token == l1USDC, "l1 token not USDC"); - require(_l2Token == l2USDC, "l2 token not USDC"); - require(!withdrawPaused, "withdraw paused"); - - totalBridgedUSDC -= _amount; - } - - /// @inheritdoc L1ERC20Gateway - function _beforeDropMessage( - address, - address, - uint256 _amount - ) internal virtual override { - require(msg.value == 0, "nonzero msg.value"); - totalBridgedUSDC -= _amount; - } - - /// @inheritdoc L1ERC20Gateway - function _deposit( - address _token, - address _to, - uint256 _amount, - bytes memory _data, - uint256 _gasLimit - ) internal virtual override nonReentrant { - require(_amount > 0, "deposit zero amount"); - require(_token == l1USDC, "only USDC is allowed"); - require(!depositPaused, "deposit paused"); - - // 1. Transfer token into this contract. - address _from; - (_from, _amount, _data) = _transferERC20In(_token, _amount, _data); - require(_data.length == 0, "call is not allowed"); - totalBridgedUSDC += _amount; - - // 2. Generate message passed to L2USDCGateway. - bytes memory _message = abi.encodeCall( - IL2ERC20Gateway.finalizeDepositERC20, - (_token, l2USDC, _from, _to, _amount, _data) - ); - - // 3. Send message to L1ScrollMessenger. - IL1ScrollMessenger(messenger).sendMessage{value: msg.value}(counterpart, 0, _message, _gasLimit, _from); - - emit DepositERC20(_token, l2USDC, _from, _to, _amount, _data); - } -} diff --git a/contracts/src/L1/gateways/usdc/draft-L1USDCGatewayCCTP.sol b/contracts/src/L1/gateways/usdc/draft-L1USDCGatewayCCTP.sol deleted file mode 100644 index 35d101a9b..000000000 --- a/contracts/src/L1/gateways/usdc/draft-L1USDCGatewayCCTP.sol +++ /dev/null @@ -1,187 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; - -import {ITokenMessenger} from "../../../interfaces/ITokenMessenger.sol"; -import {IL2ERC20Gateway} from "../../../L2/gateways/IL2ERC20Gateway.sol"; -import {IL1ScrollMessenger} from "../../IL1ScrollMessenger.sol"; -import {IL1ERC20Gateway} from "../IL1ERC20Gateway.sol"; - -import {CCTPGatewayBase} from "../../../libraries/gateway/CCTPGatewayBase.sol"; -import {ScrollGatewayBase} from "../../../libraries/gateway/ScrollGatewayBase.sol"; -import {L1ERC20Gateway} from "../L1ERC20Gateway.sol"; - -/// @title L1USDCGatewayCCTP -/// @notice The `L1USDCGateway` contract is used to deposit `USDC` token in layer 1 and -/// finalize withdraw `USDC` from layer 2, after USDC become native in layer 2. -contract L1USDCGatewayCCTP is CCTPGatewayBase, L1ERC20Gateway { - /*************** - * Constructor * - ***************/ - - constructor( - address _l1USDC, - address _l2USDC, - uint32 _destinationDomain, - address _counterpart, - address _router, - address _messenger - ) CCTPGatewayBase(_l1USDC, _l2USDC, _destinationDomain) ScrollGatewayBase(_counterpart, _router, _messenger) { - if (_router == address(0)) revert ErrorZeroAddress(); - - _disableInitializers(); - } - - /// @notice Initialize the storage of L1USDCGatewayCCTP. - /// - /// @dev The parameters `_counterpart`, `_router`, `_messenger` are no longer used. - /// - /// @param _counterpart The address of L2USDCGatewayCCTP in L2. - /// @param _router The address of L1GatewayRouter. - /// @param _messenger The address of L1ScrollMessenger. - /// @param _cctpMessenger The address of TokenMessenger in local domain. - /// @param _cctpTransmitter The address of MessageTransmitter in local domain. - function initialize( - address _counterpart, - address _router, - address _messenger, - address _cctpMessenger, - address _cctpTransmitter - ) external initializer { - ScrollGatewayBase._initialize(_counterpart, _router, _messenger); - CCTPGatewayBase._initialize(_cctpMessenger, _cctpTransmitter); - } - - /************************* - * Public View Functions * - *************************/ - - /// @inheritdoc IL1ERC20Gateway - function getL2ERC20Address(address) public view override returns (address) { - return l2USDC; - } - - /***************************** - * Public Mutating Functions * - *****************************/ - - /// @notice Relay cross chain message and claim USDC that has been cross chained. - /// @dev The `_scrollMessage` is actually encoded calldata for `L1ScrollMessenger.relayMessageWithProof`. - /// - /// @dev This helper function is aimed to claim USDC in single transaction. - /// Normally, an user should call `L1ScrollMessenger.relayMessageWithProof` first, - /// then `L1USDCGatewayCCTP.claimUSDC`. - /// - /// @param _nonce The nonce of the message from CCTP. - /// @param _cctpMessage The message passed to MessageTransmitter contract in CCTP. - /// @param _cctpSignature The message passed to MessageTransmitter contract in CCTP. - /// @param _scrollMessage The message passed to L1ScrollMessenger contract. - function relayAndClaimUSDC( - uint256 _nonce, - bytes calldata _cctpMessage, - bytes calldata _cctpSignature, - bytes calldata _scrollMessage - ) external { - require(status[_nonce] == CCTPMessageStatus.None, "message relayed"); - // call messenger to set `status[_nonce]` to `CCTPMessageStatus.Pending`. - (bool _success, ) = messenger.call(_scrollMessage); - require(_success, "call messenger failed"); - - claimUSDC(_nonce, _cctpMessage, _cctpSignature); - } - - /// @inheritdoc IL1ERC20Gateway - /// @dev The function will not mint the USDC, users need to call `claimUSDC` after this function is done. - function finalizeWithdrawERC20( - address _l1Token, - address _l2Token, - address _from, - address _to, - uint256 _amount, - bytes memory _data - ) external payable override onlyCallByCounterpart { - require(msg.value == 0, "nonzero msg.value"); - require(_l1Token == l1USDC, "l1 token not USDC"); - require(_l2Token == l2USDC, "l2 token not USDC"); - - uint256 _nonce; - (_nonce, _data) = abi.decode(_data, (uint256, bytes)); - require(status[_nonce] == CCTPMessageStatus.None, "message relayed"); - status[_nonce] = CCTPMessageStatus.Pending; - - emit FinalizeWithdrawERC20(_l1Token, _l2Token, _from, _to, _amount, _data); - } - - /******************************* - * Public Restricted Functions * - *******************************/ - - /// @notice Update the CCTP contract addresses. - /// @param _messenger The address of TokenMessenger in local domain. - /// @param _transmitter The address of MessageTransmitter in local domain. - function updateCCTPContracts(address _messenger, address _transmitter) external onlyOwner { - cctpMessenger = _messenger; - cctpTransmitter = _transmitter; - } - - /********************** - * Internal Functions * - **********************/ - - /// @inheritdoc L1ERC20Gateway - function _beforeFinalizeWithdrawERC20( - address, - address, - address, - address, - uint256, - bytes calldata - ) internal virtual override {} - - /// @inheritdoc L1ERC20Gateway - function _beforeDropMessage( - address, - address, - uint256 - ) internal virtual override { - require(msg.value == 0, "nonzero msg.value"); - } - - /// @inheritdoc L1ERC20Gateway - function _deposit( - address _token, - address _to, - uint256 _amount, - bytes memory _data, - uint256 _gasLimit - ) internal virtual override nonReentrant { - require(_amount > 0, "deposit zero amount"); - require(_token == l1USDC, "only USDC is allowed"); - - // 1. Extract real sender if this call is from L1GatewayRouter. - address _from; - (_from, _amount, _data) = _transferERC20In(_token, _amount, _data); - - // 2. Burn token through CCTP TokenMessenger - uint256 _nonce = ITokenMessenger(cctpMessenger).depositForBurnWithCaller( - _amount, - destinationDomain, - bytes32(uint256(uint160(_to))), - address(this), - bytes32(uint256(uint160(counterpart))) - ); - - // 3. Generate message passed to L2USDCGatewayCCTP. - bytes memory _message = abi.encodeCall( - IL2ERC20Gateway.finalizeDepositERC20, - (_token, l2USDC, _from, _to, _amount, abi.encode(_nonce, _data)) - ); - - // 4. Send message to L1ScrollMessenger. - IL1ScrollMessenger(messenger).sendMessage{value: msg.value}(counterpart, 0, _message, _gasLimit); - - emit DepositERC20(_token, l2USDC, _from, _to, _amount, _data); - } -} diff --git a/contracts/src/L1/rollup/IL1MessageQueue.sol b/contracts/src/L1/rollup/IL1MessageQueue.sol deleted file mode 100644 index 210f2c8d9..000000000 --- a/contracts/src/L1/rollup/IL1MessageQueue.sol +++ /dev/null @@ -1,145 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.24; - -interface IL1MessageQueue { - /********** - * Events * - **********/ - - /// @notice Emitted when a new L1 => L2 transaction is appended to the queue. - /// @param sender The address of account who initiates the transaction. - /// @param target The address of account who will receive the transaction. - /// @param value The value passed with the transaction. - /// @param queueIndex The index of this transaction in the queue. - /// @param gasLimit Gas limit required to complete the message relay on L2. - /// @param data The calldata of the transaction. - event QueueTransaction( - address indexed sender, - address indexed target, - uint256 value, - uint64 queueIndex, - uint256 gasLimit, - bytes data - ); - - /// @notice Emitted when some L1 => L2 transactions are included in L1. - /// @param startIndex The start index of messages popped. - /// @param count The number of messages popped. - /// @param skippedBitmap A bitmap indicates whether a message is skipped. - event DequeueTransaction(uint256 startIndex, uint256 count, uint256 skippedBitmap); - - /// @notice Emitted when a message is dropped from L1. - /// @param index The index of message dropped. - event DropTransaction(uint256 index); - - /// @notice Emitted when owner updates gas oracle contract. - /// @param _oldGasOracle The address of old gas oracle contract. - /// @param _newGasOracle The address of new gas oracle contract. - event UpdateGasOracle(address indexed _oldGasOracle, address indexed _newGasOracle); - - /// @notice Emitted when owner updates max gas limit. - /// @param _oldMaxGasLimit The old max gas limit. - /// @param _newMaxGasLimit The new max gas limit. - event UpdateMaxGasLimit(uint256 _oldMaxGasLimit, uint256 _newMaxGasLimit); - - /********** - * Errors * - **********/ - - /// @dev Thrown when the given address is `address(0)`. - error ErrorZeroAddress(); - - /************************* - * Public View Functions * - *************************/ - - /// @notice The start index of all pending inclusion messages. - function pendingQueueIndex() external view returns (uint256); - - /// @notice Return the index of next appended message. - /// @dev Also the total number of appended messages. - function nextCrossDomainMessageIndex() external view returns (uint256); - - /// @notice Return the message of in `queueIndex`. - /// @param queueIndex The index to query. - function getCrossDomainMessage(uint256 queueIndex) external view returns (bytes32); - - /// @notice Return the amount of ETH should pay for cross domain message. - /// @param gasLimit Gas limit required to complete the message relay on L2. - function estimateCrossDomainMessageFee(uint256 gasLimit) external view returns (uint256); - - /// @notice Return the amount of intrinsic gas fee should pay for cross domain message. - /// @param _calldata The calldata of L1-initiated transaction. - function calculateIntrinsicGasFee(bytes calldata _calldata) external view returns (uint256); - - /// @notice Return the hash of a L1 message. - /// @param sender The address of sender. - /// @param queueIndex The queue index of this message. - /// @param value The amount of Ether transfer to target. - /// @param target The address of target. - /// @param gasLimit The gas limit provided. - /// @param data The calldata passed to target address. - function computeTransactionHash( - address sender, - uint256 queueIndex, - uint256 value, - address target, - uint256 gasLimit, - bytes calldata data - ) external view returns (bytes32); - - /// @notice Return whether the message is skipped. - /// @param queueIndex The queue index of the message to check. - function isMessageSkipped(uint256 queueIndex) external view returns (bool); - - /// @notice Return whether the message is dropped. - /// @param queueIndex The queue index of the message to check. - function isMessageDropped(uint256 queueIndex) external view returns (bool); - - /***************************** - * Public Mutating Functions * - *****************************/ - - /// @notice Append a L1 to L2 message into this contract. - /// @param target The address of target contract to call in L2. - /// @param gasLimit The maximum gas should be used for relay this message in L2. - /// @param data The calldata passed to target contract. - function appendCrossDomainMessage( - address target, - uint256 gasLimit, - bytes calldata data - ) external; - - /// @notice Append an enforced transaction to this contract. - /// @dev The address of sender should be an EOA. - /// @param sender The address of sender who will initiate this transaction in L2. - /// @param target The address of target contract to call in L2. - /// @param value The value passed - /// @param gasLimit The maximum gas should be used for this transaction in L2. - /// @param data The calldata passed to target contract. - function appendEnforcedTransaction( - address sender, - address target, - uint256 value, - uint256 gasLimit, - bytes calldata data - ) external; - - /// @notice Pop finalized messages from queue. - /// - /// @dev We can pop at most 256 messages each time. And if the message is not skipped, - /// the corresponding entry will be cleared. - /// - /// @param startIndex The start index to pop. - /// @param count The number of messages to pop. - /// @param skippedBitmap A bitmap indicates whether a message is skipped. - function popCrossDomainMessage( - uint256 startIndex, - uint256 count, - uint256 skippedBitmap - ) external; - - /// @notice Drop a skipped message from the queue. - function dropCrossDomainMessage(uint256 index) external; -} diff --git a/contracts/src/L1/rollup/IL1MessageQueueWithGasPriceOracle.sol b/contracts/src/L1/rollup/IL1MessageQueueWithGasPriceOracle.sol deleted file mode 100644 index 610104431..000000000 --- a/contracts/src/L1/rollup/IL1MessageQueueWithGasPriceOracle.sol +++ /dev/null @@ -1,38 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.24; - -import {IL1MessageQueue} from "./IL1MessageQueue.sol"; - -interface IL1MessageQueueWithGasPriceOracle is IL1MessageQueue { - /********** - * Events * - **********/ - - /// @notice Emitted when owner updates whitelist checker contract. - /// @param _oldWhitelistChecker The address of old whitelist checker contract. - /// @param _newWhitelistChecker The address of new whitelist checker contract. - event UpdateWhitelistChecker(address indexed _oldWhitelistChecker, address indexed _newWhitelistChecker); - - /// @notice Emitted when current l2 base fee is updated. - /// @param oldL2BaseFee The original l2 base fee before update. - /// @param newL2BaseFee The current l2 base fee updated. - event UpdateL2BaseFee(uint256 oldL2BaseFee, uint256 newL2BaseFee); - - /********** - * Errors * - **********/ - - /// @dev Thrown when the caller is not whitelisted. - error ErrorNotWhitelistedSender(); - - /************************* - * Public View Functions * - *************************/ - - /// @notice Return the latest known l2 base fee. - function l2BaseFee() external view returns (uint256); - - /// @notice Return the address of whitelist checker contract. - function whitelistChecker() external view returns (address); -} diff --git a/contracts/src/L1/rollup/IL2GasPriceOracle.sol b/contracts/src/L1/rollup/IL2GasPriceOracle.sol deleted file mode 100644 index 773c1c956..000000000 --- a/contracts/src/L1/rollup/IL2GasPriceOracle.sol +++ /dev/null @@ -1,19 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.24; - -interface IL2GasPriceOracle { - /// @notice Return the latest known l2 base fee. - function l2BaseFee() external view returns (uint256); - - /// @notice Return the address of whitelist contract. - function whitelist() external view returns (address); - - /// @notice Estimate fee for cross chain message call. - /// @param _gasLimit Gas limit required to complete the message relay on L2. - function estimateCrossDomainMessageFee(uint256 _gasLimit) external view returns (uint256); - - /// @notice Estimate intrinsic gas fee for cross chain message call. - /// @param _message The message to be relayed on L2. - function calculateIntrinsicGasFee(bytes memory _message) external view returns (uint256); -} diff --git a/contracts/src/L1/rollup/IScrollChain.sol b/contracts/src/L1/rollup/IScrollChain.sol deleted file mode 100644 index 7af98457f..000000000 --- a/contracts/src/L1/rollup/IScrollChain.sol +++ /dev/null @@ -1,125 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.24; - -/// @title IScrollChain -/// @notice The interface for ScrollChain. -interface IScrollChain { - /********** - * Events * - **********/ - - /// @notice Emitted when a new batch is committed. - /// @param batchIndex The index of the batch. - /// @param batchHash The hash of the batch. - event CommitBatch(uint256 indexed batchIndex, bytes32 indexed batchHash); - - /// @notice revert a pending batch. - /// @param batchIndex The index of the batch. - /// @param batchHash The hash of the batch - event RevertBatch(uint256 indexed batchIndex, bytes32 indexed batchHash); - - /// @notice Emitted when a batch is finalized. - /// @param batchIndex The index of the batch. - /// @param batchHash The hash of the batch - /// @param stateRoot The state root on layer 2 after this batch. - /// @param withdrawRoot The merkle root on layer2 after this batch. - event FinalizeBatch(uint256 indexed batchIndex, bytes32 indexed batchHash, bytes32 stateRoot, bytes32 withdrawRoot); - - /// @notice Emitted when owner updates the status of sequencer. - /// @param account The address of account updated. - /// @param status The status of the account updated. - event UpdateSequencer(address indexed account, bool status); - - /// @notice Emitted when owner updates the status of prover. - /// @param account The address of account updated. - /// @param status The status of the account updated. - event UpdateProver(address indexed account, bool status); - - /// @notice Emitted when the value of `maxNumTxInChunk` is updated. - /// @param oldMaxNumTxInChunk The old value of `maxNumTxInChunk`. - /// @param newMaxNumTxInChunk The new value of `maxNumTxInChunk`. - event UpdateMaxNumTxInChunk(uint256 oldMaxNumTxInChunk, uint256 newMaxNumTxInChunk); - - /************************* - * Public View Functions * - *************************/ - - /// @return The latest finalized batch index. - function lastFinalizedBatchIndex() external view returns (uint256); - - /// @param batchIndex The index of the batch. - /// @return The batch hash of a committed batch. - function committedBatches(uint256 batchIndex) external view returns (bytes32); - - /// @param batchIndex The index of the batch. - /// @return The state root of a committed batch. - function finalizedStateRoots(uint256 batchIndex) external view returns (bytes32); - - /// @param batchIndex The index of the batch. - /// @return The message root of a committed batch. - function withdrawRoots(uint256 batchIndex) external view returns (bytes32); - - /// @param batchIndex The index of the batch. - /// @return Whether the batch is finalized by batch index. - function isBatchFinalized(uint256 batchIndex) external view returns (bool); - - /***************************** - * Public Mutating Functions * - *****************************/ - - /// @notice Commit a batch of transactions on layer 1. - /// - /// @param version The version of current batch. - /// @param parentBatchHeader The header of parent batch, see the comments of `BatchHeaderV0Codec`. - /// @param chunks The list of encoded chunks, see the comments of `ChunkCodec`. - /// @param skippedL1MessageBitmap The bitmap indicates whether each L1 message is skipped or not. - function commitBatch( - uint8 version, - bytes calldata parentBatchHeader, - bytes[] memory chunks, - bytes calldata skippedL1MessageBitmap - ) external; - - /// @notice Revert a pending batch. - /// @dev one can only revert unfinalized batches. - /// @param batchHeader The header of current batch, see the encoding in comments of `commitBatch`. - /// @param count The number of subsequent batches to revert, including current batch. - function revertBatch(bytes calldata batchHeader, uint256 count) external; - - /// @notice Finalize a committed batch on layer 1. - /// @param batchHeader The header of current batch, see the encoding in comments of `commitBatch. - /// @param prevStateRoot The state root of parent batch. - /// @param postStateRoot The state root of current batch. - /// @param withdrawRoot The withdraw trie root of current batch. - /// @param aggrProof The aggregation proof for current batch. - function finalizeBatchWithProof( - bytes calldata batchHeader, - bytes32 prevStateRoot, - bytes32 postStateRoot, - bytes32 withdrawRoot, - bytes calldata aggrProof - ) external; - - /// @notice Finalize a committed batch (with blob) on layer 1. - /// - /// @dev Memory layout of `blobDataProof`: - /// | z | y | kzg_commitment | kzg_proof | - /// |---------|---------|----------------|-----------| - /// | bytes32 | bytes32 | bytes48 | bytes48 | - /// - /// @param batchHeader The header of current batch, see the encoding in comments of `commitBatch. - /// @param prevStateRoot The state root of parent batch. - /// @param postStateRoot The state root of current batch. - /// @param withdrawRoot The withdraw trie root of current batch. - /// @param blobDataProof The proof for blob data. - /// @param aggrProof The aggregation proof for current batch. - function finalizeBatchWithProof4844( - bytes calldata batchHeader, - bytes32 prevStateRoot, - bytes32 postStateRoot, - bytes32 withdrawRoot, - bytes calldata blobDataProof, - bytes calldata aggrProof - ) external; -} diff --git a/contracts/src/L1/rollup/L1MessageQueue.sol b/contracts/src/L1/rollup/L1MessageQueue.sol deleted file mode 100644 index 6ffee522e..000000000 --- a/contracts/src/L1/rollup/L1MessageQueue.sol +++ /dev/null @@ -1,444 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; -import {BitMapsUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/structs/BitMapsUpgradeable.sol"; - -import {IL2GasPriceOracle} from "./IL2GasPriceOracle.sol"; -import {IL1MessageQueue} from "./IL1MessageQueue.sol"; - -import {AddressAliasHelper} from "../../libraries/common/AddressAliasHelper.sol"; - -// solhint-disable no-empty-blocks -// solhint-disable no-inline-assembly -// solhint-disable reason-string - -/// @title L1MessageQueue -/// @notice This contract will hold all L1 to L2 messages. -/// Each appended message is assigned with a unique and increasing `uint256` index. -contract L1MessageQueue is OwnableUpgradeable, IL1MessageQueue { - using BitMapsUpgradeable for BitMapsUpgradeable.BitMap; - - /************* - * Constants * - *************/ - - /// @notice The address of L1ScrollMessenger contract. - address public immutable messenger; - - /// @notice The address of ScrollChain contract. - address public immutable scrollChain; - - /// @notice The address EnforcedTxGateway contract. - address public immutable enforcedTxGateway; - - /************* - * Variables * - *************/ - - /// @dev The storage slot used as L1ScrollMessenger contract, which is deprecated now. - address private __messenger; - - /// @dev The storage slot used as ScrollChain contract, which is deprecated now. - address private __scrollChain; - - /// @dev The storage slot used as EnforcedTxGateway contract, which is deprecated now. - address private __enforcedTxGateway; - - /// @notice The address of GasOracle contract. - address public gasOracle; - - /// @notice The list of queued cross domain messages. - bytes32[] public messageQueue; - - /// @inheritdoc IL1MessageQueue - uint256 public pendingQueueIndex; - - /// @notice The max gas limit of L1 transactions. - uint256 public maxGasLimit; - - /// @dev The bitmap for dropped messages, where `droppedMessageBitmap[i]` keeps the bits from `[i*256, (i+1)*256)`. - BitMapsUpgradeable.BitMap private droppedMessageBitmap; - - /// @dev The bitmap for skipped messages, where `skippedMessageBitmap[i]` keeps the bits from `[i*256, (i+1)*256)`. - mapping(uint256 => uint256) private skippedMessageBitmap; - - /// @dev The storage slots for future usage. - uint256[41] private __gap; - - /********************** - * Function Modifiers * - **********************/ - - modifier onlyMessenger() { - require(_msgSender() == messenger, "Only callable by the L1ScrollMessenger"); - _; - } - - /*************** - * Constructor * - ***************/ - - /// @notice Constructor for `L1MessageQueue` implementation contract. - /// - /// @param _messenger The address of `L1ScrollMessenger` contract. - /// @param _scrollChain The address of `ScrollChain` contract. - /// @param _enforcedTxGateway The address of `EnforcedTxGateway` contract. - constructor( - address _messenger, - address _scrollChain, - address _enforcedTxGateway - ) { - if (_messenger == address(0) || _scrollChain == address(0) || _enforcedTxGateway == address(0)) { - revert ErrorZeroAddress(); - } - - _disableInitializers(); - - messenger = _messenger; - scrollChain = _scrollChain; - enforcedTxGateway = _enforcedTxGateway; - } - - /// @notice Initialize the storage of L1MessageQueue. - /// - /// @dev The parameters `_messenger`, `_scrollChain` and `_enforcedTxGateway` are no longer used. - /// - /// @param _messenger The address of `L1ScrollMessenger` contract. - /// @param _scrollChain The address of `ScrollChain` contract. - /// @param _enforcedTxGateway The address of `EnforcedTxGateway` contract. - /// @param _gasOracle The address of `GasOracle` contract. - /// @param _maxGasLimit The maximum gas limit allowed in single transaction. - function initialize( - address _messenger, - address _scrollChain, - address _enforcedTxGateway, - address _gasOracle, - uint256 _maxGasLimit - ) external initializer { - OwnableUpgradeable.__Ownable_init(); - gasOracle = _gasOracle; - maxGasLimit = _maxGasLimit; - - __messenger = _messenger; - __scrollChain = _scrollChain; - __enforcedTxGateway = _enforcedTxGateway; - } - - /************************* - * Public View Functions * - *************************/ - - /// @inheritdoc IL1MessageQueue - function nextCrossDomainMessageIndex() external view returns (uint256) { - return messageQueue.length; - } - - /// @inheritdoc IL1MessageQueue - function getCrossDomainMessage(uint256 _queueIndex) external view returns (bytes32) { - return messageQueue[_queueIndex]; - } - - /// @inheritdoc IL1MessageQueue - function estimateCrossDomainMessageFee(uint256 _gasLimit) external view virtual override returns (uint256) { - address _oracle = gasOracle; - if (_oracle == address(0)) return 0; - return IL2GasPriceOracle(_oracle).estimateCrossDomainMessageFee(_gasLimit); - } - - /// @inheritdoc IL1MessageQueue - function calculateIntrinsicGasFee(bytes calldata _calldata) public view virtual override returns (uint256) { - address _oracle = gasOracle; - if (_oracle == address(0)) return 0; - return IL2GasPriceOracle(_oracle).calculateIntrinsicGasFee(_calldata); - } - - /// @inheritdoc IL1MessageQueue - function computeTransactionHash( - address _sender, - uint256 _queueIndex, - uint256 _value, - address _target, - uint256 _gasLimit, - bytes calldata _data - ) public pure override returns (bytes32) { - // We use EIP-2718 to encode the L1 message, and the encoding of the message is - // `TransactionType || TransactionPayload` - // where - // 1. `TransactionType` is 0x7E - // 2. `TransactionPayload` is `rlp([queueIndex, gasLimit, to, value, data, sender])` - // - // The spec of rlp: https://ethereum.org/en/developers/docs/data-structures-and-encoding/rlp/ - uint256 transactionType = 0x7E; - bytes32 hash; - assembly { - function get_uint_bytes(v) -> len { - if eq(v, 0) { - len := 1 - leave - } - for { - - } gt(v, 0) { - - } { - len := add(len, 1) - v := shr(8, v) - } - } - - // This is used for both store uint and single byte. - // Integer zero is special handled by geth to encode as `0x80` - function store_uint_or_byte(_ptr, v, is_uint) -> ptr { - ptr := _ptr - switch lt(v, 128) - case 1 { - switch and(iszero(v), is_uint) - case 1 { - // integer 0 - mstore8(ptr, 0x80) - } - default { - // single byte in the [0x00, 0x7f] - mstore8(ptr, v) - } - ptr := add(ptr, 1) - } - default { - // 1-32 bytes long - let len := get_uint_bytes(v) - mstore8(ptr, add(len, 0x80)) - ptr := add(ptr, 1) - mstore(ptr, shl(mul(8, sub(32, len)), v)) - ptr := add(ptr, len) - } - } - - function store_address(_ptr, v) -> ptr { - ptr := _ptr - // 20 bytes long - mstore8(ptr, 0x94) // 0x80 + 0x14 - ptr := add(ptr, 1) - mstore(ptr, shl(96, v)) - ptr := add(ptr, 0x14) - } - - // 1 byte for TransactionType - // 4 byte for list payload length - let start_ptr := add(mload(0x40), 5) - let ptr := start_ptr - ptr := store_uint_or_byte(ptr, _queueIndex, 1) - ptr := store_uint_or_byte(ptr, _gasLimit, 1) - ptr := store_address(ptr, _target) - ptr := store_uint_or_byte(ptr, _value, 1) - - switch eq(_data.length, 1) - case 1 { - // single byte - ptr := store_uint_or_byte(ptr, byte(0, calldataload(_data.offset)), 0) - } - default { - switch lt(_data.length, 56) - case 1 { - // a string is 0-55 bytes long - mstore8(ptr, add(0x80, _data.length)) - ptr := add(ptr, 1) - calldatacopy(ptr, _data.offset, _data.length) - ptr := add(ptr, _data.length) - } - default { - // a string is more than 55 bytes long - let len_bytes := get_uint_bytes(_data.length) - mstore8(ptr, add(0xb7, len_bytes)) - ptr := add(ptr, 1) - mstore(ptr, shl(mul(8, sub(32, len_bytes)), _data.length)) - ptr := add(ptr, len_bytes) - calldatacopy(ptr, _data.offset, _data.length) - ptr := add(ptr, _data.length) - } - } - ptr := store_address(ptr, _sender) - - let payload_len := sub(ptr, start_ptr) - let value - let value_bytes - switch lt(payload_len, 56) - case 1 { - // the total payload of a list is 0-55 bytes long - value := add(0xc0, payload_len) - value_bytes := 1 - } - default { - // If the total payload of a list is more than 55 bytes long - let len_bytes := get_uint_bytes(payload_len) - value_bytes := add(len_bytes, 1) - value := add(0xf7, len_bytes) - value := shl(mul(len_bytes, 8), value) - value := or(value, payload_len) - } - value := or(value, shl(mul(8, value_bytes), transactionType)) - value_bytes := add(value_bytes, 1) - let value_bits := mul(8, value_bytes) - value := or(shl(sub(256, value_bits), value), shr(value_bits, mload(start_ptr))) - start_ptr := sub(start_ptr, value_bytes) - mstore(start_ptr, value) - hash := keccak256(start_ptr, sub(ptr, start_ptr)) - } - return hash; - } - - /// @inheritdoc IL1MessageQueue - function isMessageSkipped(uint256 _queueIndex) external view returns (bool) { - if (_queueIndex >= pendingQueueIndex) return false; - - return _isMessageSkipped(_queueIndex); - } - - /// @inheritdoc IL1MessageQueue - function isMessageDropped(uint256 _queueIndex) external view returns (bool) { - // it should be a skipped message first. - return _isMessageSkipped(_queueIndex) && droppedMessageBitmap.get(_queueIndex); - } - - /***************************** - * Public Mutating Functions * - *****************************/ - - /// @inheritdoc IL1MessageQueue - function appendCrossDomainMessage( - address _target, - uint256 _gasLimit, - bytes calldata _data - ) external override onlyMessenger { - // validate gas limit - _validateGasLimit(_gasLimit, _data); - - // do address alias to avoid replay attack in L2. - address _sender = AddressAliasHelper.applyL1ToL2Alias(_msgSender()); - - _queueTransaction(_sender, _target, 0, _gasLimit, _data); - } - - /// @inheritdoc IL1MessageQueue - function appendEnforcedTransaction( - address _sender, - address _target, - uint256 _value, - uint256 _gasLimit, - bytes calldata _data - ) external override { - require(_msgSender() == enforcedTxGateway, "Only callable by the EnforcedTxGateway"); - // We will check it in EnforcedTxGateway, just in case. - require(_sender.code.length == 0, "only EOA"); - - // validate gas limit - _validateGasLimit(_gasLimit, _data); - - _queueTransaction(_sender, _target, _value, _gasLimit, _data); - } - - /// @inheritdoc IL1MessageQueue - function popCrossDomainMessage( - uint256 _startIndex, - uint256 _count, - uint256 _skippedBitmap - ) external { - require(_msgSender() == scrollChain, "Only callable by the ScrollChain"); - - require(_count <= 256, "pop too many messages"); - require(pendingQueueIndex == _startIndex, "start index mismatch"); - - unchecked { - // clear extra bits in `_skippedBitmap`, and if _count = 256, it's designed to overflow. - uint256 mask = (1 << _count) - 1; - _skippedBitmap &= mask; - - uint256 bucket = _startIndex >> 8; - uint256 offset = _startIndex & 0xff; - skippedMessageBitmap[bucket] |= _skippedBitmap << offset; - if (offset + _count > 256) { - skippedMessageBitmap[bucket + 1] = _skippedBitmap >> (256 - offset); - } - - pendingQueueIndex = _startIndex + _count; - } - - emit DequeueTransaction(_startIndex, _count, _skippedBitmap); - } - - /// @inheritdoc IL1MessageQueue - function dropCrossDomainMessage(uint256 _index) external onlyMessenger { - require(_index < pendingQueueIndex, "cannot drop pending message"); - - require(_isMessageSkipped(_index), "drop non-skipped message"); - require(!droppedMessageBitmap.get(_index), "message already dropped"); - droppedMessageBitmap.set(_index); - - emit DropTransaction(_index); - } - - /************************ - * Restricted Functions * - ************************/ - - /// @notice Update the address of gas oracle. - /// @dev This function can only called by contract owner. - /// @param _newGasOracle The address to update. - function updateGasOracle(address _newGasOracle) external onlyOwner { - address _oldGasOracle = gasOracle; - gasOracle = _newGasOracle; - - emit UpdateGasOracle(_oldGasOracle, _newGasOracle); - } - - /// @notice Update the max gas limit. - /// @dev This function can only called by contract owner. - /// @param _newMaxGasLimit The new max gas limit. - function updateMaxGasLimit(uint256 _newMaxGasLimit) external onlyOwner { - uint256 _oldMaxGasLimit = maxGasLimit; - maxGasLimit = _newMaxGasLimit; - - emit UpdateMaxGasLimit(_oldMaxGasLimit, _newMaxGasLimit); - } - - /********************** - * Internal Functions * - **********************/ - - /// @dev Internal function to queue a L1 transaction. - /// @param _sender The address of sender who will initiate this transaction in L2. - /// @param _target The address of target contract to call in L2. - /// @param _value The value passed - /// @param _gasLimit The maximum gas should be used for this transaction in L2. - /// @param _data The calldata passed to target contract. - function _queueTransaction( - address _sender, - address _target, - uint256 _value, - uint256 _gasLimit, - bytes calldata _data - ) internal { - // compute transaction hash - uint256 _queueIndex = messageQueue.length; - bytes32 _hash = computeTransactionHash(_sender, _queueIndex, _value, _target, _gasLimit, _data); - messageQueue.push(_hash); - - // emit event - emit QueueTransaction(_sender, _target, _value, uint64(_queueIndex), _gasLimit, _data); - } - - function _validateGasLimit(uint256 _gasLimit, bytes calldata _calldata) internal view { - require(_gasLimit <= maxGasLimit, "Gas limit must not exceed maxGasLimit"); - // check if the gas limit is above intrinsic gas - uint256 intrinsicGas = calculateIntrinsicGasFee(_calldata); - require(_gasLimit >= intrinsicGas, "Insufficient gas limit, must be above intrinsic gas"); - } - - /// @dev Returns whether the bit at `index` is set. - function _isMessageSkipped(uint256 index) internal view returns (bool) { - uint256 bucket = index >> 8; - uint256 mask = 1 << (index & 0xff); - return skippedMessageBitmap[bucket] & mask != 0; - } -} diff --git a/contracts/src/L1/rollup/L1MessageQueueWithGasPriceOracle.sol b/contracts/src/L1/rollup/L1MessageQueueWithGasPriceOracle.sol deleted file mode 100644 index 0be3acffc..000000000 --- a/contracts/src/L1/rollup/L1MessageQueueWithGasPriceOracle.sol +++ /dev/null @@ -1,110 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {IWhitelist} from "../../libraries/common/IWhitelist.sol"; -import {IL1MessageQueue} from "./IL1MessageQueue.sol"; -import {IL1MessageQueueWithGasPriceOracle} from "./IL1MessageQueueWithGasPriceOracle.sol"; -import {IL2GasPriceOracle} from "./IL2GasPriceOracle.sol"; - -import {L1MessageQueue} from "./L1MessageQueue.sol"; - -contract L1MessageQueueWithGasPriceOracle is L1MessageQueue, IL1MessageQueueWithGasPriceOracle { - /************* - * Constants * - *************/ - - /// @notice The intrinsic gas for transaction. - uint256 private constant INTRINSIC_GAS_TX = 21000; - - /// @notice The appropriate intrinsic gas for each byte. - uint256 private constant APPROPRIATE_INTRINSIC_GAS_PER_BYTE = 16; - - /************* - * Variables * - *************/ - - /// @inheritdoc IL1MessageQueueWithGasPriceOracle - uint256 public override l2BaseFee; - - /// @inheritdoc IL1MessageQueueWithGasPriceOracle - address public override whitelistChecker; - - /*************** - * Constructor * - ***************/ - - /// @notice Constructor for `L1MessageQueueWithGasPriceOracle` implementation contract. - /// - /// @param _messenger The address of `L1ScrollMessenger` contract. - /// @param _scrollChain The address of `ScrollChain` contract. - /// @param _enforcedTxGateway The address of `EnforcedTxGateway` contract. - constructor( - address _messenger, - address _scrollChain, - address _enforcedTxGateway - ) L1MessageQueue(_messenger, _scrollChain, _enforcedTxGateway) {} - - /// @notice Initialize the storage of L1MessageQueueWithGasPriceOracle. - function initializeV2() external reinitializer(2) { - l2BaseFee = IL2GasPriceOracle(gasOracle).l2BaseFee(); - whitelistChecker = IL2GasPriceOracle(gasOracle).whitelist(); - } - - /************************* - * Public View Functions * - *************************/ - - /// @inheritdoc IL1MessageQueue - function estimateCrossDomainMessageFee(uint256 _gasLimit) - external - view - override(IL1MessageQueue, L1MessageQueue) - returns (uint256) - { - return _gasLimit * l2BaseFee; - } - - /// @inheritdoc IL1MessageQueue - function calculateIntrinsicGasFee(bytes calldata _calldata) - public - pure - override(IL1MessageQueue, L1MessageQueue) - returns (uint256) - { - // no way this can overflow `uint256` - unchecked { - return INTRINSIC_GAS_TX + _calldata.length * APPROPRIATE_INTRINSIC_GAS_PER_BYTE; - } - } - - /***************************** - * Public Mutating Functions * - *****************************/ - - /// @notice Allows whitelistCheckered caller to modify the l2 base fee. - /// @param _newL2BaseFee The new l2 base fee. - function setL2BaseFee(uint256 _newL2BaseFee) external { - if (!IWhitelist(whitelistChecker).isSenderAllowed(_msgSender())) { - revert ErrorNotWhitelistedSender(); - } - - uint256 _oldL2BaseFee = l2BaseFee; - l2BaseFee = _newL2BaseFee; - - emit UpdateL2BaseFee(_oldL2BaseFee, _newL2BaseFee); - } - - /************************ - * Restricted Functions * - ************************/ - - /// @notice Update whitelist checker contract. - /// @dev This function can only called by contract owner. - /// @param _newWhitelistChecker The address of new whitelist checker contract. - function updateWhitelistChecker(address _newWhitelistChecker) external onlyOwner { - address _oldWhitelistChecker = whitelistChecker; - whitelistChecker = _newWhitelistChecker; - emit UpdateWhitelistChecker(_oldWhitelistChecker, _newWhitelistChecker); - } -} diff --git a/contracts/src/L1/rollup/L2GasPriceOracle.sol b/contracts/src/L1/rollup/L2GasPriceOracle.sol deleted file mode 100644 index 4585621a0..000000000 --- a/contracts/src/L1/rollup/L2GasPriceOracle.sol +++ /dev/null @@ -1,179 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; - -import {IWhitelist} from "../../libraries/common/IWhitelist.sol"; - -import {IL2GasPriceOracle} from "./IL2GasPriceOracle.sol"; - -// solhint-disable reason-string - -contract L2GasPriceOracle is OwnableUpgradeable, IL2GasPriceOracle { - /********** - * Events * - **********/ - - /// @notice Emitted when owner updates whitelist contract. - /// @param _oldWhitelist The address of old whitelist contract. - /// @param _newWhitelist The address of new whitelist contract. - event UpdateWhitelist(address _oldWhitelist, address _newWhitelist); - - /// @notice Emitted when current l2 base fee is updated. - /// @param oldL2BaseFee The original l2 base fee before update. - /// @param newL2BaseFee The current l2 base fee updated. - event L2BaseFeeUpdated(uint256 oldL2BaseFee, uint256 newL2BaseFee); - - /// @notice Emitted when intrinsic params are updated. - /// @param txGas The intrinsic gas for transaction. - /// @param txGasContractCreation The intrinsic gas for contract creation. - /// @param zeroGas The intrinsic gas for each zero byte. - /// @param nonZeroGas The intrinsic gas for each nonzero byte. - event IntrinsicParamsUpdated(uint256 txGas, uint256 txGasContractCreation, uint256 zeroGas, uint256 nonZeroGas); - - /************* - * Variables * - *************/ - - /// @notice The latest known l2 base fee. - uint256 public l2BaseFee; - - /// @notice The address of whitelist contract. - address public whitelist; - - struct IntrinsicParams { - // The intrinsic gas for transaction. - uint64 txGas; - // The intrinsic gas for contract creation. It is reserved for future use. - uint64 txGasContractCreation; - // The intrinsic gas for each zero byte. - uint64 zeroGas; - // The intrinsic gas for each nonzero byte. - uint64 nonZeroGas; - } - - /// @notice The intrinsic params for transaction. - IntrinsicParams public intrinsicParams; - - /*************** - * Constructor * - ***************/ - - constructor() { - _disableInitializers(); - } - - function initialize( - uint64 _txGas, - uint64 _txGasContractCreation, - uint64 _zeroGas, - uint64 _nonZeroGas - ) external initializer { - OwnableUpgradeable.__Ownable_init(); - - _setIntrinsicParams(_txGas, _txGasContractCreation, _zeroGas, _nonZeroGas); - } - - /************************* - * Public View Functions * - *************************/ - - /// @inheritdoc IL2GasPriceOracle - function calculateIntrinsicGasFee(bytes memory _message) external view override returns (uint256) { - // @note currently we don't support contract deployment via L1 messages. - uint256 _txGas = uint256(intrinsicParams.txGas); - uint256 _zeroGas = uint256(intrinsicParams.zeroGas); - uint256 _nonZeroGas = uint256(intrinsicParams.nonZeroGas); - - uint256 gas = _txGas; - if (_message.length > 0) { - uint256 nz = 0; - for (uint256 i = 0; i < _message.length; i++) { - if (_message[i] != 0) { - nz++; - } - } - gas += nz * _nonZeroGas + (_message.length - nz) * _zeroGas; - } - return uint256(gas); - } - - /// @inheritdoc IL2GasPriceOracle - function estimateCrossDomainMessageFee(uint256 _gasLimit) external view override returns (uint256) { - return _gasLimit * l2BaseFee; - } - - /***************************** - * Public Mutating Functions * - *****************************/ - - /// @notice Allows whitelisted caller to modify the l2 base fee. - /// @param _newL2BaseFee The new l2 base fee. - function setL2BaseFee(uint256 _newL2BaseFee) external { - require(IWhitelist(whitelist).isSenderAllowed(_msgSender()), "Not whitelisted sender"); - - uint256 _oldL2BaseFee = l2BaseFee; - l2BaseFee = _newL2BaseFee; - - emit L2BaseFeeUpdated(_oldL2BaseFee, _newL2BaseFee); - } - - /************************ - * Restricted Functions * - ************************/ - - /// @notice Update whitelist contract. - /// @dev This function can only called by contract owner. - /// @param _newWhitelist The address of new whitelist contract. - function updateWhitelist(address _newWhitelist) external onlyOwner { - address _oldWhitelist = whitelist; - - whitelist = _newWhitelist; - emit UpdateWhitelist(_oldWhitelist, _newWhitelist); - } - - /// @notice Allows the owner to update parameters for intrinsic gas calculation. - /// @param _txGas The intrinsic gas for transaction. - /// @param _txGasContractCreation The intrinsic gas for contract creation. - /// @param _zeroGas The intrinsic gas for each zero byte. - /// @param _nonZeroGas The intrinsic gas for each nonzero byte. - function setIntrinsicParams( - uint64 _txGas, - uint64 _txGasContractCreation, - uint64 _zeroGas, - uint64 _nonZeroGas - ) external onlyOwner { - _setIntrinsicParams(_txGas, _txGasContractCreation, _zeroGas, _nonZeroGas); - } - - /********************** - * Internal Functions * - **********************/ - - /// @dev Internal function to update parameters for intrinsic gas calculation. - /// @param _txGas The intrinsic gas for transaction. - /// @param _txGasContractCreation The intrinsic gas for contract creation. - /// @param _zeroGas The intrinsic gas for each zero byte. - /// @param _nonZeroGas The intrinsic gas for each nonzero byte. - function _setIntrinsicParams( - uint64 _txGas, - uint64 _txGasContractCreation, - uint64 _zeroGas, - uint64 _nonZeroGas - ) internal { - require(_txGas > 0, "txGas is zero"); - require(_zeroGas > 0, "zeroGas is zero"); - require(_nonZeroGas > 0, "nonZeroGas is zero"); - require(_txGasContractCreation > _txGas, "txGasContractCreation is less than txGas"); - - intrinsicParams = IntrinsicParams({ - txGas: _txGas, - txGasContractCreation: _txGasContractCreation, - zeroGas: _zeroGas, - nonZeroGas: _nonZeroGas - }); - - emit IntrinsicParamsUpdated(_txGas, _txGasContractCreation, _zeroGas, _nonZeroGas); - } -} diff --git a/contracts/src/L1/rollup/MultipleVersionRollupVerifier.sol b/contracts/src/L1/rollup/MultipleVersionRollupVerifier.sol deleted file mode 100644 index eba5e148b..000000000 --- a/contracts/src/L1/rollup/MultipleVersionRollupVerifier.sol +++ /dev/null @@ -1,165 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; - -import {IRollupVerifier} from "../../libraries/verifier/IRollupVerifier.sol"; -import {IZkEvmVerifier} from "../../libraries/verifier/IZkEvmVerifier.sol"; - -/// @title MultipleVersionRollupVerifier -/// @notice Verifies aggregate zk proofs using the appropriate verifier. -contract MultipleVersionRollupVerifier is IRollupVerifier, Ownable { - /********** - * Events * - **********/ - - /// @notice Emitted when the address of verifier is updated. - /// @param version The version of the verifier. - /// @param startBatchIndex The start batch index when the verifier will be used. - /// @param verifier The address of new verifier. - event UpdateVerifier(uint256 version, uint256 startBatchIndex, address verifier); - - /********** - * Errors * - **********/ - - /// @dev Thrown when the given address is `address(0)`. - error ErrorZeroAddress(); - - /// @dev Thrown when the given start batch index is smaller than `latestVerifier.startBatchIndex`. - error ErrorStartBatchIndexTooSmall(); - - /*********** - * Structs * - ***********/ - - struct Verifier { - // The start batch index for the verifier. - uint64 startBatchIndex; - // The address of zkevm verifier. - address verifier; - } - - /************* - * Variables * - *************/ - - /// @notice Mapping from verifier version to the list of legacy zkevm verifiers. - /// The verifiers are sorted by batchIndex in increasing order. - mapping(uint256 => Verifier[]) public legacyVerifiers; - - /// @notice Mapping from verifier version to the latest used zkevm verifier. - mapping(uint256 => Verifier) public latestVerifier; - - /*************** - * Constructor * - ***************/ - - constructor(uint256[] memory _versions, address[] memory _verifiers) { - for (uint256 i = 0; i < _versions.length; i++) { - if (_verifiers[i] == address(0)) revert ErrorZeroAddress(); - latestVerifier[_versions[i]].verifier = _verifiers[i]; - - emit UpdateVerifier(_versions[i], 0, _verifiers[i]); - } - } - - /************************* - * Public View Functions * - *************************/ - - /// @notice Return the number of legacy verifiers. - /// @param _version The version of legacy verifiers. - /// @return The number of legacy verifiers. - function legacyVerifiersLength(uint256 _version) external view returns (uint256) { - return legacyVerifiers[_version].length; - } - - /// @notice Compute the verifier should be used for specific batch. - /// @param _version The version of verifier to query. - /// @param _batchIndex The batch index to query. - /// @return The address of verifier. - function getVerifier(uint256 _version, uint256 _batchIndex) public view returns (address) { - // Normally, we will use the latest verifier. - Verifier memory _verifier = latestVerifier[_version]; - - if (_verifier.startBatchIndex > _batchIndex) { - uint256 _length = legacyVerifiers[_version].length; - // In most case, only last few verifier will be used by `ScrollChain`. - // So, we use linear search instead of binary search. - unchecked { - for (uint256 i = _length; i > 0; --i) { - _verifier = legacyVerifiers[_version][i - 1]; - if (_verifier.startBatchIndex <= _batchIndex) break; - } - } - } - - return _verifier.verifier; - } - - /***************************** - * Public Mutating Functions * - *****************************/ - - /// @inheritdoc IRollupVerifier - function verifyAggregateProof( - uint256 _batchIndex, - bytes calldata _aggrProof, - bytes32 _publicInputHash - ) external view override { - address _verifier = getVerifier(0, _batchIndex); - - IZkEvmVerifier(_verifier).verify(_aggrProof, _publicInputHash); - } - - /// @inheritdoc IRollupVerifier - function verifyAggregateProof( - uint256 _version, - uint256 _batchIndex, - bytes calldata _aggrProof, - bytes32 _publicInputHash - ) external view override { - address _verifier = getVerifier(_version, _batchIndex); - - IZkEvmVerifier(_verifier).verify(_aggrProof, _publicInputHash); - } - - /************************ - * Restricted Functions * - ************************/ - - /// @notice Update the address of zkevm verifier. - /// @param _version The version of the verifier. - /// @param _startBatchIndex The start batch index when the verifier will be used. - /// @param _verifier The address of new verifier. - function updateVerifier( - uint256 _version, - uint64 _startBatchIndex, - address _verifier - ) external onlyOwner { - // We are using version to decide the verifier to use and also this function is - // controlled by 7 days TimeLock. It is hard to predict `lastFinalizedBatchIndex` after 7 days. - // So we decide to remove this check to make verifier updating more easier. - // if (_startBatchIndex <= IScrollChain(scrollChain).lastFinalizedBatchIndex()) - // revert ErrorStartBatchIndexFinalized(); - - Verifier memory _latestVerifier = latestVerifier[_version]; - if (_startBatchIndex < _latestVerifier.startBatchIndex) revert ErrorStartBatchIndexTooSmall(); - if (_verifier == address(0)) revert ErrorZeroAddress(); - - if (_latestVerifier.startBatchIndex < _startBatchIndex) { - // don't push when it is the first update of the version. - if (_latestVerifier.verifier != address(0)) { - legacyVerifiers[_version].push(_latestVerifier); - } - _latestVerifier.startBatchIndex = _startBatchIndex; - } - _latestVerifier.verifier = _verifier; - - latestVerifier[_version] = _latestVerifier; - - emit UpdateVerifier(_version, _startBatchIndex, _verifier); - } -} diff --git a/contracts/src/L1/rollup/ScrollChain.sol b/contracts/src/L1/rollup/ScrollChain.sol deleted file mode 100644 index c2fe3252c..000000000 --- a/contracts/src/L1/rollup/ScrollChain.sol +++ /dev/null @@ -1,980 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; -import {PausableUpgradeable} from "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol"; - -import {IL1MessageQueue} from "./IL1MessageQueue.sol"; -import {IScrollChain} from "./IScrollChain.sol"; -import {BatchHeaderV0Codec} from "../../libraries/codec/BatchHeaderV0Codec.sol"; -import {BatchHeaderV1Codec} from "../../libraries/codec/BatchHeaderV1Codec.sol"; -import {ChunkCodecV0} from "../../libraries/codec/ChunkCodecV0.sol"; -import {ChunkCodecV1} from "../../libraries/codec/ChunkCodecV1.sol"; -import {IRollupVerifier} from "../../libraries/verifier/IRollupVerifier.sol"; - -// solhint-disable no-inline-assembly -// solhint-disable reason-string - -/// @title ScrollChain -/// @notice This contract maintains data for the Scroll rollup. -contract ScrollChain is OwnableUpgradeable, PausableUpgradeable, IScrollChain { - /********** - * Errors * - **********/ - - /// @dev Thrown when the given account is not EOA account. - error ErrorAccountIsNotEOA(); - - /// @dev Thrown when committing a committed batch. - error ErrorBatchIsAlreadyCommitted(); - - /// @dev Thrown when finalizing a verified batch. - error ErrorBatchIsAlreadyVerified(); - - /// @dev Thrown when committing empty batch (batch without chunks) - error ErrorBatchIsEmpty(); - - /// @dev Thrown when call precompile failed. - error ErrorCallPointEvaluationPrecompileFailed(); - - /// @dev Thrown when the caller is not prover. - error ErrorCallerIsNotProver(); - - /// @dev Thrown when the caller is not sequencer. - error ErrorCallerIsNotSequencer(); - - /// @dev Thrown when the transaction has multiple blobs. - error ErrorFoundMultipleBlob(); - - /// @dev Thrown when some fields are not zero in genesis batch. - error ErrorGenesisBatchHasNonZeroField(); - - /// @dev Thrown when importing genesis batch twice. - error ErrorGenesisBatchImported(); - - /// @dev Thrown when data hash in genesis batch is zero. - error ErrorGenesisDataHashIsZero(); - - /// @dev Thrown when the parent batch hash in genesis batch is zero. - error ErrorGenesisParentBatchHashIsNonZero(); - - /// @dev Thrown when the l2 transaction is incomplete. - error ErrorIncompleteL2TransactionData(); - - /// @dev Thrown when the batch hash is incorrect. - error ErrorIncorrectBatchHash(); - - /// @dev Thrown when the batch index is incorrect. - error ErrorIncorrectBatchIndex(); - - /// @dev Thrown when the bitmap length is incorrect. - error ErrorIncorrectBitmapLength(); - - /// @dev Thrown when the previous state root doesn't match stored one. - error ErrorIncorrectPreviousStateRoot(); - - /// @dev Thrown when the last message is skipped. - error ErrorLastL1MessageSkipped(); - - /// @dev Thrown when no blob found in the transaction. - error ErrorNoBlobFound(); - - /// @dev Thrown when the number of transactions is less than number of L1 message in one block. - error ErrorNumTxsLessThanNumL1Msgs(); - - /// @dev Thrown when the given previous state is zero. - error ErrorPreviousStateRootIsZero(); - - /// @dev Thrown when the number of batches to revert is zero. - error ErrorRevertZeroBatches(); - - /// @dev Thrown when the reverted batches are not in the ending of committed batch chain. - error ErrorRevertNotStartFromEnd(); - - /// @dev Thrown when reverting a finalized batch. - error ErrorRevertFinalizedBatch(); - - /// @dev Thrown when the given state root is zero. - error ErrorStateRootIsZero(); - - /// @dev Thrown when a chunk contains too many transactions. - error ErrorTooManyTxsInOneChunk(); - - /// @dev Thrown when the precompile output is incorrect. - error ErrorUnexpectedPointEvaluationPrecompileOutput(); - - /// @dev Thrown when the given address is `address(0)`. - error ErrorZeroAddress(); - - /************* - * Constants * - *************/ - - /// @dev Address of the point evaluation precompile used for EIP-4844 blob verification. - address private constant POINT_EVALUATION_PRECOMPILE_ADDR = address(0x0A); - - /// @dev BLS Modulus value defined in EIP-4844 and the magic value returned from a successful call to the - /// point evaluation precompile - uint256 private constant BLS_MODULUS = - 52435875175126190479447740508185965837690552500527637822603658699938581184513; - - /// @notice The chain id of the corresponding layer 2 chain. - uint64 public immutable layer2ChainId; - - /// @notice The address of L1MessageQueue contract. - address public immutable messageQueue; - - /// @notice The address of RollupVerifier. - address public immutable verifier; - - /************* - * Variables * - *************/ - - /// @notice The maximum number of transactions allowed in each chunk. - uint256 public maxNumTxInChunk; - - /// @dev The storage slot used as L1MessageQueue contract, which is deprecated now. - address private __messageQueue; - - /// @dev The storage slot used as RollupVerifier contract, which is deprecated now. - address private __verifier; - - /// @notice Whether an account is a sequencer. - mapping(address => bool) public isSequencer; - - /// @notice Whether an account is a prover. - mapping(address => bool) public isProver; - - /// @inheritdoc IScrollChain - uint256 public override lastFinalizedBatchIndex; - - /// @inheritdoc IScrollChain - mapping(uint256 => bytes32) public override committedBatches; - - /// @inheritdoc IScrollChain - mapping(uint256 => bytes32) public override finalizedStateRoots; - - /// @inheritdoc IScrollChain - mapping(uint256 => bytes32) public override withdrawRoots; - - /********************** - * Function Modifiers * - **********************/ - - modifier OnlySequencer() { - // @note In the decentralized mode, it should be only called by a list of validator. - if (!isSequencer[_msgSender()]) revert ErrorCallerIsNotSequencer(); - _; - } - - modifier OnlyProver() { - if (!isProver[_msgSender()]) revert ErrorCallerIsNotProver(); - _; - } - - /*************** - * Constructor * - ***************/ - - /// @notice Constructor for `ScrollChain` implementation contract. - /// - /// @param _chainId The chain id of L2. - /// @param _messageQueue The address of `L1MessageQueue` contract. - /// @param _verifier The address of zkevm verifier contract. - constructor( - uint64 _chainId, - address _messageQueue, - address _verifier - ) { - if (_messageQueue == address(0) || _verifier == address(0)) { - revert ErrorZeroAddress(); - } - - _disableInitializers(); - - layer2ChainId = _chainId; - messageQueue = _messageQueue; - verifier = _verifier; - } - - /// @notice Initialize the storage of ScrollChain. - /// - /// @dev The parameters `_messageQueue` are no longer used. - /// - /// @param _messageQueue The address of `L1MessageQueue` contract. - /// @param _verifier The address of zkevm verifier contract. - /// @param _maxNumTxInChunk The maximum number of transactions allowed in each chunk. - function initialize( - address _messageQueue, - address _verifier, - uint256 _maxNumTxInChunk - ) public initializer { - OwnableUpgradeable.__Ownable_init(); - - maxNumTxInChunk = _maxNumTxInChunk; - __verifier = _verifier; - __messageQueue = _messageQueue; - - emit UpdateMaxNumTxInChunk(0, _maxNumTxInChunk); - } - - /************************* - * Public View Functions * - *************************/ - - /// @inheritdoc IScrollChain - function isBatchFinalized(uint256 _batchIndex) external view override returns (bool) { - return _batchIndex <= lastFinalizedBatchIndex; - } - - /***************************** - * Public Mutating Functions * - *****************************/ - - /// @notice Import layer 2 genesis block - /// @param _batchHeader The header of the genesis batch. - /// @param _stateRoot The state root of the genesis block. - function importGenesisBatch(bytes calldata _batchHeader, bytes32 _stateRoot) external { - // check genesis batch header length - if (_stateRoot == bytes32(0)) revert ErrorStateRootIsZero(); - - // check whether the genesis batch is imported - if (finalizedStateRoots[0] != bytes32(0)) revert ErrorGenesisBatchImported(); - - (uint256 memPtr, bytes32 _batchHash, , ) = _loadBatchHeader(_batchHeader); - - // check all fields except `dataHash` and `lastBlockHash` are zero - unchecked { - uint256 sum = BatchHeaderV0Codec.getVersion(memPtr) + - BatchHeaderV0Codec.getBatchIndex(memPtr) + - BatchHeaderV0Codec.getL1MessagePopped(memPtr) + - BatchHeaderV0Codec.getTotalL1MessagePopped(memPtr); - if (sum != 0) revert ErrorGenesisBatchHasNonZeroField(); - } - if (BatchHeaderV0Codec.getDataHash(memPtr) == bytes32(0)) revert ErrorGenesisDataHashIsZero(); - if (BatchHeaderV0Codec.getParentBatchHash(memPtr) != bytes32(0)) revert ErrorGenesisParentBatchHashIsNonZero(); - - committedBatches[0] = _batchHash; - finalizedStateRoots[0] = _stateRoot; - - emit CommitBatch(0, _batchHash); - emit FinalizeBatch(0, _batchHash, _stateRoot, bytes32(0)); - } - - /// @inheritdoc IScrollChain - function commitBatch( - uint8 _version, - bytes calldata _parentBatchHeader, - bytes[] memory _chunks, - bytes calldata _skippedL1MessageBitmap - ) external override OnlySequencer whenNotPaused { - // check whether the batch is empty - if (_chunks.length == 0) revert ErrorBatchIsEmpty(); - - (, bytes32 _parentBatchHash, uint256 _batchIndex, uint256 _totalL1MessagesPoppedOverall) = _loadBatchHeader( - _parentBatchHeader - ); - unchecked { - _batchIndex += 1; - } - if (committedBatches[_batchIndex] != 0) revert ErrorBatchIsAlreadyCommitted(); - - bytes32 _batchHash; - uint256 batchPtr; - bytes32 _dataHash; - uint256 _totalL1MessagesPoppedInBatch; - if (_version == 0) { - (_dataHash, _totalL1MessagesPoppedInBatch) = _commitChunksV0( - _totalL1MessagesPoppedOverall, - _chunks, - _skippedL1MessageBitmap - ); - assembly { - batchPtr := mload(0x40) - _totalL1MessagesPoppedOverall := add(_totalL1MessagesPoppedOverall, _totalL1MessagesPoppedInBatch) - } - // store entries, the order matters - BatchHeaderV0Codec.storeVersion(batchPtr, 0); - BatchHeaderV0Codec.storeBatchIndex(batchPtr, _batchIndex); - BatchHeaderV0Codec.storeL1MessagePopped(batchPtr, _totalL1MessagesPoppedInBatch); - BatchHeaderV0Codec.storeTotalL1MessagePopped(batchPtr, _totalL1MessagesPoppedOverall); - BatchHeaderV0Codec.storeDataHash(batchPtr, _dataHash); - BatchHeaderV0Codec.storeParentBatchHash(batchPtr, _parentBatchHash); - BatchHeaderV0Codec.storeSkippedBitmap(batchPtr, _skippedL1MessageBitmap); - // compute batch hash - _batchHash = BatchHeaderV0Codec.computeBatchHash( - batchPtr, - BatchHeaderV0Codec.BATCH_HEADER_FIXED_LENGTH + _skippedL1MessageBitmap.length - ); - } else if (_version >= 1) { - // versions 1 and 2 both use ChunkCodecV1 and BatchHeaderV1Codec, - // but they use different blob encoding and different verifiers. - - bytes32 blobVersionedHash; - (blobVersionedHash, _dataHash, _totalL1MessagesPoppedInBatch) = _commitChunksV1( - _totalL1MessagesPoppedOverall, - _chunks, - _skippedL1MessageBitmap - ); - assembly { - batchPtr := mload(0x40) - _totalL1MessagesPoppedOverall := add(_totalL1MessagesPoppedOverall, _totalL1MessagesPoppedInBatch) - } - // store entries, the order matters - BatchHeaderV1Codec.storeVersion(batchPtr, _version); - BatchHeaderV1Codec.storeBatchIndex(batchPtr, _batchIndex); - BatchHeaderV1Codec.storeL1MessagePopped(batchPtr, _totalL1MessagesPoppedInBatch); - BatchHeaderV1Codec.storeTotalL1MessagePopped(batchPtr, _totalL1MessagesPoppedOverall); - BatchHeaderV1Codec.storeDataHash(batchPtr, _dataHash); - BatchHeaderV1Codec.storeBlobVersionedHash(batchPtr, blobVersionedHash); - BatchHeaderV1Codec.storeParentBatchHash(batchPtr, _parentBatchHash); - BatchHeaderV1Codec.storeSkippedBitmap(batchPtr, _skippedL1MessageBitmap); - // compute batch hash - _batchHash = BatchHeaderV1Codec.computeBatchHash( - batchPtr, - BatchHeaderV1Codec.BATCH_HEADER_FIXED_LENGTH + _skippedL1MessageBitmap.length - ); - } - - // check the length of bitmap - unchecked { - if (((_totalL1MessagesPoppedInBatch + 255) / 256) * 32 != _skippedL1MessageBitmap.length) { - revert ErrorIncorrectBitmapLength(); - } - } - - committedBatches[_batchIndex] = _batchHash; - emit CommitBatch(_batchIndex, _batchHash); - } - - /// @inheritdoc IScrollChain - /// @dev If the owner want to revert a sequence of batches by sending multiple transactions, - /// make sure to revert recent batches first. - function revertBatch(bytes calldata _batchHeader, uint256 _count) external onlyOwner { - if (_count == 0) revert ErrorRevertZeroBatches(); - - (, bytes32 _batchHash, uint256 _batchIndex, ) = _loadBatchHeader(_batchHeader); - // make sure no gap is left when reverting from the ending to the beginning. - if (committedBatches[_batchIndex + _count] != bytes32(0)) revert ErrorRevertNotStartFromEnd(); - - // check finalization - if (_batchIndex <= lastFinalizedBatchIndex) revert ErrorRevertFinalizedBatch(); - - while (_count > 0) { - committedBatches[_batchIndex] = bytes32(0); - - emit RevertBatch(_batchIndex, _batchHash); - - unchecked { - _batchIndex += 1; - _count -= 1; - } - - _batchHash = committedBatches[_batchIndex]; - if (_batchHash == bytes32(0)) break; - } - } - - /// @inheritdoc IScrollChain - /// @dev We keep this function to upgrade to 4844 more smoothly. - function finalizeBatchWithProof( - bytes calldata _batchHeader, - bytes32 _prevStateRoot, - bytes32 _postStateRoot, - bytes32 _withdrawRoot, - bytes calldata _aggrProof - ) external override OnlyProver whenNotPaused { - if (_prevStateRoot == bytes32(0)) revert ErrorPreviousStateRootIsZero(); - if (_postStateRoot == bytes32(0)) revert ErrorStateRootIsZero(); - - // compute batch hash and verify - (uint256 memPtr, bytes32 _batchHash, uint256 _batchIndex, ) = _loadBatchHeader(_batchHeader); - bytes32 _dataHash = BatchHeaderV0Codec.getDataHash(memPtr); - - // verify previous state root. - if (finalizedStateRoots[_batchIndex - 1] != _prevStateRoot) revert ErrorIncorrectPreviousStateRoot(); - - // avoid duplicated verification - if (finalizedStateRoots[_batchIndex] != bytes32(0)) revert ErrorBatchIsAlreadyVerified(); - - // compute public input hash - bytes32 _publicInputHash = keccak256( - abi.encodePacked(layer2ChainId, _prevStateRoot, _postStateRoot, _withdrawRoot, _dataHash) - ); - - // verify batch - IRollupVerifier(verifier).verifyAggregateProof(0, _batchIndex, _aggrProof, _publicInputHash); - - // check and update lastFinalizedBatchIndex - unchecked { - if (lastFinalizedBatchIndex + 1 != _batchIndex) revert ErrorIncorrectBatchIndex(); - lastFinalizedBatchIndex = _batchIndex; - } - - // record state root and withdraw root - finalizedStateRoots[_batchIndex] = _postStateRoot; - withdrawRoots[_batchIndex] = _withdrawRoot; - - // Pop finalized and non-skipped message from L1MessageQueue. - _popL1Messages( - BatchHeaderV0Codec.getSkippedBitmapPtr(memPtr), - BatchHeaderV0Codec.getTotalL1MessagePopped(memPtr), - BatchHeaderV0Codec.getL1MessagePopped(memPtr) - ); - - emit FinalizeBatch(_batchIndex, _batchHash, _postStateRoot, _withdrawRoot); - } - - /// @inheritdoc IScrollChain - /// @dev Memory layout of `_blobDataProof`: - /// ```text - /// | z | y | kzg_commitment | kzg_proof | - /// |---------|---------|----------------|-----------| - /// | bytes32 | bytes32 | bytes48 | bytes48 | - /// ``` - function finalizeBatchWithProof4844( - bytes calldata _batchHeader, - bytes32 _prevStateRoot, - bytes32 _postStateRoot, - bytes32 _withdrawRoot, - bytes calldata _blobDataProof, - bytes calldata _aggrProof - ) external override OnlyProver whenNotPaused { - if (_prevStateRoot == bytes32(0)) revert ErrorPreviousStateRootIsZero(); - if (_postStateRoot == bytes32(0)) revert ErrorStateRootIsZero(); - - // compute batch hash and verify - (uint256 memPtr, bytes32 _batchHash, uint256 _batchIndex, ) = _loadBatchHeader(_batchHeader); - bytes32 _dataHash = BatchHeaderV1Codec.getDataHash(memPtr); - bytes32 _blobVersionedHash = BatchHeaderV1Codec.getBlobVersionedHash(memPtr); - - // Calls the point evaluation precompile and verifies the output - { - (bool success, bytes memory data) = POINT_EVALUATION_PRECOMPILE_ADDR.staticcall( - abi.encodePacked(_blobVersionedHash, _blobDataProof) - ); - // We verify that the point evaluation precompile call was successful by testing the latter 32 bytes of the - // response is equal to BLS_MODULUS as defined in https://eips.ethereum.org/EIPS/eip-4844#point-evaluation-precompile - if (!success) revert ErrorCallPointEvaluationPrecompileFailed(); - (, uint256 result) = abi.decode(data, (uint256, uint256)); - if (result != BLS_MODULUS) revert ErrorUnexpectedPointEvaluationPrecompileOutput(); - } - - // verify previous state root. - if (finalizedStateRoots[_batchIndex - 1] != _prevStateRoot) revert ErrorIncorrectPreviousStateRoot(); - - // avoid duplicated verification - if (finalizedStateRoots[_batchIndex] != bytes32(0)) revert ErrorBatchIsAlreadyVerified(); - - // compute public input hash - bytes32 _publicInputHash = keccak256( - abi.encodePacked( - layer2ChainId, - _prevStateRoot, - _postStateRoot, - _withdrawRoot, - _dataHash, - _blobDataProof[0:64], - _blobVersionedHash - ) - ); - - // load version from batch header, it is always the first byte. - uint256 batchVersion; - assembly { - batchVersion := shr(248, calldataload(_batchHeader.offset)) - } - // verify batch - IRollupVerifier(verifier).verifyAggregateProof(batchVersion, _batchIndex, _aggrProof, _publicInputHash); - - // check and update lastFinalizedBatchIndex - unchecked { - if (lastFinalizedBatchIndex + 1 != _batchIndex) revert ErrorIncorrectBatchIndex(); - lastFinalizedBatchIndex = _batchIndex; - } - - // record state root and withdraw root - finalizedStateRoots[_batchIndex] = _postStateRoot; - withdrawRoots[_batchIndex] = _withdrawRoot; - - // Pop finalized and non-skipped message from L1MessageQueue. - _popL1Messages( - BatchHeaderV1Codec.getSkippedBitmapPtr(memPtr), - BatchHeaderV1Codec.getTotalL1MessagePopped(memPtr), - BatchHeaderV1Codec.getL1MessagePopped(memPtr) - ); - - emit FinalizeBatch(_batchIndex, _batchHash, _postStateRoot, _withdrawRoot); - } - - /************************ - * Restricted Functions * - ************************/ - - /// @notice Add an account to the sequencer list. - /// @param _account The address of account to add. - function addSequencer(address _account) external onlyOwner { - // @note Currently many external services rely on EOA sequencer to decode metadata directly from tx.calldata. - // So we explicitly make sure the account is EOA. - if (_account.code.length > 0) revert ErrorAccountIsNotEOA(); - - isSequencer[_account] = true; - - emit UpdateSequencer(_account, true); - } - - /// @notice Remove an account from the sequencer list. - /// @param _account The address of account to remove. - function removeSequencer(address _account) external onlyOwner { - isSequencer[_account] = false; - - emit UpdateSequencer(_account, false); - } - - /// @notice Add an account to the prover list. - /// @param _account The address of account to add. - function addProver(address _account) external onlyOwner { - // @note Currently many external services rely on EOA prover to decode metadata directly from tx.calldata. - // So we explicitly make sure the account is EOA. - if (_account.code.length > 0) revert ErrorAccountIsNotEOA(); - isProver[_account] = true; - - emit UpdateProver(_account, true); - } - - /// @notice Add an account from the prover list. - /// @param _account The address of account to remove. - function removeProver(address _account) external onlyOwner { - isProver[_account] = false; - - emit UpdateProver(_account, false); - } - - /// @notice Update the value of `maxNumTxInChunk`. - /// @param _maxNumTxInChunk The new value of `maxNumTxInChunk`. - function updateMaxNumTxInChunk(uint256 _maxNumTxInChunk) external onlyOwner { - uint256 _oldMaxNumTxInChunk = maxNumTxInChunk; - maxNumTxInChunk = _maxNumTxInChunk; - - emit UpdateMaxNumTxInChunk(_oldMaxNumTxInChunk, _maxNumTxInChunk); - } - - /// @notice Pause the contract - /// @param _status The pause status to update. - function setPause(bool _status) external onlyOwner { - if (_status) { - _pause(); - } else { - _unpause(); - } - } - - /********************** - * Internal Functions * - **********************/ - - /// @dev Internal function to commit chunks with version 0 - /// @param _totalL1MessagesPoppedOverall The number of L1 messages popped before the list of chunks. - /// @param _chunks The list of chunks to commit. - /// @param _skippedL1MessageBitmap The bitmap indicates whether each L1 message is skipped or not. - /// @return _batchDataHash The computed data hash for the list of chunks. - /// @return _totalL1MessagesPoppedInBatch The total number of L1 messages popped in this batch, including skipped one. - function _commitChunksV0( - uint256 _totalL1MessagesPoppedOverall, - bytes[] memory _chunks, - bytes calldata _skippedL1MessageBitmap - ) internal view returns (bytes32 _batchDataHash, uint256 _totalL1MessagesPoppedInBatch) { - uint256 _chunksLength = _chunks.length; - - // load `batchDataHashPtr` and reserve the memory region for chunk data hashes - uint256 batchDataHashPtr; - assembly { - batchDataHashPtr := mload(0x40) - mstore(0x40, add(batchDataHashPtr, mul(_chunksLength, 32))) - } - - // compute the data hash for each chunk - for (uint256 i = 0; i < _chunksLength; i++) { - uint256 _totalNumL1MessagesInChunk; - bytes32 _chunkDataHash; - (_chunkDataHash, _totalNumL1MessagesInChunk) = _commitChunkV0( - _chunks[i], - _totalL1MessagesPoppedInBatch, - _totalL1MessagesPoppedOverall, - _skippedL1MessageBitmap - ); - unchecked { - _totalL1MessagesPoppedInBatch += _totalNumL1MessagesInChunk; - _totalL1MessagesPoppedOverall += _totalNumL1MessagesInChunk; - } - assembly { - mstore(batchDataHashPtr, _chunkDataHash) - batchDataHashPtr := add(batchDataHashPtr, 0x20) - } - } - - assembly { - let dataLen := mul(_chunksLength, 0x20) - _batchDataHash := keccak256(sub(batchDataHashPtr, dataLen), dataLen) - } - } - - /// @dev Internal function to commit chunks with version 1 - /// @param _totalL1MessagesPoppedOverall The number of L1 messages popped before the list of chunks. - /// @param _chunks The list of chunks to commit. - /// @param _skippedL1MessageBitmap The bitmap indicates whether each L1 message is skipped or not. - /// @return _blobVersionedHash The blob versioned hash for the blob carried in this transaction. - /// @return _batchDataHash The computed data hash for the list of chunks. - /// @return _totalL1MessagesPoppedInBatch The total number of L1 messages popped in this batch, including skipped one. - function _commitChunksV1( - uint256 _totalL1MessagesPoppedOverall, - bytes[] memory _chunks, - bytes calldata _skippedL1MessageBitmap - ) - internal - view - returns ( - bytes32 _blobVersionedHash, - bytes32 _batchDataHash, - uint256 _totalL1MessagesPoppedInBatch - ) - { - { - bytes32 _secondBlob; - // Get blob's versioned hash - assembly { - _blobVersionedHash := blobhash(0) - _secondBlob := blobhash(1) - } - if (_blobVersionedHash == bytes32(0)) revert ErrorNoBlobFound(); - if (_secondBlob != bytes32(0)) revert ErrorFoundMultipleBlob(); - } - - uint256 _chunksLength = _chunks.length; - - // load `batchDataHashPtr` and reserve the memory region for chunk data hashes - uint256 batchDataHashPtr; - assembly { - batchDataHashPtr := mload(0x40) - mstore(0x40, add(batchDataHashPtr, mul(_chunksLength, 32))) - } - - // compute the data hash for each chunk - for (uint256 i = 0; i < _chunksLength; i++) { - uint256 _totalNumL1MessagesInChunk; - bytes32 _chunkDataHash; - (_chunkDataHash, _totalNumL1MessagesInChunk) = _commitChunkV1( - _chunks[i], - _totalL1MessagesPoppedInBatch, - _totalL1MessagesPoppedOverall, - _skippedL1MessageBitmap - ); - unchecked { - _totalL1MessagesPoppedInBatch += _totalNumL1MessagesInChunk; - _totalL1MessagesPoppedOverall += _totalNumL1MessagesInChunk; - } - assembly { - mstore(batchDataHashPtr, _chunkDataHash) - batchDataHashPtr := add(batchDataHashPtr, 0x20) - } - } - - // compute the data hash for current batch - assembly { - let dataLen := mul(_chunksLength, 0x20) - _batchDataHash := keccak256(sub(batchDataHashPtr, dataLen), dataLen) - } - } - - /// @dev Internal function to load batch header from calldata to memory. - /// @param _batchHeader The batch header in calldata. - /// @return batchPtr The start memory offset of loaded batch header. - /// @return _batchHash The hash of the loaded batch header. - /// @return _batchIndex The index of this batch. - /// @param _totalL1MessagesPoppedOverall The number of L1 messages popped after this batch. - function _loadBatchHeader(bytes calldata _batchHeader) - internal - view - returns ( - uint256 batchPtr, - bytes32 _batchHash, - uint256 _batchIndex, - uint256 _totalL1MessagesPoppedOverall - ) - { - // load version from batch header, it is always the first byte. - uint256 version; - assembly { - version := shr(248, calldataload(_batchHeader.offset)) - } - - uint256 _length; - if (version == 0) { - (batchPtr, _length) = BatchHeaderV0Codec.loadAndValidate(_batchHeader); - _batchHash = BatchHeaderV0Codec.computeBatchHash(batchPtr, _length); - _batchIndex = BatchHeaderV0Codec.getBatchIndex(batchPtr); - } else if (version >= 1) { - (batchPtr, _length) = BatchHeaderV1Codec.loadAndValidate(_batchHeader); - _batchHash = BatchHeaderV1Codec.computeBatchHash(batchPtr, _length); - _batchIndex = BatchHeaderV1Codec.getBatchIndex(batchPtr); - } - // only check when genesis is imported - if (committedBatches[_batchIndex] != _batchHash && finalizedStateRoots[0] != bytes32(0)) { - revert ErrorIncorrectBatchHash(); - } - _totalL1MessagesPoppedOverall = BatchHeaderV0Codec.getTotalL1MessagePopped(batchPtr); - } - - /// @dev Internal function to commit a chunk with version 0. - /// @param _chunk The encoded chunk to commit. - /// @param _totalL1MessagesPoppedInBatch The total number of L1 messages popped in the current batch before this chunk. - /// @param _totalL1MessagesPoppedOverall The total number of L1 messages popped in all batches including the current batch, before this chunk. - /// @param _skippedL1MessageBitmap The bitmap indicates whether each L1 message is skipped or not. - /// @return _dataHash The computed data hash for this chunk. - /// @return _totalNumL1MessagesInChunk The total number of L1 message popped in current chunk - function _commitChunkV0( - bytes memory _chunk, - uint256 _totalL1MessagesPoppedInBatch, - uint256 _totalL1MessagesPoppedOverall, - bytes calldata _skippedL1MessageBitmap - ) internal view returns (bytes32 _dataHash, uint256 _totalNumL1MessagesInChunk) { - uint256 chunkPtr; - uint256 startDataPtr; - uint256 dataPtr; - - assembly { - dataPtr := mload(0x40) - startDataPtr := dataPtr - chunkPtr := add(_chunk, 0x20) // skip chunkLength - } - - uint256 _numBlocks = ChunkCodecV0.validateChunkLength(chunkPtr, _chunk.length); - - // concatenate block contexts, use scope to avoid stack too deep - { - uint256 _totalTransactionsInChunk; - for (uint256 i = 0; i < _numBlocks; i++) { - dataPtr = ChunkCodecV0.copyBlockContext(chunkPtr, dataPtr, i); - uint256 blockPtr = chunkPtr + 1 + i * ChunkCodecV0.BLOCK_CONTEXT_LENGTH; - uint256 _numTransactionsInBlock = ChunkCodecV0.getNumTransactions(blockPtr); - unchecked { - _totalTransactionsInChunk += _numTransactionsInBlock; - } - } - assembly { - mstore(0x40, add(dataPtr, mul(_totalTransactionsInChunk, 0x20))) // reserve memory for tx hashes - } - } - - // It is used to compute the actual number of transactions in chunk. - uint256 txHashStartDataPtr = dataPtr; - // concatenate tx hashes - uint256 l2TxPtr = ChunkCodecV0.getL2TxPtr(chunkPtr, _numBlocks); - chunkPtr += 1; - while (_numBlocks > 0) { - // concatenate l1 message hashes - uint256 _numL1MessagesInBlock = ChunkCodecV0.getNumL1Messages(chunkPtr); - dataPtr = _loadL1MessageHashes( - dataPtr, - _numL1MessagesInBlock, - _totalL1MessagesPoppedInBatch, - _totalL1MessagesPoppedOverall, - _skippedL1MessageBitmap - ); - - // concatenate l2 transaction hashes - uint256 _numTransactionsInBlock = ChunkCodecV0.getNumTransactions(chunkPtr); - if (_numTransactionsInBlock < _numL1MessagesInBlock) revert ErrorNumTxsLessThanNumL1Msgs(); - for (uint256 j = _numL1MessagesInBlock; j < _numTransactionsInBlock; j++) { - bytes32 txHash; - (txHash, l2TxPtr) = ChunkCodecV0.loadL2TxHash(l2TxPtr); - assembly { - mstore(dataPtr, txHash) - dataPtr := add(dataPtr, 0x20) - } - } - - unchecked { - _totalNumL1MessagesInChunk += _numL1MessagesInBlock; - _totalL1MessagesPoppedInBatch += _numL1MessagesInBlock; - _totalL1MessagesPoppedOverall += _numL1MessagesInBlock; - - _numBlocks -= 1; - chunkPtr += ChunkCodecV0.BLOCK_CONTEXT_LENGTH; - } - } - - // check the actual number of transactions in the chunk - if ((dataPtr - txHashStartDataPtr) / 32 > maxNumTxInChunk) revert ErrorTooManyTxsInOneChunk(); - - assembly { - chunkPtr := add(_chunk, 0x20) - } - // check chunk has correct length - if (l2TxPtr - chunkPtr != _chunk.length) revert ErrorIncompleteL2TransactionData(); - - // compute data hash and store to memory - assembly { - _dataHash := keccak256(startDataPtr, sub(dataPtr, startDataPtr)) - } - } - - /// @dev Internal function to commit a chunk with version 1. - /// @param _chunk The encoded chunk to commit. - /// @param _totalL1MessagesPoppedInBatch The total number of L1 messages popped in current batch. - /// @param _totalL1MessagesPoppedOverall The total number of L1 messages popped in all batches including current batch. - /// @param _skippedL1MessageBitmap The bitmap indicates whether each L1 message is skipped or not. - /// @return _dataHash The computed data hash for this chunk. - /// @return _totalNumL1MessagesInChunk The total number of L1 message popped in current chunk - function _commitChunkV1( - bytes memory _chunk, - uint256 _totalL1MessagesPoppedInBatch, - uint256 _totalL1MessagesPoppedOverall, - bytes calldata _skippedL1MessageBitmap - ) internal view returns (bytes32 _dataHash, uint256 _totalNumL1MessagesInChunk) { - uint256 chunkPtr; - uint256 startDataPtr; - uint256 dataPtr; - - assembly { - dataPtr := mload(0x40) - startDataPtr := dataPtr - chunkPtr := add(_chunk, 0x20) // skip chunkLength - } - - uint256 _numBlocks = ChunkCodecV1.validateChunkLength(chunkPtr, _chunk.length); - // concatenate block contexts, use scope to avoid stack too deep - for (uint256 i = 0; i < _numBlocks; i++) { - dataPtr = ChunkCodecV1.copyBlockContext(chunkPtr, dataPtr, i); - uint256 blockPtr = chunkPtr + 1 + i * ChunkCodecV1.BLOCK_CONTEXT_LENGTH; - uint256 _numL1MessagesInBlock = ChunkCodecV1.getNumL1Messages(blockPtr); - unchecked { - _totalNumL1MessagesInChunk += _numL1MessagesInBlock; - } - } - assembly { - mstore(0x40, add(dataPtr, mul(_totalNumL1MessagesInChunk, 0x20))) // reserve memory for l1 message hashes - chunkPtr := add(chunkPtr, 1) - } - - // the number of actual transactions in one chunk: non-skipped l1 messages + l2 txs - uint256 _totalTransactionsInChunk; - // concatenate tx hashes - while (_numBlocks > 0) { - // concatenate l1 message hashes - uint256 _numL1MessagesInBlock = ChunkCodecV1.getNumL1Messages(chunkPtr); - uint256 startPtr = dataPtr; - dataPtr = _loadL1MessageHashes( - dataPtr, - _numL1MessagesInBlock, - _totalL1MessagesPoppedInBatch, - _totalL1MessagesPoppedOverall, - _skippedL1MessageBitmap - ); - uint256 _numTransactionsInBlock = ChunkCodecV1.getNumTransactions(chunkPtr); - if (_numTransactionsInBlock < _numL1MessagesInBlock) revert ErrorNumTxsLessThanNumL1Msgs(); - unchecked { - _totalTransactionsInChunk += (dataPtr - startPtr) / 32; // number of non-skipped l1 messages - _totalTransactionsInChunk += _numTransactionsInBlock - _numL1MessagesInBlock; // number of l2 txs - _totalL1MessagesPoppedInBatch += _numL1MessagesInBlock; - _totalL1MessagesPoppedOverall += _numL1MessagesInBlock; - - _numBlocks -= 1; - chunkPtr += ChunkCodecV1.BLOCK_CONTEXT_LENGTH; - } - } - - // check the actual number of transactions in the chunk - if (_totalTransactionsInChunk > maxNumTxInChunk) { - revert ErrorTooManyTxsInOneChunk(); - } - - // compute data hash and store to memory - assembly { - _dataHash := keccak256(startDataPtr, sub(dataPtr, startDataPtr)) - } - } - - /// @dev Internal function to load L1 message hashes from the message queue. - /// @param _ptr The memory offset to store the transaction hash. - /// @param _numL1Messages The number of L1 messages to load. - /// @param _totalL1MessagesPoppedInBatch The total number of L1 messages popped in current batch. - /// @param _totalL1MessagesPoppedOverall The total number of L1 messages popped in all batches including current batch. - /// @param _skippedL1MessageBitmap The bitmap indicates whether each L1 message is skipped or not. - /// @return uint256 The new memory offset after loading. - function _loadL1MessageHashes( - uint256 _ptr, - uint256 _numL1Messages, - uint256 _totalL1MessagesPoppedInBatch, - uint256 _totalL1MessagesPoppedOverall, - bytes calldata _skippedL1MessageBitmap - ) internal view returns (uint256) { - if (_numL1Messages == 0) return _ptr; - IL1MessageQueue _messageQueue = IL1MessageQueue(messageQueue); - - unchecked { - uint256 _bitmap; - uint256 rem; - for (uint256 i = 0; i < _numL1Messages; i++) { - uint256 quo = _totalL1MessagesPoppedInBatch >> 8; - rem = _totalL1MessagesPoppedInBatch & 0xff; - - // load bitmap every 256 bits - if (i == 0 || rem == 0) { - assembly { - _bitmap := calldataload(add(_skippedL1MessageBitmap.offset, mul(0x20, quo))) - } - } - if (((_bitmap >> rem) & 1) == 0) { - // message not skipped - bytes32 _hash = _messageQueue.getCrossDomainMessage(_totalL1MessagesPoppedOverall); - assembly { - mstore(_ptr, _hash) - _ptr := add(_ptr, 0x20) - } - } - - _totalL1MessagesPoppedInBatch += 1; - _totalL1MessagesPoppedOverall += 1; - } - - // check last L1 message is not skipped, _totalL1MessagesPoppedInBatch must > 0 - rem = (_totalL1MessagesPoppedInBatch - 1) & 0xff; - if (((_bitmap >> rem) & 1) > 0) revert ErrorLastL1MessageSkipped(); - } - - return _ptr; - } - - /// @dev Internal function to pop finalized l1 messages. - /// @param bitmapPtr The memory offset of `skippedL1MessageBitmap`. - /// @param totalL1MessagePopped The total number of L1 messages popped in all batches including current batch. - /// @param l1MessagePopped The number of L1 messages popped in current batch. - function _popL1Messages( - uint256 bitmapPtr, - uint256 totalL1MessagePopped, - uint256 l1MessagePopped - ) internal { - if (l1MessagePopped == 0) return; - - unchecked { - uint256 startIndex = totalL1MessagePopped - l1MessagePopped; - uint256 bitmap; - - for (uint256 i = 0; i < l1MessagePopped; i += 256) { - uint256 _count = 256; - if (l1MessagePopped - i < _count) { - _count = l1MessagePopped - i; - } - assembly { - bitmap := mload(bitmapPtr) - bitmapPtr := add(bitmapPtr, 0x20) - } - IL1MessageQueue(messageQueue).popCrossDomainMessage(startIndex, _count, bitmap); - startIndex += 256; - } - } - } -} diff --git a/contracts/src/L1/rollup/ScrollChainCommitmentVerifier.sol b/contracts/src/L1/rollup/ScrollChainCommitmentVerifier.sol deleted file mode 100644 index 3d5674f5c..000000000 --- a/contracts/src/L1/rollup/ScrollChainCommitmentVerifier.sol +++ /dev/null @@ -1,59 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {IScrollChain} from "./IScrollChain.sol"; -import {ZkTrieVerifier} from "../../libraries/verifier/ZkTrieVerifier.sol"; - -contract ScrollChainCommitmentVerifier { - /// @notice The address of poseidon hash contract - address public immutable poseidon; - - /// @notice The address of ScrollChain contract. - address public immutable rollup; - - constructor(address _poseidon, address _rollup) { - poseidon = _poseidon; - rollup = _rollup; - } - - /// @notice Validates a proof from eth_getProof in l2geth. - /// @param account The address of the contract. - /// @param storageKey The storage slot to verify. - /// @param proof The rlp encoding result of eth_getProof. - /// @return stateRoot The computed state root. Must be checked by the caller. - /// @return storageValue The value of `storageKey`. - /// - /// The encoding order of `proof` is - /// ```text - /// | 1 byte | ... | 1 byte | ... | - /// | account proof length | account proof | storage proof length | storage proof | - /// ``` - function verifyZkTrieProof( - address account, - bytes32 storageKey, - bytes calldata proof - ) public view returns (bytes32 stateRoot, bytes32 storageValue) { - return ZkTrieVerifier.verifyZkTrieProof(poseidon, account, storageKey, proof); - } - - /// @notice Verifies a batch inclusion proof. - /// @param batchIndex The index of the batch. - /// @param account The address of the contract in L2. - /// @param storageKey The storage key inside the contract in L2. - /// @param proof The rlp encoding result of eth_getProof. - /// @return storageValue The value of `storageKey`. - function verifyStateCommitment( - uint256 batchIndex, - address account, - bytes32 storageKey, - bytes calldata proof - ) external view returns (bytes32 storageValue) { - require(IScrollChain(rollup).isBatchFinalized(batchIndex), "Batch not finalized"); - - bytes32 computedStateRoot; - (computedStateRoot, storageValue) = verifyZkTrieProof(account, storageKey, proof); - bytes32 expectedStateRoot = IScrollChain(rollup).finalizedStateRoots(batchIndex); - require(computedStateRoot == expectedStateRoot, "Invalid inclusion proof"); - } -} diff --git a/contracts/src/L2/IL2ScrollMessenger.sol b/contracts/src/L2/IL2ScrollMessenger.sol deleted file mode 100644 index 44e60b16f..000000000 --- a/contracts/src/L2/IL2ScrollMessenger.sol +++ /dev/null @@ -1,35 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.24; - -import {IScrollMessenger} from "../libraries/IScrollMessenger.sol"; - -interface IL2ScrollMessenger is IScrollMessenger { - /********** - * Events * - **********/ - - /// @notice Emitted when the maximum number of times each message can fail in L2 is updated. - /// @param oldMaxFailedExecutionTimes The old maximum number of times each message can fail in L2. - /// @param newMaxFailedExecutionTimes The new maximum number of times each message can fail in L2. - event UpdateMaxFailedExecutionTimes(uint256 oldMaxFailedExecutionTimes, uint256 newMaxFailedExecutionTimes); - - /***************************** - * Public Mutating Functions * - *****************************/ - - /// @notice execute L1 => L2 message - /// @dev Make sure this is only called by privileged accounts. - /// @param from The address of the sender of the message. - /// @param to The address of the recipient of the message. - /// @param value The msg.value passed to the message call. - /// @param nonce The nonce of the message to avoid replay attack. - /// @param message The content of the message. - function relayMessage( - address from, - address to, - uint256 value, - uint256 nonce, - bytes calldata message - ) external; -} diff --git a/contracts/src/L2/L2ScrollMessenger.sol b/contracts/src/L2/L2ScrollMessenger.sol deleted file mode 100644 index 3d01b40e8..000000000 --- a/contracts/src/L2/L2ScrollMessenger.sol +++ /dev/null @@ -1,170 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {IL2ScrollMessenger} from "./IL2ScrollMessenger.sol"; -import {L2MessageQueue} from "./predeploys/L2MessageQueue.sol"; - -import {PatriciaMerkleTrieVerifier} from "../libraries/verifier/PatriciaMerkleTrieVerifier.sol"; -import {ScrollConstants} from "../libraries/constants/ScrollConstants.sol"; -import {AddressAliasHelper} from "../libraries/common/AddressAliasHelper.sol"; -import {IScrollMessenger} from "../libraries/IScrollMessenger.sol"; -import {ScrollMessengerBase} from "../libraries/ScrollMessengerBase.sol"; - -// solhint-disable reason-string -// solhint-disable not-rely-on-time - -/// @title L2ScrollMessenger -/// @notice The `L2ScrollMessenger` contract can: -/// -/// 1. send messages from layer 2 to layer 1; -/// 2. relay messages from layer 1 layer 2; -/// 3. drop expired message due to sequencer problems. -/// -/// @dev It should be a predeployed contract on layer 2 and should hold infinite amount -/// of Ether (Specifically, `uint256(-1)`), which can be initialized in Genesis Block. -contract L2ScrollMessenger is ScrollMessengerBase, IL2ScrollMessenger { - /************* - * Constants * - *************/ - - /// @notice The address of L2MessageQueue. - address public immutable messageQueue; - - /************* - * Variables * - *************/ - - /// @notice Mapping from L2 message hash to the timestamp when the message is sent. - mapping(bytes32 => uint256) public messageSendTimestamp; - - /// @notice Mapping from L1 message hash to a boolean value indicating if the message has been successfully executed. - mapping(bytes32 => bool) public isL1MessageExecuted; - - /// @dev The storage slots used by previous versions of this contract. - uint256[2] private __used; - - /*************** - * Constructor * - ***************/ - - constructor(address _counterpart, address _messageQueue) ScrollMessengerBase(_counterpart) { - if (_messageQueue == address(0)) { - revert ErrorZeroAddress(); - } - - _disableInitializers(); - - messageQueue = _messageQueue; - } - - function initialize(address) external initializer { - ScrollMessengerBase.__ScrollMessengerBase_init(address(0), address(0)); - } - - /***************************** - * Public Mutating Functions * - *****************************/ - - /// @inheritdoc IScrollMessenger - function sendMessage( - address _to, - uint256 _value, - bytes memory _message, - uint256 _gasLimit - ) external payable override whenNotPaused { - _sendMessage(_to, _value, _message, _gasLimit); - } - - /// @inheritdoc IScrollMessenger - function sendMessage( - address _to, - uint256 _value, - bytes calldata _message, - uint256 _gasLimit, - address - ) external payable override whenNotPaused { - _sendMessage(_to, _value, _message, _gasLimit); - } - - /// @inheritdoc IL2ScrollMessenger - function relayMessage( - address _from, - address _to, - uint256 _value, - uint256 _nonce, - bytes memory _message - ) external override whenNotPaused { - // It is impossible to deploy a contract with the same address, reentrance is prevented in nature. - require(AddressAliasHelper.undoL1ToL2Alias(_msgSender()) == counterpart, "Caller is not L1ScrollMessenger"); - - bytes32 _xDomainCalldataHash = keccak256(_encodeXDomainCalldata(_from, _to, _value, _nonce, _message)); - - require(!isL1MessageExecuted[_xDomainCalldataHash], "Message was already successfully executed"); - - _executeMessage(_from, _to, _value, _message, _xDomainCalldataHash); - } - - /********************** - * Internal Functions * - **********************/ - - /// @dev Internal function to send cross domain message. - /// @param _to The address of account who receive the message. - /// @param _value The amount of ether passed when call target contract. - /// @param _message The content of the message. - /// @param _gasLimit Optional gas limit to complete the message relay on corresponding chain. - function _sendMessage( - address _to, - uint256 _value, - bytes memory _message, - uint256 _gasLimit - ) internal nonReentrant { - require(msg.value == _value, "msg.value mismatch"); - - uint256 _nonce = L2MessageQueue(messageQueue).nextMessageIndex(); - bytes32 _xDomainCalldataHash = keccak256(_encodeXDomainCalldata(_msgSender(), _to, _value, _nonce, _message)); - - // normally this won't happen, since each message has different nonce, but just in case. - require(messageSendTimestamp[_xDomainCalldataHash] == 0, "Duplicated message"); - messageSendTimestamp[_xDomainCalldataHash] = block.timestamp; - - L2MessageQueue(messageQueue).appendMessage(_xDomainCalldataHash); - - emit SentMessage(_msgSender(), _to, _value, _nonce, _gasLimit, _message); - } - - /// @dev Internal function to execute a L1 => L2 message. - /// @param _from The address of the sender of the message. - /// @param _to The address of the recipient of the message. - /// @param _value The msg.value passed to the message call. - /// @param _message The content of the message. - /// @param _xDomainCalldataHash The hash of the message. - function _executeMessage( - address _from, - address _to, - uint256 _value, - bytes memory _message, - bytes32 _xDomainCalldataHash - ) internal { - // @note check more `_to` address to avoid attack in the future when we add more gateways. - require(_to != messageQueue, "Forbid to call message queue"); - _validateTargetAddress(_to); - - // @note This usually will never happen, just in case. - require(_from != xDomainMessageSender, "Invalid message sender"); - - xDomainMessageSender = _from; - // solhint-disable-next-line avoid-low-level-calls - (bool success, ) = _to.call{value: _value}(_message); - // reset value to refund gas. - xDomainMessageSender = ScrollConstants.DEFAULT_XDOMAIN_MESSAGE_SENDER; - - if (success) { - isL1MessageExecuted[_xDomainCalldataHash] = true; - emit RelayedMessage(_xDomainCalldataHash); - } else { - emit FailedRelayedMessage(_xDomainCalldataHash); - } - } -} diff --git a/contracts/src/L2/gateways/IL2ERC1155Gateway.sol b/contracts/src/L2/gateways/IL2ERC1155Gateway.sol deleted file mode 100644 index 2a0d6182b..000000000 --- a/contracts/src/L2/gateways/IL2ERC1155Gateway.sol +++ /dev/null @@ -1,168 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.24; - -/// @title The interface for the ERC1155 cross chain gateway on layer 2. -interface IL2ERC1155Gateway { - /********** - * Events * - **********/ - - /// @notice Emitted when the ERC1155 NFT is transferred to recipient on layer 2. - /// @param l1Token The address of ERC1155 NFT on layer 1. - /// @param l2Token The address of ERC1155 NFT on layer 2. - /// @param from The address of sender on layer 1. - /// @param to The address of recipient on layer 2. - /// @param tokenId The token id of the ERC1155 NFT deposited on layer 1. - /// @param amount The amount of token deposited. - event FinalizeDepositERC1155( - address indexed l1Token, - address indexed l2Token, - address indexed from, - address to, - uint256 tokenId, - uint256 amount - ); - - /// @notice Emitted when the ERC1155 NFT is batch transferred to recipient on layer 2. - /// @param l1Token The address of ERC1155 NFT on layer 1. - /// @param l2Token The address of ERC1155 NFT on layer 2. - /// @param from The address of sender on layer 1. - /// @param to The address of recipient on layer 2. - /// @param tokenIds The list of token ids of the ERC1155 NFT deposited on layer 1. - /// @param amounts The list of corresponding amounts deposited. - event FinalizeBatchDepositERC1155( - address indexed l1Token, - address indexed l2Token, - address indexed from, - address to, - uint256[] tokenIds, - uint256[] amounts - ); - - /// @notice Emitted when the ERC1155 NFT is transferred to gateway on layer 2. - /// @param l1Token The address of ERC1155 NFT on layer 1. - /// @param l2Token The address of ERC1155 NFT on layer 2. - /// @param from The address of sender on layer 2. - /// @param to The address of recipient on layer 1. - /// @param tokenId The token id of the ERC1155 NFT to withdraw on layer 2. - /// @param amount The amount of token to withdraw. - event WithdrawERC1155( - address indexed l1Token, - address indexed l2Token, - address indexed from, - address to, - uint256 tokenId, - uint256 amount - ); - - /// @notice Emitted when the ERC1155 NFT is batch transferred to gateway on layer 2. - /// @param l1Token The address of ERC1155 NFT on layer 1. - /// @param l2Token The address of ERC1155 NFT on layer 2. - /// @param from The address of sender on layer 2. - /// @param to The address of recipient on layer 1. - /// @param tokenIds The list of token ids of the ERC1155 NFT to withdraw on layer 2. - /// @param amounts The list of corresponding amounts to withdraw. - event BatchWithdrawERC1155( - address indexed l1Token, - address indexed l2Token, - address indexed from, - address to, - uint256[] tokenIds, - uint256[] amounts - ); - - /***************************** - * Public Mutating Functions * - *****************************/ - - /// @notice Withdraw some ERC1155 NFT to caller's account on layer 1. - /// @param token The address of ERC1155 NFT on layer 2. - /// @param tokenId The token id to withdraw. - /// @param amount The amount of token to withdraw. - /// @param gasLimit Unused, but included for potential forward compatibility considerations. - function withdrawERC1155( - address token, - uint256 tokenId, - uint256 amount, - uint256 gasLimit - ) external payable; - - /// @notice Withdraw some ERC1155 NFT to caller's account on layer 1. - /// @param token The address of ERC1155 NFT on layer 2. - /// @param to The address of recipient on layer 1. - /// @param tokenId The token id to withdraw. - /// @param amount The amount of token to withdraw. - /// @param gasLimit Unused, but included for potential forward compatibility considerations. - function withdrawERC1155( - address token, - address to, - uint256 tokenId, - uint256 amount, - uint256 gasLimit - ) external payable; - - /// @notice Batch withdraw a list of ERC1155 NFT to caller's account on layer 1. - /// @param token The address of ERC1155 NFT on layer 2. - /// @param tokenIds The list of token ids to withdraw. - /// @param amounts The list of corresponding amounts to withdraw. - /// @param gasLimit Unused, but included for potential forward compatibility considerations. - function batchWithdrawERC1155( - address token, - uint256[] memory tokenIds, - uint256[] memory amounts, - uint256 gasLimit - ) external payable; - - /// @notice Batch withdraw a list of ERC1155 NFT to caller's account on layer 1. - /// @param token The address of ERC1155 NFT on layer 2. - /// @param to The address of recipient on layer 1. - /// @param tokenIds The list of token ids to withdraw. - /// @param amounts The list of corresponding amounts to withdraw. - /// @param gasLimit Unused, but included for potential forward compatibility considerations. - function batchWithdrawERC1155( - address token, - address to, - uint256[] memory tokenIds, - uint256[] memory amounts, - uint256 gasLimit - ) external payable; - - /// @notice Complete ERC1155 deposit from layer 1 to layer 2 and send NFT to recipient's account on layer 2. - /// @dev Requirements: - /// - The function should only be called by L2ScrollMessenger. - /// - The function should also only be called by L1ERC1155Gateway on layer 1. - /// @param l1Token The address of corresponding layer 1 token. - /// @param l2Token The address of corresponding layer 2 token. - /// @param from The address of account who deposits the token on layer 1. - /// @param to The address of recipient on layer 2 to receive the token. - /// @param tokenId The token id to deposit. - /// @param amount The amount of token to deposit. - function finalizeDepositERC1155( - address l1Token, - address l2Token, - address from, - address to, - uint256 tokenId, - uint256 amount - ) external; - - /// @notice Complete ERC1155 deposit from layer 1 to layer 2 and send NFT to recipient's account on layer 2. - /// @dev Requirements: - /// - The function should only be called by L2ScrollMessenger. - /// - The function should also only be called by L1ERC1155Gateway on layer 1. - /// @param l1Token The address of corresponding layer 1 token. - /// @param l2Token The address of corresponding layer 2 token. - /// @param from The address of account who deposits the token on layer 1. - /// @param to The address of recipient on layer 2 to receive the token. - /// @param tokenIds The list of token ids to deposit. - /// @param amounts The list of corresponding amounts to deposit. - function finalizeBatchDepositERC1155( - address l1Token, - address l2Token, - address from, - address to, - uint256[] calldata tokenIds, - uint256[] calldata amounts - ) external; -} diff --git a/contracts/src/L2/gateways/IL2ERC20Gateway.sol b/contracts/src/L2/gateways/IL2ERC20Gateway.sol deleted file mode 100644 index 39740cbd3..000000000 --- a/contracts/src/L2/gateways/IL2ERC20Gateway.sol +++ /dev/null @@ -1,115 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.24; - -interface IL2ERC20Gateway { - /********** - * Events * - **********/ - - /// @notice Emitted when ERC20 token is deposited from L1 to L2 and transfer to recipient. - /// @param l1Token The address of the token in L1. - /// @param l2Token The address of the token in L2. - /// @param from The address of sender in L1. - /// @param to The address of recipient in L2. - /// @param amount The amount of token withdrawn from L1 to L2. - /// @param data The optional calldata passed to recipient in L2. - event FinalizeDepositERC20( - address indexed l1Token, - address indexed l2Token, - address indexed from, - address to, - uint256 amount, - bytes data - ); - - /// @notice Emitted when someone withdraw ERC20 token from L2 to L1. - /// @param l1Token The address of the token in L1. - /// @param l2Token The address of the token in L2. - /// @param from The address of sender in L2. - /// @param to The address of recipient in L1. - /// @param amount The amount of token will be deposited from L2 to L1. - /// @param data The optional calldata passed to recipient in L1. - event WithdrawERC20( - address indexed l1Token, - address indexed l2Token, - address indexed from, - address to, - uint256 amount, - bytes data - ); - - /************************* - * Public View Functions * - *************************/ - - /// @notice Return the corresponding l1 token address given l2 token address. - /// @param l2Token The address of l2 token. - function getL1ERC20Address(address l2Token) external view returns (address); - - /// @notice Return the corresponding l2 token address given l1 token address. - /// @param l1Token The address of l1 token. - function getL2ERC20Address(address l1Token) external view returns (address); - - /***************************** - * Public Mutating Functions * - *****************************/ - - /// @notice Withdraw of some token to a caller's account on L1. - /// @dev Make this function payable to send relayer fee in Ether. - /// @param token The address of token in L2. - /// @param amount The amount of token to transfer. - /// @param gasLimit Unused, but included for potential forward compatibility considerations. - function withdrawERC20( - address token, - uint256 amount, - uint256 gasLimit - ) external payable; - - /// @notice Withdraw of some token to a recipient's account on L1. - /// @dev Make this function payable to send relayer fee in Ether. - /// @param token The address of token in L2. - /// @param to The address of recipient's account on L1. - /// @param amount The amount of token to transfer. - /// @param gasLimit Unused, but included for potential forward compatibility considerations. - function withdrawERC20( - address token, - address to, - uint256 amount, - uint256 gasLimit - ) external payable; - - /// @notice Withdraw of some token to a recipient's account on L1 and call. - /// @dev Make this function payable to send relayer fee in Ether. - /// @param token The address of token in L2. - /// @param to The address of recipient's account on L1. - /// @param amount The amount of token to transfer. - /// @param data Optional data to forward to recipient's account. - /// @param gasLimit Unused, but included for potential forward compatibility considerations. - function withdrawERC20AndCall( - address token, - address to, - uint256 amount, - bytes calldata data, - uint256 gasLimit - ) external payable; - - /// @notice Complete a deposit from L1 to L2 and send fund to recipient's account in L2. - /// @dev Make this function payable to handle WETH deposit/withdraw. - /// The function should only be called by L2ScrollMessenger. - /// The function should also only be called by L1ERC20Gateway in L1. - /// @param l1Token The address of corresponding L1 token. - /// @param l2Token The address of corresponding L2 token. - /// @param from The address of account who deposits the token in L1. - /// @param to The address of recipient in L2 to receive the token. - /// @param amount The amount of the token to deposit. - /// @param data Optional data to forward to recipient's account. - function finalizeDepositERC20( - address l1Token, - address l2Token, - address from, - address to, - uint256 amount, - bytes calldata data - ) external payable; -} diff --git a/contracts/src/L2/gateways/IL2ERC721Gateway.sol b/contracts/src/L2/gateways/IL2ERC721Gateway.sol deleted file mode 100644 index d92b55702..000000000 --- a/contracts/src/L2/gateways/IL2ERC721Gateway.sol +++ /dev/null @@ -1,148 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.24; - -/// @title The interface for the ERC721 cross chain gateway on layer 2. -interface IL2ERC721Gateway { - /********** - * Events * - **********/ - - /// @notice Emitted when the ERC721 NFT is transferred to recipient on layer 2. - /// @param l1Token The address of ERC721 NFT on layer 1. - /// @param l2Token The address of ERC721 NFT on layer 2. - /// @param from The address of sender on layer 1. - /// @param to The address of recipient on layer 2. - /// @param tokenId The token id of the ERC721 NFT deposited on layer 1. - event FinalizeDepositERC721( - address indexed l1Token, - address indexed l2Token, - address indexed from, - address to, - uint256 tokenId - ); - - /// @notice Emitted when the ERC721 NFT is batch transferred to recipient on layer 2. - /// @param l1Token The address of ERC721 NFT on layer 1. - /// @param l2Token The address of ERC721 NFT on layer 2. - /// @param from The address of sender on layer 1. - /// @param to The address of recipient on layer 2. - /// @param tokenIds The list of token ids of the ERC721 NFT deposited on layer 1. - event FinalizeBatchDepositERC721( - address indexed l1Token, - address indexed l2Token, - address indexed from, - address to, - uint256[] tokenIds - ); - - /// @notice Emitted when the ERC721 NFT is transferred to gateway on layer 2. - /// @param l1Token The address of ERC721 NFT on layer 1. - /// @param l2Token The address of ERC721 NFT on layer 2. - /// @param from The address of sender on layer 2. - /// @param to The address of recipient on layer 1. - /// @param tokenId The token id of the ERC721 NFT to withdraw on layer 2. - event WithdrawERC721( - address indexed l1Token, - address indexed l2Token, - address indexed from, - address to, - uint256 tokenId - ); - - /// @notice Emitted when the ERC721 NFT is batch transferred to gateway on layer 2. - /// @param l1Token The address of ERC721 NFT on layer 1. - /// @param l2Token The address of ERC721 NFT on layer 2. - /// @param from The address of sender on layer 2. - /// @param to The address of recipient on layer 1. - /// @param tokenIds The list of token ids of the ERC721 NFT to withdraw on layer 2. - event BatchWithdrawERC721( - address indexed l1Token, - address indexed l2Token, - address indexed from, - address to, - uint256[] tokenIds - ); - - /***************************** - * Public Mutating Functions * - *****************************/ - - /// @notice Withdraw some ERC721 NFT to caller's account on layer 1. - /// @param token The address of ERC721 NFT on layer 2. - /// @param tokenId The token id to withdraw. - /// @param gasLimit Unused, but included for potential forward compatibility considerations. - function withdrawERC721( - address token, - uint256 tokenId, - uint256 gasLimit - ) external payable; - - /// @notice Withdraw some ERC721 NFT to caller's account on layer 1. - /// @param token The address of ERC721 NFT on layer 2. - /// @param to The address of recipient on layer 1. - /// @param tokenId The token id to withdraw. - /// @param gasLimit Unused, but included for potential forward compatibility considerations. - function withdrawERC721( - address token, - address to, - uint256 tokenId, - uint256 gasLimit - ) external payable; - - /// @notice Batch withdraw a list of ERC721 NFT to caller's account on layer 1. - /// @param token The address of ERC721 NFT on layer 2. - /// @param tokenIds The list of token ids to withdraw. - /// @param gasLimit Unused, but included for potential forward compatibility considerations. - function batchWithdrawERC721( - address token, - uint256[] memory tokenIds, - uint256 gasLimit - ) external payable; - - /// @notice Batch withdraw a list of ERC721 NFT to caller's account on layer 1. - /// @param token The address of ERC721 NFT on layer 2. - /// @param to The address of recipient on layer 1. - /// @param tokenIds The list of token ids to withdraw. - /// @param gasLimit Unused, but included for potential forward compatibility considerations. - function batchWithdrawERC721( - address token, - address to, - uint256[] memory tokenIds, - uint256 gasLimit - ) external payable; - - /// @notice Complete ERC721 deposit from layer 1 to layer 2 and send NFT to recipient's account on layer 2. - /// @dev Requirements: - /// - The function should only be called by L2ScrollMessenger. - /// - The function should also only be called by L1ERC721Gateway on layer 1. - /// @param l1Token The address of corresponding layer 1 token. - /// @param l2Token The address of corresponding layer 2 token. - /// @param from The address of account who withdraw the token on layer 1. - /// @param to The address of recipient on layer 2 to receive the token. - /// @param tokenId The token id to withdraw. - function finalizeDepositERC721( - address l1Token, - address l2Token, - address from, - address to, - uint256 tokenId - ) external; - - /// @notice Complete ERC721 deposit from layer 1 to layer 2 and send NFT to recipient's account on layer 2. - /// @dev Requirements: - /// - The function should only be called by L2ScrollMessenger. - /// - The function should also only be called by L1ERC721Gateway on layer 1. - /// @param l1Token The address of corresponding layer 1 token. - /// @param l2Token The address of corresponding layer 2 token. - /// @param from The address of account who withdraw the token on layer 1. - /// @param to The address of recipient on layer 2 to receive the token. - /// @param tokenIds The list of token ids to withdraw. - function finalizeBatchDepositERC721( - address l1Token, - address l2Token, - address from, - address to, - uint256[] calldata tokenIds - ) external; -} diff --git a/contracts/src/L2/gateways/IL2ETHGateway.sol b/contracts/src/L2/gateways/IL2ETHGateway.sol deleted file mode 100644 index 80407b10e..000000000 --- a/contracts/src/L2/gateways/IL2ETHGateway.sol +++ /dev/null @@ -1,68 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.24; - -interface IL2ETHGateway { - /********** - * Events * - **********/ - - /// @notice Emitted when someone withdraw ETH from L2 to L1. - /// @param from The address of sender in L2. - /// @param to The address of recipient in L1. - /// @param amount The amount of ETH will be deposited from L2 to L1. - /// @param data The optional calldata passed to recipient in L1. - event WithdrawETH(address indexed from, address indexed to, uint256 amount, bytes data); - - /// @notice Emitted when ETH is deposited from L1 to L2 and transfer to recipient. - /// @param from The address of sender in L1. - /// @param to The address of recipient in L2. - /// @param amount The amount of ETH deposited from L1 to L2. - /// @param data The optional calldata passed to recipient in L2. - event FinalizeDepositETH(address indexed from, address indexed to, uint256 amount, bytes data); - - /***************************** - * Public Mutating Functions * - *****************************/ - - /// @notice Withdraw ETH to caller's account in L1. - /// @param amount The amount of ETH to be withdrawn. - /// @param gasLimit Optional, gas limit used to complete the withdraw on L1. - function withdrawETH(uint256 amount, uint256 gasLimit) external payable; - - /// @notice Withdraw ETH to caller's account in L1. - /// @param to The address of recipient's account on L1. - /// @param amount The amount of ETH to be withdrawn. - /// @param gasLimit Optional, gas limit used to complete the withdraw on L1. - function withdrawETH( - address to, - uint256 amount, - uint256 gasLimit - ) external payable; - - /// @notice Withdraw ETH to caller's account in L1. - /// @param to The address of recipient's account on L1. - /// @param amount The amount of ETH to be withdrawn. - /// @param data Optional data to forward to recipient's account. - /// @param gasLimit Optional, gas limit used to complete the withdraw on L1. - function withdrawETHAndCall( - address to, - uint256 amount, - bytes calldata data, - uint256 gasLimit - ) external payable; - - /// @notice Complete ETH deposit from L1 to L2 and send fund to recipient's account in L2. - /// @dev This function should only be called by L2ScrollMessenger. - /// This function should also only be called by L1GatewayRouter in L1. - /// @param _from The address of account who deposit ETH in L1. - /// @param _to The address of recipient in L2 to receive ETH. - /// @param _amount The amount of ETH to deposit. - /// @param _data Optional data to forward to recipient's account. - function finalizeDepositETH( - address _from, - address _to, - uint256 _amount, - bytes calldata _data - ) external payable; -} diff --git a/contracts/src/L2/gateways/IL2GatewayRouter.sol b/contracts/src/L2/gateways/IL2GatewayRouter.sol deleted file mode 100644 index f2a6facc8..000000000 --- a/contracts/src/L2/gateways/IL2GatewayRouter.sol +++ /dev/null @@ -1,48 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.24; - -import {IL2ETHGateway} from "./IL2ETHGateway.sol"; -import {IL2ERC20Gateway} from "./IL2ERC20Gateway.sol"; - -interface IL2GatewayRouter is IL2ETHGateway, IL2ERC20Gateway { - /********** - * Events * - **********/ - - /// @notice Emitted when the address of ETH Gateway is updated. - /// @param oldETHGateway The address of the old ETH Gateway. - /// @param newEthGateway The address of the new ETH Gateway. - event SetETHGateway(address indexed oldETHGateway, address indexed newEthGateway); - - /// @notice Emitted when the address of default ERC20 Gateway is updated. - /// @param oldDefaultERC20Gateway The address of the old default ERC20 Gateway. - /// @param newDefaultERC20Gateway The address of the new default ERC20 Gateway. - event SetDefaultERC20Gateway(address indexed oldDefaultERC20Gateway, address indexed newDefaultERC20Gateway); - - /// @notice Emitted when the `gateway` for `token` is updated. - /// @param token The address of token updated. - /// @param oldGateway The corresponding address of the old gateway. - /// @param newGateway The corresponding address of the new gateway. - event SetERC20Gateway(address indexed token, address indexed oldGateway, address indexed newGateway); - - /************************ - * Restricted Functions * - ************************/ - - /// @notice Update the address of ETH gateway contract. - /// @dev This function should only be called by contract owner. - /// @param _newEthGateway The address to update. - function setETHGateway(address _newEthGateway) external; - - /// @notice Update the address of default ERC20 gateway contract. - /// @dev This function should only be called by contract owner. - /// @param _newDefaultERC20Gateway The address to update. - function setDefaultERC20Gateway(address _newDefaultERC20Gateway) external; - - /// @notice Update the mapping from token address to gateway address. - /// @dev This function should only be called by contract owner. - /// @param _tokens The list of addresses of tokens to update. - /// @param _gateways The list of addresses of gateways to update. - function setERC20Gateway(address[] calldata _tokens, address[] calldata _gateways) external; -} diff --git a/contracts/src/L2/gateways/L2CustomERC20Gateway.sol b/contracts/src/L2/gateways/L2CustomERC20Gateway.sol deleted file mode 100644 index 32eb7dec1..000000000 --- a/contracts/src/L2/gateways/L2CustomERC20Gateway.sol +++ /dev/null @@ -1,160 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {IL2ERC20Gateway, L2ERC20Gateway} from "./L2ERC20Gateway.sol"; -import {IL2ScrollMessenger} from "../IL2ScrollMessenger.sol"; -import {IL1ERC20Gateway} from "../../L1/gateways/IL1ERC20Gateway.sol"; -import {ScrollGatewayBase} from "../../libraries/gateway/ScrollGatewayBase.sol"; -import {IScrollERC20Upgradeable} from "../../libraries/token/IScrollERC20Upgradeable.sol"; - -/// @title L2ERC20Gateway -/// @notice The `L2ERC20Gateway` is used to withdraw custom ERC20 compatible tokens on layer 2 and -/// finalize deposit the tokens from layer 1. -/// @dev The withdrawn tokens will be burned directly. On finalizing deposit, the corresponding -/// tokens will be minted and transferred to the recipient. -contract L2CustomERC20Gateway is L2ERC20Gateway { - /********** - * Events * - **********/ - - /// @notice Emitted when token mapping for ERC20 token is updated. - /// @param l2Token The address of corresponding ERC20 token in layer 2. - /// @param oldL1Token The address of the old corresponding ERC20 token in layer 1. - /// @param newL1Token The address of the new corresponding ERC20 token in layer 1. - event UpdateTokenMapping(address indexed l2Token, address indexed oldL1Token, address indexed newL1Token); - - /************* - * Variables * - *************/ - - /// @notice Mapping from layer 2 token address to layer 1 token address for ERC20 token. - // solhint-disable-next-line var-name-mixedcase - mapping(address => address) public tokenMapping; - - /*************** - * Constructor * - ***************/ - - /// @notice Constructor for `L2CustomERC20Gateway` implementation contract. - /// - /// @param _counterpart The address of `L1CustomERC20Gateway` contract in L1. - /// @param _router The address of `L2GatewayRouter` contract in L2. - /// @param _messenger The address of `L2ScrollMessenger` contract in L2. - constructor( - address _counterpart, - address _router, - address _messenger - ) ScrollGatewayBase(_counterpart, _router, _messenger) { - if (_router == address(0)) revert ErrorZeroAddress(); - - _disableInitializers(); - } - - /// @notice Initialize the storage of `L2CustomERC20Gateway`. - /// - /// @dev The parameters `_counterpart`, `_router` and `_messenger` are no longer used. - /// - /// @param _counterpart The address of `L1CustomERC20Gateway` contract in L1. - /// @param _router The address of `L2GatewayRouter` contract in L2. - /// @param _messenger The address of `L2ScrollMessenger` contract in L2. - function initialize( - address _counterpart, - address _router, - address _messenger - ) external initializer { - ScrollGatewayBase._initialize(_counterpart, _router, _messenger); - } - - /************************* - * Public View Functions * - *************************/ - - /// @inheritdoc IL2ERC20Gateway - function getL1ERC20Address(address _l2Token) external view override returns (address) { - return tokenMapping[_l2Token]; - } - - /// @inheritdoc IL2ERC20Gateway - function getL2ERC20Address(address) public pure override returns (address) { - revert("unimplemented"); - } - - /***************************** - * Public Mutating Functions * - *****************************/ - - /// @inheritdoc IL2ERC20Gateway - function finalizeDepositERC20( - address _l1Token, - address _l2Token, - address _from, - address _to, - uint256 _amount, - bytes calldata _data - ) external payable override onlyCallByCounterpart nonReentrant { - require(msg.value == 0, "nonzero msg.value"); - require(_l1Token != address(0), "token address cannot be 0"); - require(_l1Token == tokenMapping[_l2Token], "l1 token mismatch"); - - IScrollERC20Upgradeable(_l2Token).mint(_to, _amount); - - _doCallback(_to, _data); - - emit FinalizeDepositERC20(_l1Token, _l2Token, _from, _to, _amount, _data); - } - - /************************ - * Restricted Functions * - ************************/ - - /// @notice Update layer 2 to layer 1 token mapping. - /// @param _l2Token The address of corresponding ERC20 token on layer 2. - /// @param _l1Token The address of ERC20 token on layer 1. - function updateTokenMapping(address _l2Token, address _l1Token) external onlyOwner { - require(_l1Token != address(0), "token address cannot be 0"); - - address _oldL1Token = tokenMapping[_l2Token]; - tokenMapping[_l2Token] = _l1Token; - - emit UpdateTokenMapping(_l2Token, _oldL1Token, _l1Token); - } - - /********************** - * Internal Functions * - **********************/ - - /// @inheritdoc L2ERC20Gateway - function _withdraw( - address _token, - address _to, - uint256 _amount, - bytes memory _data, - uint256 _gasLimit - ) internal virtual override nonReentrant { - address _l1Token = tokenMapping[_token]; - require(_l1Token != address(0), "no corresponding l1 token"); - - require(_amount > 0, "withdraw zero amount"); - - // 1. Extract real sender if this call is from L2GatewayRouter. - address _from = _msgSender(); - if (router == _from) { - (_from, _data) = abi.decode(_data, (address, bytes)); - } - - // 2. Burn token. - IScrollERC20Upgradeable(_token).burn(_from, _amount); - - // 3. Generate message passed to L1StandardERC20Gateway. - bytes memory _message = abi.encodeCall( - IL1ERC20Gateway.finalizeWithdrawERC20, - (_l1Token, _token, _from, _to, _amount, _data) - ); - - // 4. send message to L2ScrollMessenger - IL2ScrollMessenger(messenger).sendMessage{value: msg.value}(counterpart, 0, _message, _gasLimit); - - emit WithdrawERC20(_l1Token, _token, _from, _to, _amount, _data); - } -} diff --git a/contracts/src/L2/gateways/L2ERC1155Gateway.sol b/contracts/src/L2/gateways/L2ERC1155Gateway.sol deleted file mode 100644 index d85f685a6..000000000 --- a/contracts/src/L2/gateways/L2ERC1155Gateway.sol +++ /dev/null @@ -1,238 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {ERC1155HolderUpgradeable, ERC1155ReceiverUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC1155/utils/ERC1155HolderUpgradeable.sol"; - -import {IL2ERC1155Gateway} from "./IL2ERC1155Gateway.sol"; -import {IL2ScrollMessenger} from "../IL2ScrollMessenger.sol"; -import {IL1ERC1155Gateway} from "../../L1/gateways/IL1ERC1155Gateway.sol"; -import {ScrollGatewayBase} from "../../libraries/gateway/ScrollGatewayBase.sol"; -import {IScrollERC1155} from "../../libraries/token/IScrollERC1155.sol"; - -/// @title L2ERC1155Gateway -/// @notice The `L2ERC1155Gateway` is used to withdraw ERC1155 compatible NFTs on layer 2 and -/// finalize deposit the NFTs from layer 1. -/// @dev The withdrawn NFTs tokens will be burned directly. On finalizing deposit, the corresponding -/// NFT will be minted and transferred to the recipient. -/// -/// This will be changed if we have more specific scenarios. -contract L2ERC1155Gateway is ERC1155HolderUpgradeable, ScrollGatewayBase, IL2ERC1155Gateway { - /********** - * Events * - **********/ - - /// @notice Emitted when token mapping for ERC1155 token is updated. - /// @param l2Token The address of corresponding ERC1155 token in layer 2. - /// @param oldL1Token The address of the old corresponding ERC1155 token in layer 1. - /// @param newL1Token The address of the new corresponding ERC1155 token in layer 1. - event UpdateTokenMapping(address indexed l2Token, address indexed oldL1Token, address indexed newL1Token); - - /************* - * Variables * - *************/ - - /// @notice Mapping from layer 2 token address to layer 1 token address for ERC1155 NFT. - // solhint-disable-next-line var-name-mixedcase - mapping(address => address) public tokenMapping; - - /*************** - * Constructor * - ***************/ - - /// @notice Constructor for `L2ERC1155Gateway` implementation contract. - /// - /// @param _counterpart The address of `L1ERC1155Gateway` contract in L1. - /// @param _messenger The address of `L2ScrollMessenger` contract in L2. - constructor(address _counterpart, address _messenger) ScrollGatewayBase(_counterpart, address(0), _messenger) { - _disableInitializers(); - } - - /// @notice Initialize the storage of `L2ERC1155Gateway`. - /// - /// @dev The parameters `_counterpart` and `_messenger` are no longer used. - /// - /// @param _counterpart The address of `L1ERC1155Gateway` contract in L1. - /// @param _messenger The address of `L2ScrollMessenger` contract in L2. - function initialize(address _counterpart, address _messenger) external initializer { - ERC1155HolderUpgradeable.__ERC1155Holder_init(); - ERC1155ReceiverUpgradeable.__ERC1155Receiver_init(); - - ScrollGatewayBase._initialize(_counterpart, address(0), _messenger); - } - - /***************************** - * Public Mutating Functions * - *****************************/ - - /// @inheritdoc IL2ERC1155Gateway - function withdrawERC1155( - address _token, - uint256 _tokenId, - uint256 _amount, - uint256 _gasLimit - ) external payable override { - _withdrawERC1155(_token, _msgSender(), _tokenId, _amount, _gasLimit); - } - - /// @inheritdoc IL2ERC1155Gateway - function withdrawERC1155( - address _token, - address _to, - uint256 _tokenId, - uint256 _amount, - uint256 _gasLimit - ) external payable override { - _withdrawERC1155(_token, _to, _tokenId, _amount, _gasLimit); - } - - /// @inheritdoc IL2ERC1155Gateway - function batchWithdrawERC1155( - address _token, - uint256[] calldata _tokenIds, - uint256[] calldata _amounts, - uint256 _gasLimit - ) external payable override { - _batchWithdrawERC1155(_token, _msgSender(), _tokenIds, _amounts, _gasLimit); - } - - /// @inheritdoc IL2ERC1155Gateway - function batchWithdrawERC1155( - address _token, - address _to, - uint256[] calldata _tokenIds, - uint256[] calldata _amounts, - uint256 _gasLimit - ) external payable override { - _batchWithdrawERC1155(_token, _to, _tokenIds, _amounts, _gasLimit); - } - - /// @inheritdoc IL2ERC1155Gateway - function finalizeDepositERC1155( - address _l1Token, - address _l2Token, - address _from, - address _to, - uint256 _tokenId, - uint256 _amount - ) external virtual onlyCallByCounterpart nonReentrant { - require(_l1Token != address(0), "token address cannot be 0"); - require(_l1Token == tokenMapping[_l2Token], "l2 token mismatch"); - - IScrollERC1155(_l2Token).mint(_to, _tokenId, _amount, ""); - - emit FinalizeDepositERC1155(_l1Token, _l2Token, _from, _to, _tokenId, _amount); - } - - /// @inheritdoc IL2ERC1155Gateway - function finalizeBatchDepositERC1155( - address _l1Token, - address _l2Token, - address _from, - address _to, - uint256[] calldata _tokenIds, - uint256[] calldata _amounts - ) external virtual onlyCallByCounterpart nonReentrant { - require(_l1Token != address(0), "token address cannot be 0"); - require(_l1Token == tokenMapping[_l2Token], "l2 token mismatch"); - - IScrollERC1155(_l2Token).batchMint(_to, _tokenIds, _amounts, ""); - - emit FinalizeBatchDepositERC1155(_l1Token, _l2Token, _from, _to, _tokenIds, _amounts); - } - - /************************ - * Restricted Functions * - ************************/ - - /// @notice Update layer 2 to layer 1 token mapping. - /// @param _l2Token The address of corresponding ERC1155 token on layer 2. - /// @param _l1Token The address of ERC1155 token on layer 1. - function updateTokenMapping(address _l2Token, address _l1Token) external onlyOwner { - require(_l1Token != address(0), "token address cannot be 0"); - - address _oldL1Token = tokenMapping[_l2Token]; - tokenMapping[_l2Token] = _l1Token; - - emit UpdateTokenMapping(_l2Token, _oldL1Token, _l1Token); - } - - /********************** - * Internal Functions * - **********************/ - - /// @dev Internal function to withdraw ERC1155 NFT to layer 2. - /// @param _token The address of ERC1155 NFT on layer 1. - /// @param _to The address of recipient on layer 2. - /// @param _tokenId The token id to withdraw. - /// @param _amount The amount of token to withdraw. - /// @param _gasLimit Estimated gas limit required to complete the withdraw on layer 2. - function _withdrawERC1155( - address _token, - address _to, - uint256 _tokenId, - uint256 _amount, - uint256 _gasLimit - ) internal virtual nonReentrant { - require(_amount > 0, "withdraw zero amount"); - - address _l1Token = tokenMapping[_token]; - require(_l1Token != address(0), "no corresponding l1 token"); - - address _sender = _msgSender(); - - // 1. burn token - IScrollERC1155(_token).burn(_sender, _tokenId, _amount); - - // 2. Generate message passed to L1ERC1155Gateway. - bytes memory _message = abi.encodeCall( - IL1ERC1155Gateway.finalizeWithdrawERC1155, - (_l1Token, _token, _sender, _to, _tokenId, _amount) - ); - - // 3. Send message to L2ScrollMessenger. - IL2ScrollMessenger(messenger).sendMessage{value: msg.value}(counterpart, 0, _message, _gasLimit); - - emit WithdrawERC1155(_l1Token, _token, _sender, _to, _tokenId, _amount); - } - - /// @dev Internal function to batch withdraw ERC1155 NFT to layer 2. - /// @param _token The address of ERC1155 NFT on layer 1. - /// @param _to The address of recipient on layer 2. - /// @param _tokenIds The list of token ids to withdraw. - /// @param _amounts The list of corresponding number of token to withdraw. - /// @param _gasLimit Estimated gas limit required to complete the withdraw on layer 1. - function _batchWithdrawERC1155( - address _token, - address _to, - uint256[] calldata _tokenIds, - uint256[] calldata _amounts, - uint256 _gasLimit - ) internal virtual nonReentrant { - require(_tokenIds.length > 0, "no token to withdraw"); - require(_tokenIds.length == _amounts.length, "length mismatch"); - - for (uint256 i = 0; i < _amounts.length; i++) { - require(_amounts[i] > 0, "withdraw zero amount"); - } - - address _l1Token = tokenMapping[_token]; - require(_l1Token != address(0), "no corresponding l1 token"); - - address _sender = _msgSender(); - - // 1. transfer token to this contract - IScrollERC1155(_token).batchBurn(_sender, _tokenIds, _amounts); - - // 2. Generate message passed to L1ERC1155Gateway. - bytes memory _message = abi.encodeCall( - IL1ERC1155Gateway.finalizeBatchWithdrawERC1155, - (_l1Token, _token, _sender, _to, _tokenIds, _amounts) - ); - - // 3. Send message to L2ScrollMessenger. - IL2ScrollMessenger(messenger).sendMessage{value: msg.value}(counterpart, 0, _message, _gasLimit); - - emit BatchWithdrawERC1155(_l1Token, _token, _sender, _to, _tokenIds, _amounts); - } -} diff --git a/contracts/src/L2/gateways/L2ERC20Gateway.sol b/contracts/src/L2/gateways/L2ERC20Gateway.sol deleted file mode 100644 index 7479a9398..000000000 --- a/contracts/src/L2/gateways/L2ERC20Gateway.sol +++ /dev/null @@ -1,62 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.24; - -import {IL2ERC20Gateway} from "./IL2ERC20Gateway.sol"; - -import {ScrollGatewayBase} from "../../libraries/gateway/ScrollGatewayBase.sol"; - -abstract contract L2ERC20Gateway is ScrollGatewayBase, IL2ERC20Gateway { - /************* - * Variables * - *************/ - - /// @dev The storage slots for future usage. - uint256[50] private __gap; - - /***************************** - * Public Mutating Functions * - *****************************/ - - /// @inheritdoc IL2ERC20Gateway - function withdrawERC20( - address _token, - uint256 _amount, - uint256 _gasLimit - ) external payable override { - _withdraw(_token, _msgSender(), _amount, new bytes(0), _gasLimit); - } - - /// @inheritdoc IL2ERC20Gateway - function withdrawERC20( - address _token, - address _to, - uint256 _amount, - uint256 _gasLimit - ) external payable override { - _withdraw(_token, _to, _amount, new bytes(0), _gasLimit); - } - - /// @inheritdoc IL2ERC20Gateway - function withdrawERC20AndCall( - address _token, - address _to, - uint256 _amount, - bytes calldata _data, - uint256 _gasLimit - ) external payable override { - _withdraw(_token, _to, _amount, _data, _gasLimit); - } - - /********************** - * Internal Functions * - **********************/ - - function _withdraw( - address _token, - address _to, - uint256 _amount, - bytes memory _data, - uint256 _gasLimit - ) internal virtual; -} diff --git a/contracts/src/L2/gateways/L2ERC721Gateway.sol b/contracts/src/L2/gateways/L2ERC721Gateway.sol deleted file mode 100644 index 72c408535..000000000 --- a/contracts/src/L2/gateways/L2ERC721Gateway.sol +++ /dev/null @@ -1,228 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {ERC721HolderUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC721/utils/ERC721HolderUpgradeable.sol"; - -import {IL2ERC721Gateway} from "./IL2ERC721Gateway.sol"; -import {IL2ScrollMessenger} from "../IL2ScrollMessenger.sol"; -import {IL1ERC721Gateway} from "../../L1/gateways/IL1ERC721Gateway.sol"; -import {ScrollGatewayBase} from "../../libraries/gateway/ScrollGatewayBase.sol"; -import {IScrollERC721} from "../../libraries/token/IScrollERC721.sol"; - -/// @title L2ERC721Gateway -/// @notice The `L2ERC721Gateway` is used to withdraw ERC721 compatible NFTs on layer 2 and -/// finalize deposit the NFTs from layer 1. -/// @dev The withdrawn NFTs tokens will be burned directly. On finalizing deposit, the corresponding -/// NFT will be minted and transferred to the recipient. -/// -/// This will be changed if we have more specific scenarios. -contract L2ERC721Gateway is ERC721HolderUpgradeable, ScrollGatewayBase, IL2ERC721Gateway { - /********** - * Events * - **********/ - - /// @notice Emitted when token mapping for ERC721 token is updated. - /// @param l2Token The address of corresponding ERC721 token in layer 2. - /// @param oldL1Token The address of the old corresponding ERC721 token in layer 1. - /// @param newL1Token The address of the new corresponding ERC721 token in layer 1. - event UpdateTokenMapping(address indexed l2Token, address indexed oldL1Token, address indexed newL1Token); - - /************* - * Variables * - *************/ - - /// @notice Mapping from layer 2 token address to layer 1 token address for ERC721 NFT. - // solhint-disable-next-line var-name-mixedcase - mapping(address => address) public tokenMapping; - - /*************** - * Constructor * - ***************/ - - /// @notice Constructor for `L2ERC721Gateway` implementation contract. - /// - /// @param _counterpart The address of `L1ERC721Gateway` contract in L1. - /// @param _messenger The address of `L2ScrollMessenger` contract in L2. - constructor(address _counterpart, address _messenger) ScrollGatewayBase(_counterpart, address(0), _messenger) { - _disableInitializers(); - } - - /// @notice Initialize the storage of `L2ERC721Gateway`. - /// - /// @dev The parameters `_counterpart` and `_messenger` are no longer used. - /// - /// @param _counterpart The address of `L1ERC721Gateway` contract in L1. - /// @param _messenger The address of `L2ScrollMessenger` contract in L2. - function initialize(address _counterpart, address _messenger) external initializer { - ERC721HolderUpgradeable.__ERC721Holder_init(); - - ScrollGatewayBase._initialize(_counterpart, address(0), _messenger); - } - - /***************************** - * Public Mutating Functions * - *****************************/ - - /// @inheritdoc IL2ERC721Gateway - function withdrawERC721( - address _token, - uint256 _tokenId, - uint256 _gasLimit - ) external payable override { - _withdrawERC721(_token, _msgSender(), _tokenId, _gasLimit); - } - - /// @inheritdoc IL2ERC721Gateway - function withdrawERC721( - address _token, - address _to, - uint256 _tokenId, - uint256 _gasLimit - ) external payable override { - _withdrawERC721(_token, _to, _tokenId, _gasLimit); - } - - /// @inheritdoc IL2ERC721Gateway - function batchWithdrawERC721( - address _token, - uint256[] calldata _tokenIds, - uint256 _gasLimit - ) external payable override { - _batchWithdrawERC721(_token, _msgSender(), _tokenIds, _gasLimit); - } - - /// @inheritdoc IL2ERC721Gateway - function batchWithdrawERC721( - address _token, - address _to, - uint256[] calldata _tokenIds, - uint256 _gasLimit - ) external payable override { - _batchWithdrawERC721(_token, _to, _tokenIds, _gasLimit); - } - - /// @inheritdoc IL2ERC721Gateway - function finalizeDepositERC721( - address _l1Token, - address _l2Token, - address _from, - address _to, - uint256 _tokenId - ) external virtual onlyCallByCounterpart nonReentrant { - require(_l1Token != address(0), "token address cannot be 0"); - require(_l1Token == tokenMapping[_l2Token], "l2 token mismatch"); - - IScrollERC721(_l2Token).mint(_to, _tokenId); - - emit FinalizeDepositERC721(_l1Token, _l2Token, _from, _to, _tokenId); - } - - /// @inheritdoc IL2ERC721Gateway - function finalizeBatchDepositERC721( - address _l1Token, - address _l2Token, - address _from, - address _to, - uint256[] calldata _tokenIds - ) external virtual onlyCallByCounterpart nonReentrant { - require(_l1Token != address(0), "token address cannot be 0"); - require(_l1Token == tokenMapping[_l2Token], "l2 token mismatch"); - - for (uint256 i = 0; i < _tokenIds.length; i++) { - IScrollERC721(_l2Token).mint(_to, _tokenIds[i]); - } - - emit FinalizeBatchDepositERC721(_l1Token, _l2Token, _from, _to, _tokenIds); - } - - /************************ - * Restricted Functions * - ************************/ - - /// @notice Update layer 2 to layer 1 token mapping. - /// @param _l2Token The address of corresponding ERC721 token on layer 2. - /// @param _l1Token The address of ERC721 token on layer 1. - function updateTokenMapping(address _l2Token, address _l1Token) external onlyOwner { - require(_l1Token != address(0), "token address cannot be 0"); - - address _oldL1Token = tokenMapping[_l2Token]; - tokenMapping[_l2Token] = _l1Token; - - emit UpdateTokenMapping(_l2Token, _oldL1Token, _l1Token); - } - - /********************** - * Internal Functions * - **********************/ - - /// @dev Internal function to withdraw ERC721 NFT to layer 1. - /// @param _token The address of ERC721 NFT on layer 2. - /// @param _to The address of recipient on layer 1. - /// @param _tokenId The token id to withdraw. - /// @param _gasLimit Estimated gas limit required to complete the withdraw on layer 1. - function _withdrawERC721( - address _token, - address _to, - uint256 _tokenId, - uint256 _gasLimit - ) internal virtual nonReentrant { - address _l1Token = tokenMapping[_token]; - require(_l1Token != address(0), "no corresponding l1 token"); - - address _sender = _msgSender(); - - // 1. burn token - // @note in case the token has given too much power to the gateway, we check owner here. - require(IScrollERC721(_token).ownerOf(_tokenId) == _sender, "token not owned"); - IScrollERC721(_token).burn(_tokenId); - - // 2. Generate message passed to L1ERC721Gateway. - bytes memory _message = abi.encodeCall( - IL1ERC721Gateway.finalizeWithdrawERC721, - (_l1Token, _token, _sender, _to, _tokenId) - ); - - // 3. Send message to L2ScrollMessenger. - IL2ScrollMessenger(messenger).sendMessage{value: msg.value}(counterpart, 0, _message, _gasLimit); - - emit WithdrawERC721(_l1Token, _token, _sender, _to, _tokenId); - } - - /// @dev Internal function to batch withdraw ERC721 NFT to layer 1. - /// @param _token The address of ERC721 NFT on layer 2. - /// @param _to The address of recipient on layer 1. - /// @param _tokenIds The list of token ids to withdraw. - /// @param _gasLimit Estimated gas limit required to complete the withdraw on layer 1. - function _batchWithdrawERC721( - address _token, - address _to, - uint256[] calldata _tokenIds, - uint256 _gasLimit - ) internal virtual nonReentrant { - require(_tokenIds.length > 0, "no token to withdraw"); - - address _l1Token = tokenMapping[_token]; - require(_l1Token != address(0), "no corresponding l1 token"); - - address _sender = _msgSender(); - - // 1. transfer token to this contract - for (uint256 i = 0; i < _tokenIds.length; i++) { - // @note in case the token has given too much power to the gateway, we check owner here. - require(IScrollERC721(_token).ownerOf(_tokenIds[i]) == _sender, "token not owned"); - IScrollERC721(_token).burn(_tokenIds[i]); - } - - // 2. Generate message passed to L1ERC721Gateway. - bytes memory _message = abi.encodeCall( - IL1ERC721Gateway.finalizeBatchWithdrawERC721, - (_l1Token, _token, _sender, _to, _tokenIds) - ); - - // 3. Send message to L2ScrollMessenger. - IL2ScrollMessenger(messenger).sendMessage{value: msg.value}(counterpart, 0, _message, _gasLimit); - - emit BatchWithdrawERC721(_l1Token, _token, _sender, _to, _tokenIds); - } -} diff --git a/contracts/src/L2/gateways/L2ETHGateway.sol b/contracts/src/L2/gateways/L2ETHGateway.sol deleted file mode 100644 index ae9c42ffb..000000000 --- a/contracts/src/L2/gateways/L2ETHGateway.sol +++ /dev/null @@ -1,128 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {IL1ETHGateway} from "../../L1/gateways/IL1ETHGateway.sol"; -import {IL2ScrollMessenger} from "../IL2ScrollMessenger.sol"; -import {IL2ETHGateway} from "./IL2ETHGateway.sol"; - -import {ScrollGatewayBase} from "../../libraries/gateway/ScrollGatewayBase.sol"; - -/// @title L2ETHGateway -/// @notice The `L2ETHGateway` contract is used to withdraw ETH token on layer 2 and -/// finalize deposit ETH from layer 1. -/// @dev The ETH are not held in the gateway. The ETH will be sent to the `L2ScrollMessenger` contract. -/// On finalizing deposit, the Ether will be transferred from `L2ScrollMessenger`, then transfer to recipient. -contract L2ETHGateway is ScrollGatewayBase, IL2ETHGateway { - /*************** - * Constructor * - ***************/ - - /// @notice Constructor for `L2ETHGateway` implementation contract. - /// - /// @param _counterpart The address of `L1ETHGateway` contract in L1. - /// @param _router The address of `L1GatewayRouter` contract. - /// @param _messenger The address of `L1ScrollMessenger` contract. - constructor( - address _counterpart, - address _router, - address _messenger - ) ScrollGatewayBase(_counterpart, _router, _messenger) { - if (_router == address(0)) revert ErrorZeroAddress(); - - _disableInitializers(); - } - - /// @notice Initialize the storage of L2ETHGateway. - /// - /// @dev The parameters `_counterpart`, `_router` and `_messenger` are no longer used. - /// - /// @param _counterpart The address of L1ETHGateway in L1. - /// @param _router The address of L2GatewayRouter in L2. - /// @param _messenger The address of L2ScrollMessenger in L2. - function initialize( - address _counterpart, - address _router, - address _messenger - ) external initializer { - ScrollGatewayBase._initialize(_counterpart, _router, _messenger); - } - - /***************************** - * Public Mutating Functions * - *****************************/ - - /// @inheritdoc IL2ETHGateway - function withdrawETH(uint256 _amount, uint256 _gasLimit) external payable override { - _withdraw(_msgSender(), _amount, new bytes(0), _gasLimit); - } - - /// @inheritdoc IL2ETHGateway - function withdrawETH( - address _to, - uint256 _amount, - uint256 _gasLimit - ) public payable override { - _withdraw(_to, _amount, new bytes(0), _gasLimit); - } - - /// @inheritdoc IL2ETHGateway - function withdrawETHAndCall( - address _to, - uint256 _amount, - bytes memory _data, - uint256 _gasLimit - ) public payable override { - _withdraw(_to, _amount, _data, _gasLimit); - } - - /// @inheritdoc IL2ETHGateway - function finalizeDepositETH( - address _from, - address _to, - uint256 _amount, - bytes calldata _data - ) external payable override onlyCallByCounterpart nonReentrant { - require(msg.value == _amount, "msg.value mismatch"); - - // solhint-disable-next-line avoid-low-level-calls - (bool _success, ) = _to.call{value: _amount}(""); - require(_success, "ETH transfer failed"); - - _doCallback(_to, _data); - - emit FinalizeDepositETH(_from, _to, _amount, _data); - } - - /********************** - * Internal Functions * - **********************/ - - /// @dev The internal ETH withdraw implementation. - /// @param _to The address of recipient's account on L1. - /// @param _amount The amount of ETH to be withdrawn. - /// @param _data Optional data to forward to recipient's account. - /// @param _gasLimit Optional gas limit to complete the deposit on L1. - function _withdraw( - address _to, - uint256 _amount, - bytes memory _data, - uint256 _gasLimit - ) internal virtual nonReentrant { - require(msg.value > 0, "withdraw zero eth"); - - // 1. Extract real sender if this call is from L1GatewayRouter. - address _from = _msgSender(); - - if (router == _from) { - (_from, _data) = abi.decode(_data, (address, bytes)); - } - - // @note no rate limit here, since ETH is limited in messenger - - bytes memory _message = abi.encodeCall(IL1ETHGateway.finalizeWithdrawETH, (_from, _to, _amount, _data)); - IL2ScrollMessenger(messenger).sendMessage{value: msg.value}(counterpart, _amount, _message, _gasLimit); - - emit WithdrawETH(_from, _to, _amount, _data); - } -} diff --git a/contracts/src/L2/gateways/L2GatewayRouter.sol b/contracts/src/L2/gateways/L2GatewayRouter.sol deleted file mode 100644 index 2bf214757..000000000 --- a/contracts/src/L2/gateways/L2GatewayRouter.sol +++ /dev/null @@ -1,207 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; - -import {IL2GatewayRouter} from "./IL2GatewayRouter.sol"; -import {IL2ETHGateway} from "./IL2ETHGateway.sol"; -import {IL2ERC20Gateway} from "./IL2ERC20Gateway.sol"; - -/// @title L2GatewayRouter -/// @notice The `L2GatewayRouter` is the main entry for withdrawing Ether and ERC20 tokens. -/// All deposited tokens are routed to corresponding gateways. -/// @dev One can also use this contract to query L1/L2 token address mapping. -/// In the future, ERC-721 and ERC-1155 tokens will be added to the router too. -contract L2GatewayRouter is OwnableUpgradeable, IL2GatewayRouter { - /************* - * Variables * - *************/ - - /// @notice The address of L2ETHGateway. - address public ethGateway; - - /// @notice The address of default L2 ERC20 gateway, normally the L2StandardERC20Gateway contract. - address public defaultERC20Gateway; - - /// @notice Mapping from L2 ERC20 token address to corresponding L2ERC20Gateway. - // solhint-disable-next-line var-name-mixedcase - mapping(address => address) public ERC20Gateway; - - /*************** - * Constructor * - ***************/ - - constructor() { - _disableInitializers(); - } - - function initialize(address _ethGateway, address _defaultERC20Gateway) external initializer { - OwnableUpgradeable.__Ownable_init(); - - // it can be zero during initialization - if (_defaultERC20Gateway != address(0)) { - defaultERC20Gateway = _defaultERC20Gateway; - emit SetDefaultERC20Gateway(address(0), _defaultERC20Gateway); - } - - // it can be zero during initialization - if (_ethGateway != address(0)) { - ethGateway = _ethGateway; - emit SetETHGateway(address(0), _ethGateway); - } - } - - /************************* - * Public View Functions * - *************************/ - - /// @inheritdoc IL2ERC20Gateway - function getL2ERC20Address(address) external pure override returns (address) { - revert("unsupported"); - } - - /// @inheritdoc IL2ERC20Gateway - function getL1ERC20Address(address _l2Address) external view override returns (address) { - address _gateway = getERC20Gateway(_l2Address); - if (_gateway == address(0)) { - return address(0); - } - - return IL2ERC20Gateway(_gateway).getL1ERC20Address(_l2Address); - } - - /// @notice Return the corresponding gateway address for given token address. - /// @param _token The address of token to query. - function getERC20Gateway(address _token) public view returns (address) { - address _gateway = ERC20Gateway[_token]; - if (_gateway == address(0)) { - _gateway = defaultERC20Gateway; - } - return _gateway; - } - - /***************************** - * Public Mutating Functions * - *****************************/ - - /// @inheritdoc IL2ERC20Gateway - function withdrawERC20( - address _token, - uint256 _amount, - uint256 _gasLimit - ) external payable override { - withdrawERC20AndCall(_token, _msgSender(), _amount, new bytes(0), _gasLimit); - } - - /// @inheritdoc IL2ERC20Gateway - function withdrawERC20( - address _token, - address _to, - uint256 _amount, - uint256 _gasLimit - ) external payable override { - withdrawERC20AndCall(_token, _to, _amount, new bytes(0), _gasLimit); - } - - /// @inheritdoc IL2ERC20Gateway - function withdrawERC20AndCall( - address _token, - address _to, - uint256 _amount, - bytes memory _data, - uint256 _gasLimit - ) public payable override { - address _gateway = getERC20Gateway(_token); - require(_gateway != address(0), "no gateway available"); - - // encode msg.sender with _data - bytes memory _routerData = abi.encode(_msgSender(), _data); - - IL2ERC20Gateway(_gateway).withdrawERC20AndCall{value: msg.value}(_token, _to, _amount, _routerData, _gasLimit); - } - - /// @inheritdoc IL2ETHGateway - function withdrawETH(uint256 _amount, uint256 _gasLimit) external payable override { - withdrawETHAndCall(_msgSender(), _amount, new bytes(0), _gasLimit); - } - - /// @inheritdoc IL2ETHGateway - function withdrawETH( - address _to, - uint256 _amount, - uint256 _gasLimit - ) external payable override { - withdrawETHAndCall(_to, _amount, new bytes(0), _gasLimit); - } - - /// @inheritdoc IL2ETHGateway - function withdrawETHAndCall( - address _to, - uint256 _amount, - bytes memory _data, - uint256 _gasLimit - ) public payable override { - address _gateway = ethGateway; - require(_gateway != address(0), "eth gateway available"); - - // encode msg.sender with _data - bytes memory _routerData = abi.encode(_msgSender(), _data); - - IL2ETHGateway(_gateway).withdrawETHAndCall{value: msg.value}(_to, _amount, _routerData, _gasLimit); - } - - /// @inheritdoc IL2ETHGateway - function finalizeDepositETH( - address, - address, - uint256, - bytes calldata - ) external payable virtual override { - revert("should never be called"); - } - - /// @inheritdoc IL2ERC20Gateway - function finalizeDepositERC20( - address, - address, - address, - address, - uint256, - bytes calldata - ) external payable virtual override { - revert("should never be called"); - } - - /************************ - * Restricted Functions * - ************************/ - - /// @inheritdoc IL2GatewayRouter - function setETHGateway(address _newEthGateway) external onlyOwner { - address _oldEthGateway = ethGateway; - ethGateway = _newEthGateway; - - emit SetETHGateway(_oldEthGateway, _newEthGateway); - } - - /// @inheritdoc IL2GatewayRouter - function setDefaultERC20Gateway(address _newDefaultERC20Gateway) external onlyOwner { - address _oldDefaultERC20Gateway = defaultERC20Gateway; - defaultERC20Gateway = _newDefaultERC20Gateway; - - emit SetDefaultERC20Gateway(_oldDefaultERC20Gateway, _newDefaultERC20Gateway); - } - - /// @inheritdoc IL2GatewayRouter - function setERC20Gateway(address[] memory _tokens, address[] memory _gateways) external onlyOwner { - require(_tokens.length == _gateways.length, "length mismatch"); - - for (uint256 i = 0; i < _tokens.length; i++) { - address _oldGateway = ERC20Gateway[_tokens[i]]; - ERC20Gateway[_tokens[i]] = _gateways[i]; - - emit SetERC20Gateway(_tokens[i], _oldGateway, _gateways[i]); - } - } -} diff --git a/contracts/src/L2/gateways/L2StandardERC20Gateway.sol b/contracts/src/L2/gateways/L2StandardERC20Gateway.sol deleted file mode 100644 index 3b3455ffd..000000000 --- a/contracts/src/L2/gateways/L2StandardERC20Gateway.sol +++ /dev/null @@ -1,192 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {AddressUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol"; - -import {IL2ERC20Gateway, L2ERC20Gateway} from "./L2ERC20Gateway.sol"; -import {IL2ScrollMessenger} from "../IL2ScrollMessenger.sol"; -import {IL1ERC20Gateway} from "../../L1/gateways/IL1ERC20Gateway.sol"; -import {IScrollERC20Upgradeable} from "../../libraries/token/IScrollERC20Upgradeable.sol"; -import {ScrollStandardERC20} from "../../libraries/token/ScrollStandardERC20.sol"; -import {IScrollStandardERC20Factory} from "../../libraries/token/IScrollStandardERC20Factory.sol"; -import {ScrollGatewayBase} from "../../libraries/gateway/ScrollGatewayBase.sol"; - -/// @title L2StandardERC20Gateway -/// @notice The `L2StandardERC20Gateway` is used to withdraw standard ERC20 tokens on layer 2 and -/// finalize deposit the tokens from layer 1. -/// @dev The withdrawn ERC20 tokens will be burned directly. On finalizing deposit, the corresponding -/// token will be minted and transferred to the recipient. Any ERC20 that requires non-standard functionality -/// should use a separate gateway. -contract L2StandardERC20Gateway is L2ERC20Gateway { - using AddressUpgradeable for address; - - /************* - * Constants * - *************/ - - /// @notice The address of ScrollStandardERC20Factory. - address public immutable tokenFactory; - - /************* - * Variables * - *************/ - - /// @notice Mapping from l2 token address to l1 token address. - mapping(address => address) private tokenMapping; - - /// @dev The storage slot used as ScrollStandardERC20Factory contract, which is deprecated now. - address private __tokenFactory; - - /*************** - * Constructor * - ***************/ - - /// @notice Constructor for `L2StandardERC20Gateway` implementation contract. - /// - /// @param _counterpart The address of `L1StandardERC20Gateway` contract in L1. - /// @param _router The address of `L2GatewayRouter` contract in L2. - /// @param _messenger The address of `L2ScrollMessenger` contract in L2. - /// @param _tokenFactory The address of `ScrollStandardERC20Factory` contract in L2. - constructor( - address _counterpart, - address _router, - address _messenger, - address _tokenFactory - ) ScrollGatewayBase(_counterpart, _router, _messenger) { - if (_router == address(0) || _tokenFactory == address(0)) revert ErrorZeroAddress(); - - _disableInitializers(); - - tokenFactory = _tokenFactory; - } - - /// @notice Initialize the storage of L2StandardERC20Gateway. - /// - /// @dev The parameters `_counterpart`, `_router`, `_messenger` and `_tokenFactory` are no longer used. - /// - /// @param _counterpart The address of `L1StandardERC20Gateway` contract in L1. - /// @param _router The address of `L2GatewayRouter` contract in L2. - /// @param _messenger The address of `L2ScrollMessenger` contract in L2. - function initialize( - address _counterpart, - address _router, - address _messenger, - address /*_tokenFactory*/ - ) external initializer { - ScrollGatewayBase._initialize(_counterpart, _router, _messenger); - } - - /************************* - * Public View Functions * - *************************/ - - /// @inheritdoc IL2ERC20Gateway - function getL1ERC20Address(address _l2Token) external view override returns (address) { - return tokenMapping[_l2Token]; - } - - /// @inheritdoc IL2ERC20Gateway - function getL2ERC20Address(address _l1Token) public view override returns (address) { - return IScrollStandardERC20Factory(tokenFactory).computeL2TokenAddress(address(this), _l1Token); - } - - /***************************** - * Public Mutating Functions * - *****************************/ - - /// @inheritdoc IL2ERC20Gateway - function finalizeDepositERC20( - address _l1Token, - address _l2Token, - address _from, - address _to, - uint256 _amount, - bytes memory _data - ) external payable override onlyCallByCounterpart nonReentrant { - require(msg.value == 0, "nonzero msg.value"); - require(_l1Token != address(0), "token address cannot be 0"); - - { - // avoid stack too deep - address _expectedL2Token = IScrollStandardERC20Factory(tokenFactory).computeL2TokenAddress( - address(this), - _l1Token - ); - require(_l2Token == _expectedL2Token, "l2 token mismatch"); - } - - bool _hasMetadata; - (_hasMetadata, _data) = abi.decode(_data, (bool, bytes)); - - bytes memory _deployData; - bytes memory _callData; - - if (_hasMetadata) { - (_callData, _deployData) = abi.decode(_data, (bytes, bytes)); - } else { - require(tokenMapping[_l2Token] == _l1Token, "token mapping mismatch"); - _callData = _data; - } - - if (!_l2Token.isContract()) { - // first deposit, update mapping - tokenMapping[_l2Token] = _l1Token; - - _deployL2Token(_deployData, _l1Token); - } - - IScrollERC20Upgradeable(_l2Token).mint(_to, _amount); - - _doCallback(_to, _callData); - - emit FinalizeDepositERC20(_l1Token, _l2Token, _from, _to, _amount, _callData); - } - - /********************** - * Internal Functions * - **********************/ - - /// @inheritdoc L2ERC20Gateway - function _withdraw( - address _token, - address _to, - uint256 _amount, - bytes memory _data, - uint256 _gasLimit - ) internal virtual override nonReentrant { - require(_amount > 0, "withdraw zero amount"); - - // 1. Extract real sender if this call is from L2GatewayRouter. - address _from = _msgSender(); - if (router == _from) { - (_from, _data) = abi.decode(_data, (address, bytes)); - } - - address _l1Token = tokenMapping[_token]; - require(_l1Token != address(0), "no corresponding l1 token"); - - // 2. Burn token. - IScrollERC20Upgradeable(_token).burn(_from, _amount); - - // 3. Generate message passed to L1StandardERC20Gateway. - bytes memory _message = abi.encodeCall( - IL1ERC20Gateway.finalizeWithdrawERC20, - (_l1Token, _token, _from, _to, _amount, _data) - ); - - // 4. send message to L2ScrollMessenger - IL2ScrollMessenger(messenger).sendMessage{value: msg.value}(counterpart, 0, _message, _gasLimit); - - emit WithdrawERC20(_l1Token, _token, _from, _to, _amount, _data); - } - - function _deployL2Token(bytes memory _deployData, address _l1Token) internal { - address _l2Token = IScrollStandardERC20Factory(tokenFactory).deployL2Token(address(this), _l1Token); - (string memory _symbol, string memory _name, uint8 _decimals) = abi.decode( - _deployData, - (string, string, uint8) - ); - ScrollStandardERC20(_l2Token).initialize(_name, _symbol, _decimals, address(this), _l1Token); - } -} diff --git a/contracts/src/L2/gateways/L2WETHGateway.sol b/contracts/src/L2/gateways/L2WETHGateway.sol deleted file mode 100644 index a50a7b35b..000000000 --- a/contracts/src/L2/gateways/L2WETHGateway.sol +++ /dev/null @@ -1,163 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {IERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; -import {SafeERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol"; - -import {IL2ERC20Gateway, L2ERC20Gateway} from "./L2ERC20Gateway.sol"; -import {IL2ScrollMessenger} from "../IL2ScrollMessenger.sol"; -import {IWETH} from "../../interfaces/IWETH.sol"; -import {IL1ERC20Gateway} from "../../L1/gateways/IL1ERC20Gateway.sol"; -import {ScrollGatewayBase} from "../../libraries/gateway/ScrollGatewayBase.sol"; - -/// @title L2WETHGateway -/// @notice The `L2WETHGateway` contract is used to withdraw `WETH` token on layer 2 and -/// finalize deposit `WETH` from layer 1. -/// @dev The WETH tokens are not held in the gateway. It will first be unwrapped as Ether and -/// then the Ether will be sent to the `L2ScrollMessenger` contract. -/// On finalizing deposit, the Ether will be transferred from `L2ScrollMessenger`, then -/// wrapped as WETH and finally transfer to recipient. -contract L2WETHGateway is L2ERC20Gateway { - using SafeERC20Upgradeable for IERC20Upgradeable; - - /************* - * Constants * - *************/ - - /// @notice The address of L1 WETH address. - address public immutable l1WETH; - - /// @notice The address of L2 WETH address. - // solhint-disable-next-line var-name-mixedcase - address public immutable WETH; - - /*************** - * Constructor * - ***************/ - - /// @notice Constructor for `L2WETHGateway` implementation contract. - /// - /// @param _WETH The address of WETH in L2. - /// @param _l1WETH The address of WETH in L1. - /// @param _counterpart The address of `L1WETHGateway` contract in L1. - /// @param _router The address of `L2GatewayRouter` contract. - /// @param _messenger The address of `L2ScrollMessenger` contract. - constructor( - address _WETH, - address _l1WETH, - address _counterpart, - address _router, - address _messenger - ) ScrollGatewayBase(_counterpart, _router, _messenger) { - if (_WETH == address(0) || _l1WETH == address(0) || _router == address(0)) { - revert ErrorZeroAddress(); - } - - _disableInitializers(); - - WETH = _WETH; - l1WETH = _l1WETH; - } - - /// @notice Initialize the storage of `L2WETHGateway`. - /// - /// @dev The parameters `_counterpart`, `_router` and `_messenger` are no longer used. - /// - /// @param _counterpart The address of `L1WETHGateway` contract in L1. - /// @param _router The address of `L2GatewayRouter` contract in L2. - /// @param _messenger The address of `L2ScrollMessenger` contract in L2. - function initialize( - address _counterpart, - address _router, - address _messenger - ) external initializer { - ScrollGatewayBase._initialize(_counterpart, _router, _messenger); - } - - receive() external payable { - require(_msgSender() == WETH, "only WETH"); - } - - /************************* - * Public View Functions * - *************************/ - - /// @inheritdoc IL2ERC20Gateway - function getL1ERC20Address(address) external view override returns (address) { - return l1WETH; - } - - /// @inheritdoc IL2ERC20Gateway - function getL2ERC20Address(address) public view override returns (address) { - return WETH; - } - - /***************************** - * Public Mutating Functions * - *****************************/ - - /// @inheritdoc IL2ERC20Gateway - function finalizeDepositERC20( - address _l1Token, - address _l2Token, - address _from, - address _to, - uint256 _amount, - bytes calldata _data - ) external payable override onlyCallByCounterpart nonReentrant { - require(_l1Token == l1WETH, "l1 token not WETH"); - require(_l2Token == WETH, "l2 token not WETH"); - require(_amount == msg.value, "msg.value mismatch"); - - IWETH(_l2Token).deposit{value: _amount}(); - IERC20Upgradeable(_l2Token).safeTransfer(_to, _amount); - - _doCallback(_to, _data); - - emit FinalizeDepositERC20(_l1Token, _l2Token, _from, _to, _amount, _data); - } - - /********************** - * Internal Functions * - **********************/ - - /// @inheritdoc L2ERC20Gateway - function _withdraw( - address _token, - address _to, - uint256 _amount, - bytes memory _data, - uint256 _gasLimit - ) internal virtual override nonReentrant { - require(_amount > 0, "withdraw zero amount"); - require(_token == WETH, "only WETH is allowed"); - - // 1. Extract real sender if this call is from L1GatewayRouter. - address _from = _msgSender(); - if (router == _from) { - (_from, _data) = abi.decode(_data, (address, bytes)); - } - - // 2. Transfer token into this contract. - IERC20Upgradeable(_token).safeTransferFrom(_from, address(this), _amount); - IWETH(_token).withdraw(_amount); - - // 3. Generate message passed to L2StandardERC20Gateway. - address _l1WETH = l1WETH; - bytes memory _message = abi.encodeCall( - IL1ERC20Gateway.finalizeWithdrawERC20, - (_l1WETH, _token, _from, _to, _amount, _data) - ); - - // 4. Send message to L1ScrollMessenger. - IL2ScrollMessenger(messenger).sendMessage{value: _amount + msg.value}( - counterpart, - _amount, - _message, - _gasLimit - ); - - emit WithdrawERC20(_l1WETH, _token, _from, _to, _amount, _data); - } -} diff --git a/contracts/src/L2/gateways/usdc/L2USDCGateway.sol b/contracts/src/L2/gateways/usdc/L2USDCGateway.sol deleted file mode 100644 index d3408c837..000000000 --- a/contracts/src/L2/gateways/usdc/L2USDCGateway.sol +++ /dev/null @@ -1,200 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; -import {IERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; -import {SafeERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol"; - -import {IFiatToken} from "../../../interfaces/IFiatToken.sol"; -import {IUSDCDestinationBridge} from "../../../interfaces/IUSDCDestinationBridge.sol"; -import {IL1ERC20Gateway} from "../../../L1/gateways/IL1ERC20Gateway.sol"; -import {IL2ScrollMessenger} from "../../IL2ScrollMessenger.sol"; -import {IL2ERC20Gateway} from "../IL2ERC20Gateway.sol"; - -import {ScrollGatewayBase} from "../../../libraries/gateway/ScrollGatewayBase.sol"; -import {L2ERC20Gateway} from "../L2ERC20Gateway.sol"; - -/// @title L2USDCGateway -/// @notice The `L2USDCGateway` contract is used to withdraw `USDC` token on layer 2 and -/// finalize deposit `USDC` from layer 1. -contract L2USDCGateway is L2ERC20Gateway, IUSDCDestinationBridge { - using SafeERC20Upgradeable for IERC20Upgradeable; - - /************* - * Constants * - *************/ - - /// @notice The address of L1 USDC address. - address public immutable l1USDC; - - /// @notice The address of L2 USDC address. - address public immutable l2USDC; - - /************* - * Variables * - *************/ - - /// @notice The address of caller from Circle. - address public circleCaller; - - /// @notice The flag indicates whether USDC deposit is paused. - /// @dev This is not necessary to be set `true` since we will set `L1USDCGateway.depositPaused` first. - /// This is kept just in case and will be set after all pending messages are relayed. - bool public depositPaused; - - /// @notice The flag indicates whether USDC withdrawal is paused. - bool public withdrawPaused; - - /*************** - * Constructor * - ***************/ - - /// @notice Constructor for `L2USDCGateway` implementation contract. - /// - /// @param _l1USDC The address of USDC in L1. - /// @param _l2USDC The address of USDC in L2. - /// @param _counterpart The address of `L1USDCGateway` contract in L1. - /// @param _router The address of `L2GatewayRouter` contract in L2. - /// @param _messenger The address of `L2ScrollMessenger` contract in L2. - constructor( - address _l1USDC, - address _l2USDC, - address _counterpart, - address _router, - address _messenger - ) ScrollGatewayBase(_counterpart, _router, _messenger) { - if (_l1USDC == address(0) || _l2USDC == address(0) || _router == address(0)) { - revert ErrorZeroAddress(); - } - - _disableInitializers(); - - l1USDC = _l1USDC; - l2USDC = _l2USDC; - } - - /// @notice Initialize the storage of `L2USDCGateway`. - /// - /// @dev The parameters `_counterpart`, `_router` and `_messenger` are no longer used. - /// - /// @param _counterpart The address of `L1USDCGateway` contract in L1. - /// @param _router The address of `L2GatewayRouter` contract in L2. - /// @param _messenger The address of `L2ScrollMessenger` contract in L2. - function initialize( - address _counterpart, - address _router, - address _messenger - ) external initializer { - ScrollGatewayBase._initialize(_counterpart, _router, _messenger); - } - - /************************* - * Public View Functions * - *************************/ - - /// @inheritdoc IL2ERC20Gateway - function getL1ERC20Address(address) external view override returns (address) { - return l1USDC; - } - - /// @inheritdoc IL2ERC20Gateway - function getL2ERC20Address(address) public view override returns (address) { - return l2USDC; - } - - /***************************** - * Public Mutating Functions * - *****************************/ - - /// @inheritdoc IL2ERC20Gateway - function finalizeDepositERC20( - address _l1Token, - address _l2Token, - address _from, - address _to, - uint256 _amount, - bytes calldata _data - ) external payable override onlyCallByCounterpart nonReentrant { - require(msg.value == 0, "nonzero msg.value"); - require(_l1Token == l1USDC, "l1 token not USDC"); - require(_l2Token == l2USDC, "l2 token not USDC"); - require(!depositPaused, "deposit paused"); - - require(IFiatToken(_l2Token).mint(_to, _amount), "mint USDC failed"); - - // disable call for USDC - // _doCallback(_to, _data); - - emit FinalizeDepositERC20(_l1Token, _l2Token, _from, _to, _amount, _data); - } - - /******************************* - * Public Restricted Functions * - *******************************/ - - /// @inheritdoc IUSDCDestinationBridge - function transferUSDCRoles(address _owner) external { - require(_msgSender() == circleCaller, "only circle caller"); - - OwnableUpgradeable(l2USDC).transferOwnership(_owner); - } - - /// @notice Update the Circle EOA address. - /// @param _caller The address to update. - function updateCircleCaller(address _caller) external onlyOwner { - circleCaller = _caller; - } - - /// @notice Change the deposit pause status of this contract. - /// @param _paused The new status, `true` means paused and `false` means not paused. - function pauseDeposit(bool _paused) external onlyOwner { - depositPaused = _paused; - } - - /// @notice Change the withdraw pause status of this contract. - /// @param _paused The new status, `true` means paused and `false` means not paused. - function pauseWithdraw(bool _paused) external onlyOwner { - withdrawPaused = _paused; - } - - /********************** - * Internal Functions * - **********************/ - - /// @inheritdoc L2ERC20Gateway - function _withdraw( - address _token, - address _to, - uint256 _amount, - bytes memory _data, - uint256 _gasLimit - ) internal virtual override nonReentrant { - require(_amount > 0, "withdraw zero amount"); - require(_token == l2USDC, "only USDC is allowed"); - require(!withdrawPaused, "withdraw paused"); - - // 1. Extract real sender if this call is from L2GatewayRouter. - address _from = _msgSender(); - if (router == _from) { - (_from, _data) = abi.decode(_data, (address, bytes)); - } - require(_data.length == 0, "call is not allowed"); - - // 2. Transfer token into this contract. - IERC20Upgradeable(_token).safeTransferFrom(_from, address(this), _amount); - IFiatToken(_token).burn(_amount); - - // 3. Generate message passed to L1USDCGateway. - address _l1USDC = l1USDC; - bytes memory _message = abi.encodeCall( - IL1ERC20Gateway.finalizeWithdrawERC20, - (_l1USDC, _token, _from, _to, _amount, _data) - ); - - // 4. Send message to L2ScrollMessenger. - IL2ScrollMessenger(messenger).sendMessage{value: msg.value}(counterpart, 0, _message, _gasLimit); - - emit WithdrawERC20(_l1USDC, _token, _from, _to, _amount, _data); - } -} diff --git a/contracts/src/L2/gateways/usdc/draft-L2USDCGatewayCCTP.sol b/contracts/src/L2/gateways/usdc/draft-L2USDCGatewayCCTP.sol deleted file mode 100644 index 002f7bf20..000000000 --- a/contracts/src/L2/gateways/usdc/draft-L2USDCGatewayCCTP.sol +++ /dev/null @@ -1,163 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; -import {IERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; -import {SafeERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol"; - -import {ITokenMessenger} from "../../../interfaces/ITokenMessenger.sol"; -import {IL1ERC20Gateway} from "../../../L1/gateways/IL1ERC20Gateway.sol"; -import {IL2ScrollMessenger} from "../../IL2ScrollMessenger.sol"; -import {IL2ERC20Gateway} from "../IL2ERC20Gateway.sol"; - -import {CCTPGatewayBase} from "../../../libraries/gateway/CCTPGatewayBase.sol"; -import {ScrollGatewayBase} from "../../../libraries/gateway/ScrollGatewayBase.sol"; -import {L2ERC20Gateway} from "../L2ERC20Gateway.sol"; - -/// @title L2USDCGatewayCCTP -/// @notice The `L2USDCGatewayCCTP` contract is used to withdraw `USDC` token in layer 2 and -/// finalize deposit `USDC` from layer 1. -contract L2USDCGatewayCCTP is CCTPGatewayBase, L2ERC20Gateway { - using SafeERC20Upgradeable for IERC20Upgradeable; - - /*************** - * Constructor * - ***************/ - - constructor( - address _l1USDC, - address _l2USDC, - uint32 _destinationDomain, - address _counterpart, - address _router, - address _messenger - ) CCTPGatewayBase(_l1USDC, _l2USDC, _destinationDomain) ScrollGatewayBase(_counterpart, _router, _messenger) { - if (_router == address(0)) revert ErrorZeroAddress(); - - _disableInitializers(); - } - - /// @notice Initialize the storage of L2USDCGatewayCCTP. - /// - /// @dev The parameters `_counterpart`, `_router`, `_messenger` are no longer used. - /// - /// @param _counterpart The address of L1USDCGatewayCCTP in L1. - /// @param _router The address of L2GatewayRouter. - /// @param _messenger The address of L2ScrollMessenger. - /// @param _cctpMessenger The address of TokenMessenger in local domain. - /// @param _cctpTransmitter The address of MessageTransmitter in local domain. - function initialize( - address _counterpart, - address _router, - address _messenger, - address _cctpMessenger, - address _cctpTransmitter - ) external initializer { - ScrollGatewayBase._initialize(_counterpart, _router, _messenger); - CCTPGatewayBase._initialize(_cctpMessenger, _cctpTransmitter); - } - - /************************* - * Public View Functions * - *************************/ - - /// @inheritdoc IL2ERC20Gateway - function getL1ERC20Address(address) external view override returns (address) { - return l1USDC; - } - - /// @inheritdoc IL2ERC20Gateway - function getL2ERC20Address(address) public view override returns (address) { - return l2USDC; - } - - /***************************** - * Public Mutating Functions * - *****************************/ - - /// @inheritdoc IL2ERC20Gateway - /// @dev The function will not mint the USDC, users need to call `claimUSDC` after this function is done. - function finalizeDepositERC20( - address _l1Token, - address _l2Token, - address _from, - address _to, - uint256 _amount, - bytes memory _data - ) external payable override onlyCallByCounterpart { - require(msg.value == 0, "nonzero msg.value"); - require(_l1Token == l1USDC, "l1 token not USDC"); - require(_l2Token == l2USDC, "l2 token not USDC"); - - uint256 _nonce; - (_nonce, _data) = abi.decode(_data, (uint256, bytes)); - require(status[_nonce] == CCTPMessageStatus.None, "message relayed"); - status[_nonce] = CCTPMessageStatus.Pending; - - emit FinalizeDepositERC20(_l1Token, _l2Token, _from, _to, _amount, _data); - } - - /******************************* - * Public Restricted Functions * - *******************************/ - - /// @notice Update the CCTP contract addresses. - /// @param _messenger The address of TokenMessenger in local domain. - /// @param _transmitter The address of MessageTransmitter in local domain. - function updateCCTPContracts(address _messenger, address _transmitter) external onlyOwner { - cctpMessenger = _messenger; - cctpTransmitter = _transmitter; - } - - /********************** - * Internal Functions * - **********************/ - - /// @inheritdoc L2ERC20Gateway - function _withdraw( - address _token, - address _to, - uint256 _amount, - bytes memory _data, - uint256 _gasLimit - ) internal virtual override { - require(_amount > 0, "withdraw zero amount"); - require(_token == l2USDC, "only USDC is allowed"); - - // 1. Extract real sender if this call is from L1GatewayRouter. - address _from = _msgSender(); - if (router == _from) { - (_from, _data) = abi.decode(_data, (address, bytes)); - } - - // 2. Transfer token into this contract. - IERC20Upgradeable(_token).safeTransferFrom(_from, address(this), _amount); - - // 3. Burn token through CCTP TokenMessenger - uint256 _nonce = ITokenMessenger(cctpMessenger).depositForBurnWithCaller( - _amount, - destinationDomain, - bytes32(uint256(uint160(_to))), - address(this), - bytes32(uint256(uint160(counterpart))) - ); - - // 4. Generate message passed to L1USDCGateway. - address _l1USDC = l1USDC; - bytes memory _message = abi.encodeWithSelector( - IL1ERC20Gateway.finalizeWithdrawERC20.selector, - _l1USDC, - _token, - _from, - _to, - _amount, - abi.encode(_nonce, _data) - ); - - // 4. Send message to L1ScrollMessenger. - IL2ScrollMessenger(messenger).sendMessage{value: msg.value}(counterpart, 0, _message, _gasLimit); - - emit WithdrawERC20(_l1USDC, _token, _from, _to, _amount, _data); - } -} diff --git a/contracts/src/L2/predeploys/IL1BlockContainer.sol b/contracts/src/L2/predeploys/IL1BlockContainer.sol deleted file mode 100644 index aafee8cd5..000000000 --- a/contracts/src/L2/predeploys/IL1BlockContainer.sol +++ /dev/null @@ -1,63 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.24; - -interface IL1BlockContainer { - /********** - * Events * - **********/ - - /// @notice Emitted when a block is imported. - /// @param blockHash The hash of the imported block. - /// @param blockHeight The height of the imported block. - /// @param blockTimestamp The timestamp of the imported block. - /// @param baseFee The base fee of the imported block. - /// @param stateRoot The state root of the imported block. - event ImportBlock( - bytes32 indexed blockHash, - uint256 blockHeight, - uint256 blockTimestamp, - uint256 baseFee, - bytes32 stateRoot - ); - - /************************* - * Public View Functions * - *************************/ - - /// @notice Return the latest imported block hash - function latestBlockHash() external view returns (bytes32); - - /// @notice Return the latest imported L1 base fee - function latestBaseFee() external view returns (uint256); - - /// @notice Return the latest imported block number - function latestBlockNumber() external view returns (uint256); - - /// @notice Return the latest imported block timestamp - function latestBlockTimestamp() external view returns (uint256); - - /// @notice Return the state root of given block. - /// @param blockHash The block hash to query. - /// @return stateRoot The state root of the block. - function getStateRoot(bytes32 blockHash) external view returns (bytes32 stateRoot); - - /// @notice Return the block timestamp of given block. - /// @param blockHash The block hash to query. - /// @return timestamp The corresponding block timestamp. - function getBlockTimestamp(bytes32 blockHash) external view returns (uint256 timestamp); - - /***************************** - * Public Mutating Functions * - *****************************/ - - /// @notice Import L1 block header to this contract. - /// @param blockHash The hash of block. - /// @param blockHeaderRLP The RLP encoding of L1 block. - /// @param updateGasPriceOracle Whether to update gas price oracle. - function importBlockHeader( - bytes32 blockHash, - bytes calldata blockHeaderRLP, - bool updateGasPriceOracle - ) external; -} diff --git a/contracts/src/L2/predeploys/IL1GasPriceOracle.sol b/contracts/src/L2/predeploys/IL1GasPriceOracle.sol deleted file mode 100644 index 850a178a6..000000000 --- a/contracts/src/L2/predeploys/IL1GasPriceOracle.sol +++ /dev/null @@ -1,82 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.24; - -interface IL1GasPriceOracle { - /********** - * Events * - **********/ - - /// @notice Emitted when current fee overhead is updated. - /// @param overhead The current fee overhead updated. - event OverheadUpdated(uint256 overhead); - - /// @notice Emitted when current fee scalar is updated. - /// @param scalar The current fee scalar updated. - event ScalarUpdated(uint256 scalar); - - /// @notice Emitted when current commit fee scalar is updated. - /// @param scalar The current commit fee scalar updated. - event CommitScalarUpdated(uint256 scalar); - - /// @notice Emitted when current blob fee scalar is updated. - /// @param scalar The current blob fee scalar updated. - event BlobScalarUpdated(uint256 scalar); - - /// @notice Emitted when current l1 base fee is updated. - /// @param l1BaseFee The current l1 base fee updated. - event L1BaseFeeUpdated(uint256 l1BaseFee); - - /// @notice Emitted when current l1 blob base fee is updated. - /// @param l1BlobBaseFee The current l1 blob base fee updated. - event L1BlobBaseFeeUpdated(uint256 l1BlobBaseFee); - - /************************* - * Public View Functions * - *************************/ - - /// @notice Return the current l1 fee overhead. - function overhead() external view returns (uint256); - - /// @notice Return the current l1 fee scalar before Curie fork. - function scalar() external view returns (uint256); - - /// @notice Return the current l1 commit fee scalar. - function commitScalar() external view returns (uint256); - - /// @notice Return the current l1 blob fee scalar. - function blobScalar() external view returns (uint256); - - /// @notice Return the latest known l1 base fee. - function l1BaseFee() external view returns (uint256); - - /// @notice Return the latest known l1 blob base fee. - function l1BlobBaseFee() external view returns (uint256); - - /// @notice Computes the L1 portion of the fee based on the size of the rlp encoded input - /// transaction, the current L1 base fee, and the various dynamic parameters. - /// @param data Signed fully RLP-encoded transaction to get the L1 fee for. - /// @return L1 fee that should be paid for the tx - function getL1Fee(bytes memory data) external view returns (uint256); - - /// @notice Computes the amount of L1 gas used for a transaction. Adds the overhead which - /// represents the per-transaction gas overhead of posting the transaction and state - /// roots to L1. Adds 74 bytes of padding to account for the fact that the input does - /// not have a signature. - /// @param data Signed fully RLP-encoded transaction to get the L1 gas for. - /// @return Amount of L1 gas used to publish the transaction. - function getL1GasUsed(bytes memory data) external view returns (uint256); - - /***************************** - * Public Mutating Functions * - *****************************/ - - /// @notice Allows whitelisted caller to modify the l1 base fee. - /// @param _l1BaseFee New l1 base fee. - function setL1BaseFee(uint256 _l1BaseFee) external; - - /// @notice Allows whitelisted caller to modify the l1 base fee. - /// @param _l1BaseFee New l1 base fee. - /// @param _l1BlobBaseFee New l1 blob base fee. - function setL1BaseFeeAndBlobBaseFee(uint256 _l1BaseFee, uint256 _l1BlobBaseFee) external; -} diff --git a/contracts/src/L2/predeploys/L1BlockContainer.sol b/contracts/src/L2/predeploys/L1BlockContainer.sol deleted file mode 100644 index 054a7dff1..000000000 --- a/contracts/src/L2/predeploys/L1BlockContainer.sol +++ /dev/null @@ -1,305 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {IL1BlockContainer} from "./IL1BlockContainer.sol"; -import {IL1GasPriceOracle} from "./IL1GasPriceOracle.sol"; - -import {OwnableBase} from "../../libraries/common/OwnableBase.sol"; -import {IWhitelist} from "../../libraries/common/IWhitelist.sol"; -import {ScrollPredeploy} from "../../libraries/constants/ScrollPredeploy.sol"; - -/// @title L1BlockContainer -/// @notice This contract will maintain the list of blocks proposed in L1. -contract L1BlockContainer is OwnableBase, IL1BlockContainer { - /********** - * Events * - **********/ - - /// @notice Emitted when owner updates whitelist contract. - /// @param _oldWhitelist The address of old whitelist contract. - /// @param _newWhitelist The address of new whitelist contract. - event UpdateWhitelist(address _oldWhitelist, address _newWhitelist); - - /*********** - * Structs * - ***********/ - - /// @dev Compiler will pack this into single `uint256`. - struct BlockMetadata { - // The block height. - uint64 height; - // The block timestamp. - uint64 timestamp; - // The base fee in the block. - uint128 baseFee; - } - - /************* - * Variables * - *************/ - - /// @notice The address of whitelist contract. - IWhitelist public whitelist; - - /// @inheritdoc IL1BlockContainer - bytes32 public override latestBlockHash; - - /// @notice Mapping from block hash to corresponding state root. - mapping(bytes32 => bytes32) public stateRoot; - - /// @notice Mapping from block hash to corresponding block metadata, - /// including timestamp and height. - mapping(bytes32 => BlockMetadata) public metadata; - - /*************** - * Constructor * - ***************/ - - constructor(address _owner) { - _transferOwnership(_owner); - } - - function initialize( - bytes32 _startBlockHash, - uint64 _startBlockHeight, - uint64 _startBlockTimestamp, - uint128 _startBlockBaseFee, - bytes32 _startStateRoot - ) external onlyOwner { - require(latestBlockHash == bytes32(0), "already initialized"); - - latestBlockHash = _startBlockHash; - stateRoot[_startBlockHash] = _startStateRoot; - metadata[_startBlockHash] = BlockMetadata(_startBlockHeight, _startBlockTimestamp, _startBlockBaseFee); - - emit ImportBlock(_startBlockHash, _startBlockHeight, _startBlockTimestamp, _startBlockBaseFee, _startStateRoot); - } - - /************************* - * Public View Functions * - *************************/ - - /// @inheritdoc IL1BlockContainer - function latestBaseFee() external view override returns (uint256) { - return metadata[latestBlockHash].baseFee; - } - - /// @inheritdoc IL1BlockContainer - function latestBlockNumber() external view override returns (uint256) { - return metadata[latestBlockHash].height; - } - - /// @inheritdoc IL1BlockContainer - function latestBlockTimestamp() external view override returns (uint256) { - return metadata[latestBlockHash].timestamp; - } - - /// @inheritdoc IL1BlockContainer - function getStateRoot(bytes32 _blockHash) external view returns (bytes32) { - return stateRoot[_blockHash]; - } - - /// @inheritdoc IL1BlockContainer - function getBlockTimestamp(bytes32 _blockHash) external view returns (uint256) { - return metadata[_blockHash].timestamp; - } - - /***************************** - * Public Mutating Functions * - *****************************/ - - /// @inheritdoc IL1BlockContainer - function importBlockHeader( - bytes32 _blockHash, - bytes calldata _blockHeaderRLP, - bool _updateGasPriceOracle - ) external { - require(whitelist.isSenderAllowed(msg.sender), "Not whitelisted sender"); - - // The encoding order in block header is - // 1. ParentHash: 32 bytes - // 2. UncleHash: 32 bytes - // 3. Coinbase: 20 bytes - // 4. StateRoot: 32 bytes - // 5. TransactionsRoot: 32 bytes - // 6. ReceiptsRoot: 32 bytes - // 7. LogsBloom: 256 bytes - // 8. Difficulty: uint - // 9. BlockHeight: uint - // 10. GasLimit: uint64 - // 11. GasUsed: uint64 - // 12. BlockTimestamp: uint64 - // 13. ExtraData: several bytes - // 14. MixHash: 32 bytes - // 15. BlockNonce: 8 bytes - // 16. BaseFee: uint // optional - bytes32 _parentHash; - bytes32 _stateRoot; - uint64 _height; - uint64 _timestamp; - uint128 _baseFee; - - assembly { - // reverts with error `msg`. - // make sure the length of error string <= 32 - function revertWith(msg) { - // keccak("Error(string)") - mstore(0x00, shl(224, 0x08c379a0)) - mstore(0x04, 0x20) // str.offset - mstore(0x44, msg) - let msgLen - for { - - } msg { - - } { - msg := shl(8, msg) - msgLen := add(msgLen, 1) - } - mstore(0x24, msgLen) // str.length - revert(0x00, 0x64) - } - // reverts with `msg` when condition is not matched. - // make sure the length of error string <= 32 - function require(cond, msg) { - if iszero(cond) { - revertWith(msg) - } - } - // returns the calldata offset of the value and the length in bytes - // for the RLP encoded data item at `ptr`. used in `decodeFlat` - function decodeValue(ptr) -> dataLen, valueOffset { - let b0 := byte(0, calldataload(ptr)) - - // 0x00 - 0x7f, single byte - if lt(b0, 0x80) { - // for a single byte whose value is in the [0x00, 0x7f] range, - // that byte is its own RLP encoding. - dataLen := 1 - valueOffset := ptr - leave - } - - // 0x80 - 0xb7, short string/bytes, length <= 55 - if lt(b0, 0xb8) { - // the RLP encoding consists of a single byte with value 0x80 - // plus the length of the string followed by the string. - dataLen := sub(b0, 0x80) - valueOffset := add(ptr, 1) - leave - } - - // 0xb8 - 0xbf, long string/bytes, length > 55 - if lt(b0, 0xc0) { - // the RLP encoding consists of a single byte with value 0xb7 - // plus the length in bytes of the length of the string in binary form, - // followed by the length of the string, followed by the string. - let lengthBytes := sub(b0, 0xb7) - if gt(lengthBytes, 4) { - invalid() - } - - // load the extended length - valueOffset := add(ptr, 1) - let extendedLen := calldataload(valueOffset) - let bits := sub(256, mul(lengthBytes, 8)) - extendedLen := shr(bits, extendedLen) - - dataLen := extendedLen - valueOffset := add(valueOffset, lengthBytes) - leave - } - - revertWith("Not value") - } - - let ptr := _blockHeaderRLP.offset - let headerPayloadLength - { - let b0 := byte(0, calldataload(ptr)) - // the input should be a long list - if lt(b0, 0xf8) { - invalid() - } - let lengthBytes := sub(b0, 0xf7) - if gt(lengthBytes, 32) { - invalid() - } - // load the extended length - ptr := add(ptr, 1) - headerPayloadLength := calldataload(ptr) - let bits := sub(256, mul(lengthBytes, 8)) - // compute payload length: extended length + length bytes + 1 - headerPayloadLength := shr(bits, headerPayloadLength) - headerPayloadLength := add(headerPayloadLength, lengthBytes) - headerPayloadLength := add(headerPayloadLength, 1) - ptr := add(ptr, lengthBytes) - } - - let memPtr := mload(0x40) - calldatacopy(memPtr, _blockHeaderRLP.offset, headerPayloadLength) - let _computedBlockHash := keccak256(memPtr, headerPayloadLength) - require(eq(_blockHash, _computedBlockHash), "Block hash mismatch") - - // load 16 values - for { - let i := 0 - } lt(i, 16) { - i := add(i, 1) - } { - let len, offset := decodeValue(ptr) - // the value we care must have at most 32 bytes - if lt(len, 33) { - let bits := mul(sub(32, len), 8) - let value := calldataload(offset) - value := shr(bits, value) - mstore(memPtr, value) - } - memPtr := add(memPtr, 0x20) - ptr := add(len, offset) - } - require(eq(ptr, add(_blockHeaderRLP.offset, _blockHeaderRLP.length)), "Header RLP length mismatch") - - memPtr := mload(0x40) - // load parent hash, 1-st entry - _parentHash := mload(memPtr) - // load state root, 4-th entry - _stateRoot := mload(add(memPtr, 0x60)) - // load block height, 9-th entry - _height := mload(add(memPtr, 0x100)) - // load block timestamp, 12-th entry - _timestamp := mload(add(memPtr, 0x160)) - // load base fee, 16-th entry - _baseFee := mload(add(memPtr, 0x1e0)) - } - require(stateRoot[_parentHash] != bytes32(0), "Parent not imported"); - BlockMetadata memory _parentMetadata = metadata[_parentHash]; - require(_parentMetadata.height + 1 == _height, "Block height mismatch"); - require(_parentMetadata.timestamp <= _timestamp, "Parent block has larger timestamp"); - - latestBlockHash = _blockHash; - stateRoot[_blockHash] = _stateRoot; - metadata[_blockHash] = BlockMetadata(_height, _timestamp, _baseFee); - - emit ImportBlock(_blockHash, _height, _timestamp, _baseFee, _stateRoot); - - if (_updateGasPriceOracle) { - IL1GasPriceOracle(ScrollPredeploy.L1_GAS_PRICE_ORACLE).setL1BaseFee(_baseFee); - } - } - - /************************ - * Restricted Functions * - ************************/ - - /// @notice Update whitelist contract. - /// @dev This function can only called by contract owner. - /// @param _newWhitelist The address of new whitelist contract. - function updateWhitelist(address _newWhitelist) external onlyOwner { - address _oldWhitelist = address(whitelist); - - whitelist = IWhitelist(_newWhitelist); - emit UpdateWhitelist(_oldWhitelist, _newWhitelist); - } -} diff --git a/contracts/src/L2/predeploys/L1GasPriceOracle.sol b/contracts/src/L2/predeploys/L1GasPriceOracle.sol deleted file mode 100644 index fe3c37e4e..000000000 --- a/contracts/src/L2/predeploys/L1GasPriceOracle.sol +++ /dev/null @@ -1,266 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {OwnableBase} from "../../libraries/common/OwnableBase.sol"; -import {IWhitelist} from "../../libraries/common/IWhitelist.sol"; - -import {IL1GasPriceOracle} from "./IL1GasPriceOracle.sol"; - -contract L1GasPriceOracle is OwnableBase, IL1GasPriceOracle { - /********** - * Events * - **********/ - - /// @notice Emitted when owner updates whitelist contract. - /// @param _oldWhitelist The address of old whitelist contract. - /// @param _newWhitelist The address of new whitelist contract. - event UpdateWhitelist(address _oldWhitelist, address _newWhitelist); - - /********** - * Errors * - **********/ - - /// @dev Thrown when the blob fee scalar exceed `MAX_BLOB_SCALAR`. - error ErrExceedMaxBlobScalar(); - - /// @dev Thrown when the commit fee scalar exceed `MAX_COMMIT_SCALAR`. - error ErrExceedMaxCommitScalar(); - - /// @dev Thrown when the l1 fee overhead exceed `MAX_OVERHEAD`. - error ErrExceedMaxOverhead(); - - /// @dev Thrown when the l1 fee scalar exceed `MAX_SCALAR`. - error ErrExceedMaxScalar(); - - /// @dev Thrown when the caller is not whitelisted. - error ErrCallerNotWhitelisted(); - - /// @dev Thrown when we enable Curie fork after Curie fork. - error ErrAlreadyInCurieFork(); - - /************* - * Constants * - *************/ - - /// @dev The precision used in the scalar. - uint256 private constant PRECISION = 1e9; - - /// @dev The maximum possible l1 fee overhead. - /// Computed based on current l1 block gas limit. - uint256 private constant MAX_OVERHEAD = 30000000 / 16; - - /// @dev The maximum possible l1 fee scale before Curie. - /// x1000 should be enough. - uint256 private constant MAX_SCALAR = 1000 * PRECISION; - - /// @dev The maximum possible l1 commit fee scalar after Curie. - /// We derive the commit scalar by - /// ``` - /// commit_scalar = commit_gas_per_tx * fluctuation_multiplier * 1e9 - /// ``` - /// So, the value should not exceed 10^9 * 1e9 normally. - uint256 private constant MAX_COMMIT_SCALAR = 10 ** 9 * PRECISION; - - /// @dev The maximum possible l1 blob fee scalar after Curie. - /// We derive the blob scalar by - /// ``` - /// blob_scalar = fluctuation_multiplier / compression_ratio / blob_util_ratio * 1e9 - /// ``` - /// So, the value should not exceed 10^9 * 1e9 normally. - uint256 private constant MAX_BLOB_SCALAR = 10 ** 9 * PRECISION; - - /************* - * Variables * - *************/ - - /// @inheritdoc IL1GasPriceOracle - uint256 public l1BaseFee; - - /// @inheritdoc IL1GasPriceOracle - uint256 public override overhead; - - /// @inheritdoc IL1GasPriceOracle - uint256 public override scalar; - - /// @notice The address of whitelist contract. - IWhitelist public whitelist; - - /// @inheritdoc IL1GasPriceOracle - uint256 public override l1BlobBaseFee; - - /// @inheritdoc IL1GasPriceOracle - uint256 public override commitScalar; - - /// @inheritdoc IL1GasPriceOracle - uint256 public override blobScalar; - - /// @notice Indicates whether the network has gone through the Curie upgrade. - bool public isCurie; - - /************* - * Modifiers * - *************/ - - modifier onlyWhitelistedSender() { - if (!whitelist.isSenderAllowed(msg.sender)) revert ErrCallerNotWhitelisted(); - _; - } - - /*************** - * Constructor * - ***************/ - - constructor(address _owner) { - _transferOwnership(_owner); - } - - /************************* - * Public View Functions * - *************************/ - - /// @inheritdoc IL1GasPriceOracle - function getL1Fee(bytes memory _data) external view override returns (uint256) { - if (isCurie) { - return _getL1FeeCurie(_data); - } else { - return _getL1FeeBeforeCurie(_data); - } - } - - /// @inheritdoc IL1GasPriceOracle - function getL1GasUsed(bytes memory _data) public view override returns (uint256) { - if (isCurie) { - // It is near zero since we put all transactions to blob. - return 0; - } else { - return _getL1GasUsedBeforeCurie(_data); - } - } - - /***************************** - * Public Mutating Functions * - *****************************/ - - /// @inheritdoc IL1GasPriceOracle - function setL1BaseFee(uint256 _l1BaseFee) external override onlyWhitelistedSender { - l1BaseFee = _l1BaseFee; - - emit L1BaseFeeUpdated(_l1BaseFee); - } - - /// @inheritdoc IL1GasPriceOracle - function setL1BaseFeeAndBlobBaseFee( - uint256 _l1BaseFee, - uint256 _l1BlobBaseFee - ) external override onlyWhitelistedSender { - l1BaseFee = _l1BaseFee; - l1BlobBaseFee = _l1BlobBaseFee; - - emit L1BaseFeeUpdated(_l1BaseFee); - emit L1BlobBaseFeeUpdated(_l1BlobBaseFee); - } - - /************************ - * Restricted Functions * - ************************/ - - /// @notice Allows the owner to modify the overhead. - /// @param _overhead New overhead - function setOverhead(uint256 _overhead) external onlyOwner { - if (_overhead > MAX_OVERHEAD) revert ErrExceedMaxOverhead(); - - overhead = _overhead; - emit OverheadUpdated(_overhead); - } - - /// Allows the owner to modify the scalar. - /// @param _scalar New scalar - function setScalar(uint256 _scalar) external onlyOwner { - if (_scalar > MAX_SCALAR) revert ErrExceedMaxScalar(); - - scalar = _scalar; - emit ScalarUpdated(_scalar); - } - - /// Allows the owner to modify the commit scalar. - /// @param _scalar New scalar - function setCommitScalar(uint256 _scalar) external onlyOwner { - if (_scalar > MAX_COMMIT_SCALAR) revert ErrExceedMaxCommitScalar(); - - commitScalar = _scalar; - emit CommitScalarUpdated(_scalar); - } - - /// Allows the owner to modify the blob scalar. - /// @param _scalar New scalar - function setBlobScalar(uint256 _scalar) external onlyOwner { - if (_scalar > MAX_BLOB_SCALAR) revert ErrExceedMaxBlobScalar(); - - blobScalar = _scalar; - emit BlobScalarUpdated(_scalar); - } - - /// @notice Update whitelist contract. - /// @dev This function can only called by contract owner. - /// @param _newWhitelist The address of new whitelist contract. - function updateWhitelist(address _newWhitelist) external onlyOwner { - address _oldWhitelist = address(whitelist); - - whitelist = IWhitelist(_newWhitelist); - emit UpdateWhitelist(_oldWhitelist, _newWhitelist); - } - - /// @notice Enable the Curie fork (callable by contract owner). - /// - /// @dev Since this is a predeploy contract, we will directly set the slot while hard fork - /// to avoid external owner operations. - /// The reason that we keep this function is for easy unit testing. - function enableCurie() external onlyOwner { - if (isCurie) revert ErrAlreadyInCurieFork(); - isCurie = true; - } - - /********************** - * Internal Functions * - **********************/ - - /// @dev Internal function to computes the amount of L1 gas used for a transaction before Curie fork. - /// The `_data` is the RLP-encoded transaction with signature. And we also reserve additional - /// 4 bytes in the non-zero bytes to store the number of bytes in the RLP-encoded transaction. - /// @param _data Signed fully RLP-encoded transaction to get the L1 gas for. - /// @return Amount of L1 gas used to publish the transaction. - function _getL1GasUsedBeforeCurie(bytes memory _data) private view returns (uint256) { - uint256 _total = 0; - uint256 _length = _data.length; - unchecked { - for (uint256 i = 0; i < _length; i++) { - if (_data[i] == 0) { - _total += 4; - } else { - _total += 16; - } - } - return _total + overhead + (4 * 16); - } - } - - /// @dev Internal function to compute the L1 portion of the fee based on the size of the rlp encoded input - /// transaction, the current L1 base fee, and the various dynamic parameters, before Curie fork. - /// @param _data Signed fully RLP-encoded transaction to get the L1 fee for. - /// @return L1 fee that should be paid for the tx - function _getL1FeeBeforeCurie(bytes memory _data) private view returns (uint256) { - uint256 _l1GasUsed = _getL1GasUsedBeforeCurie(_data); - uint256 _l1Fee = _l1GasUsed * l1BaseFee; - return (_l1Fee * scalar) / PRECISION; - } - - /// @dev Internal function to compute the L1 portion of the fee based on the size of the rlp encoded input - /// transaction, the current L1 base fee, and the various dynamic parameters, after Curie fork. - /// @param _data Signed fully RLP-encoded transaction to get the L1 fee for. - /// @return L1 fee that should be paid for the tx - function _getL1FeeCurie(bytes memory _data) private view returns (uint256) { - // We have bounded the value of `commitScalar` and `blobScalar`, the whole expression won't overflow. - return (commitScalar * l1BaseFee + blobScalar * _data.length * l1BlobBaseFee) / PRECISION; - } -} diff --git a/contracts/src/L2/predeploys/L2MessageQueue.sol b/contracts/src/L2/predeploys/L2MessageQueue.sol deleted file mode 100644 index 997ff446a..000000000 --- a/contracts/src/L2/predeploys/L2MessageQueue.sol +++ /dev/null @@ -1,66 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {AppendOnlyMerkleTree} from "../../libraries/common/AppendOnlyMerkleTree.sol"; -import {OwnableBase} from "../../libraries/common/OwnableBase.sol"; - -/// @title L2MessageQueue -/// @notice The original idea is from Optimism, see [OVM_L2ToL1MessagePasser](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts/contracts/L2/predeploys/OVM_L2ToL1MessagePasser.sol). -/// The L2 to L1 Message Passer is a utility contract which facilitate an L1 proof of the -/// of a message on L2. The L1 Cross Domain Messenger performs this proof in its -/// _verifyStorageProof function, which verifies the existence of the transaction hash in this -/// contract's `sentMessages` mapping. -contract L2MessageQueue is AppendOnlyMerkleTree, OwnableBase { - /********** - * Events * - **********/ - - /// @notice Emitted when a new message is added to the merkle tree. - /// @param index The index of the corresponding message. - /// @param messageHash The hash of the corresponding message. - event AppendMessage(uint256 index, bytes32 messageHash); - - /************* - * Variables * - *************/ - - /// @notice The address of L2ScrollMessenger contract. - address public messenger; - - /*************** - * Constructor * - ***************/ - - constructor(address _owner) { - _transferOwnership(_owner); - } - - /// @notice Initialize the state of `L2MessageQueue` - /// @dev You are not allowed to initialize when there are some messages appended. - /// @param _messenger The address of messenger to update. - function initialize(address _messenger) external onlyOwner { - require(nextMessageIndex == 0, "cannot initialize"); - - _initializeMerkleTree(); - - messenger = _messenger; - } - - /***************************** - * Public Mutating Functions * - *****************************/ - - /// @notice record the message to merkle tree and compute the new root. - /// @param _messageHash The hash of the new added message. - function appendMessage(bytes32 _messageHash) external returns (bytes32) { - require(msg.sender == messenger, "only messenger"); - - (uint256 _currentNonce, bytes32 _currentRoot) = _appendMessageHash(_messageHash); - - // We can use the event to compute the merkle tree locally. - emit AppendMessage(_currentNonce, _messageHash); - - return _currentRoot; - } -} diff --git a/contracts/src/L2/predeploys/L2TxFeeVault.sol b/contracts/src/L2/predeploys/L2TxFeeVault.sol deleted file mode 100644 index 20248eb76..000000000 --- a/contracts/src/L2/predeploys/L2TxFeeVault.sol +++ /dev/null @@ -1,167 +0,0 @@ -// SPDX-License-Identifier: MIT - -// MIT License - -// Copyright (c) 2022 Optimism -// Copyright (c) 2022 Scroll - -// 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.8.24; - -import {IL2ScrollMessenger} from "../IL2ScrollMessenger.sol"; -import {OwnableBase} from "../../libraries/common/OwnableBase.sol"; - -// solhint-disable no-empty-blocks -// solhint-disable reason-string - -/// @title L2TxFeeVault -/// @notice The L2TxFeeVault contract contains the logic for the vault contracts -/// used to hold fee revenue generated by the L2 system. -contract L2TxFeeVault is OwnableBase { - /********** - * Events * - **********/ - - /// @notice Emits each time that a withdrawal occurs. - /// - /// @param value Amount that was withdrawn (in wei). - /// @param to Address that the funds were sent to. - /// @param from Address that triggered the withdrawal. - event Withdrawal(uint256 value, address to, address from); - - /// @notice Emits each time the owner updates the address of `messenger`. - /// @param oldMessenger The address of old messenger. - /// @param newMessenger The address of new messenger. - event UpdateMessenger(address indexed oldMessenger, address indexed newMessenger); - - /// @notice Emits each time the owner updates the address of `recipient`. - /// @param oldRecipient The address of old recipient. - /// @param newRecipient The address of new recipient. - event UpdateRecipient(address indexed oldRecipient, address indexed newRecipient); - - /// @notice Emits each time the owner updates the value of `minWithdrawAmount`. - /// @param oldMinWithdrawAmount The value of old `minWithdrawAmount`. - /// @param newMinWithdrawAmount The value of new `minWithdrawAmount`. - event UpdateMinWithdrawAmount(uint256 oldMinWithdrawAmount, uint256 newMinWithdrawAmount); - - /************* - * Variables * - *************/ - - /// @notice Minimum balance before a withdrawal can be triggered. - uint256 public minWithdrawAmount; - - /// @notice Scroll L2 messenger address. - address public messenger; - - /// @notice Wallet that will receive the fees on L1. - address public recipient; - - /// @notice Total amount of wei processed by the contract. - uint256 public totalProcessed; - - /*************** - * Constructor * - ***************/ - - /// @param _owner The owner of the contract. - /// @param _recipient Wallet that will receive the fees on L1. - /// @param _minWithdrawalAmount Minimum balance before a withdrawal can be triggered. - constructor( - address _owner, - address _recipient, - uint256 _minWithdrawalAmount - ) { - _transferOwnership(_owner); - - minWithdrawAmount = _minWithdrawalAmount; - recipient = _recipient; - } - - /***************************** - * Public Mutating Functions * - *****************************/ - - /// @notice Allow the contract to receive ETH. - receive() external payable {} - - /// @notice Triggers a withdrawal of funds to the L1 fee wallet. - /// @param _value The amount of ETH to withdraw. - function withdraw(uint256 _value) public { - require( - _value >= minWithdrawAmount, - "FeeVault: withdrawal amount must be greater than minimum withdrawal amount" - ); - - uint256 _balance = address(this).balance; - require(_value <= _balance, "FeeVault: insufficient balance to withdraw"); - - unchecked { - totalProcessed += _value; - } - - emit Withdrawal(_value, recipient, msg.sender); - - // no fee provided - IL2ScrollMessenger(messenger).sendMessage{value: _value}( - recipient, - _value, - bytes(""), // no message (simple eth transfer) - 0 // _gasLimit can be zero for fee vault. - ); - } - - /// @notice Triggers a withdrawal of all available funds to the L1 fee wallet. - function withdraw() external { - uint256 value = address(this).balance; - withdraw(value); - } - - /************************ - * Restricted Functions * - ************************/ - - /// @notice Update the address of messenger. - /// @param _newMessenger The address of messenger to update. - function updateMessenger(address _newMessenger) external onlyOwner { - address _oldMessenger = messenger; - messenger = _newMessenger; - - emit UpdateMessenger(_oldMessenger, _newMessenger); - } - - /// @notice Update the address of recipient. - /// @param _newRecipient The address of recipient to update. - function updateRecipient(address _newRecipient) external onlyOwner { - address _oldRecipient = recipient; - recipient = _newRecipient; - - emit UpdateRecipient(_oldRecipient, _newRecipient); - } - - /// @notice Update the minimum withdraw amount. - /// @param _newMinWithdrawAmount The minimum withdraw amount to update. - function updateMinWithdrawAmount(uint256 _newMinWithdrawAmount) external onlyOwner { - uint256 _oldMinWithdrawAmount = minWithdrawAmount; - minWithdrawAmount = _newMinWithdrawAmount; - - emit UpdateMinWithdrawAmount(_oldMinWithdrawAmount, _newMinWithdrawAmount); - } -} diff --git a/contracts/src/L2/predeploys/Whitelist.sol b/contracts/src/L2/predeploys/Whitelist.sol deleted file mode 100644 index 712700cf1..000000000 --- a/contracts/src/L2/predeploys/Whitelist.sol +++ /dev/null @@ -1,35 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {OwnableBase} from "../../libraries/common/OwnableBase.sol"; -import {IWhitelist} from "../../libraries/common/IWhitelist.sol"; - -contract Whitelist is OwnableBase, IWhitelist { - /// @notice Emitted when account whitelist status changed. - /// @param _account The address of account whose status is changed. - /// @param _status The current whitelist status. - event WhitelistStatusChanged(address indexed _account, bool _status); - - /// @notice Keep track whether the account is whitelisted. - mapping(address => bool) private isWhitelisted; - - constructor(address _owner) { - _transferOwnership(_owner); - } - - /// @notice See {IWhitelist-isSenderAllowed} - function isSenderAllowed(address _sender) external view returns (bool) { - return isWhitelisted[_sender]; - } - - /// @notice Update the whitelist status - /// @param _accounts The list of addresses to update. - /// @param _status The whitelist status to update. - function updateWhitelistStatus(address[] memory _accounts, bool _status) external onlyOwner { - for (uint256 i = 0; i < _accounts.length; i++) { - isWhitelisted[_accounts[i]] = _status; - emit WhitelistStatusChanged(_accounts[i], _status); - } - } -} diff --git a/contracts/src/L2/predeploys/WrappedEther.sol b/contracts/src/L2/predeploys/WrappedEther.sol deleted file mode 100644 index 64aa269fd..000000000 --- a/contracts/src/L2/predeploys/WrappedEther.sol +++ /dev/null @@ -1,47 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; -import {ERC20Permit} from "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol"; - -// solhint-disable reason-string -// solhint-disable no-empty-blocks - -/// @author Inspired by WETH9 (https://github.com/dapphub/ds-weth/blob/master/src/weth9.sol) -contract WrappedEther is ERC20Permit { - /// @notice Emitted when user deposits Ether to this contract. - /// @param dst The address of depositor. - /// @param wad The amount of Ether in wei deposited. - event Deposit(address indexed dst, uint256 wad); - - /// @notice Emitted when user withdraws some Ether from this contract. - /// @param src The address of caller. - /// @param wad The amount of Ether in wei withdrawn. - event Withdrawal(address indexed src, uint256 wad); - - constructor() ERC20Permit("Wrapped Ether") ERC20("Wrapped Ether", "WETH") {} - - receive() external payable { - deposit(); - } - - function deposit() public payable { - address _sender = _msgSender(); - - _mint(_sender, msg.value); - - emit Deposit(_sender, msg.value); - } - - function withdraw(uint256 wad) external { - address _sender = _msgSender(); - - _burn(_sender, wad); - - (bool success, ) = _sender.call{value: wad}(""); - require(success, "withdraw ETH failed"); - - emit Withdrawal(_sender, wad); - } -} diff --git a/contracts/src/LICENSE b/contracts/src/LICENSE deleted file mode 100644 index c7d611106..000000000 --- a/contracts/src/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2023 Scroll - -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. \ No newline at end of file diff --git a/contracts/src/README.md b/contracts/src/README.md deleted file mode 100644 index b0ac540f6..000000000 --- a/contracts/src/README.md +++ /dev/null @@ -1,35 +0,0 @@ -A library for interacting with Scroll contracts. - -This library includes contracts and interfaces needed to interact with the Scroll Smart Contracts deployed on both Layer 1 and Layer 2. This includes deposting and withdrawing ETH, ERC20 tokens and NFTs or sending arbitrary messages. - -# Overview - -## Installations - -```bash -npm install @scroll-tech/contracts -``` - -## Usage - -Once installed, you can use the contracts in the library by importing them: - -```solidity -// SPDX-License-Identifier: MIT -pragma solidity 0.8.20; - -import "@scroll-tech/contracts/L1/gateways/IL1ETHGateway.sol"; - -contract MyContract { - function bridgeETH(address scrollBridge, uint256 gasLimit) public payable { - IL1ETHGateway(scrollBridge).depositETH(msg.sender, msg.value, gasLimit); - } -} - -``` - -Visit the Bridge Documentation for API reference, architecture overview and guides with code examples. - -# About Scroll - -Scroll is a bytecode equivalent zkEVM for Ethereum. It enables native compatibility for existing Ethereum applications and tools. Learn more about Scroll [here](https://scroll.io/). diff --git a/contracts/src/batch-bridge/BatchBridgeCodec.sol b/contracts/src/batch-bridge/BatchBridgeCodec.sol deleted file mode 100644 index ce03fb06b..000000000 --- a/contracts/src/batch-bridge/BatchBridgeCodec.sol +++ /dev/null @@ -1,35 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -library BatchBridgeCodec { - /// @dev Encode the `token` and `batchIndex` to single `bytes32`. - function encodeInitialNode(address token, uint64 batchIndex) internal pure returns (bytes32 node) { - assembly { - node := add(shl(96, token), batchIndex) - } - } - - /// @dev Encode the `sender` and `amount` to single `bytes32`. - function encodeNode(address sender, uint96 amount) internal pure returns (bytes32 node) { - assembly { - node := add(shl(96, sender), amount) - } - } - - /// @dev Decode `bytes32` `node` to `receiver` and `amount`. - function decodeNode(bytes32 node) internal pure returns (address receiver, uint256 amount) { - receiver = address(uint160(uint256(node) >> 96)); - amount = uint256(node) & 0xffffffffffffffffffffffff; - } - - /// @dev Compute `keccak256(concat(a, b))`. - function hash(bytes32 a, bytes32 b) internal pure returns (bytes32 value) { - // solhint-disable-next-line no-inline-assembly - assembly { - mstore(0x00, a) - mstore(0x20, b) - value := keccak256(0x00, 0x40) - } - } -} diff --git a/contracts/src/batch-bridge/L1BatchBridgeGateway.sol b/contracts/src/batch-bridge/L1BatchBridgeGateway.sol deleted file mode 100644 index 445f6320d..000000000 --- a/contracts/src/batch-bridge/L1BatchBridgeGateway.sol +++ /dev/null @@ -1,424 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {AccessControlEnumerableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol"; -import {ReentrancyGuardUpgradeable} from "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol"; -import {SafeERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol"; -import {IERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; - -import {IL1ERC20Gateway} from "../L1/gateways/IL1ERC20Gateway.sol"; -import {IL1GatewayRouter} from "../L1/gateways/IL1GatewayRouter.sol"; -import {IL1MessageQueue} from "../L1/rollup/IL1MessageQueue.sol"; -import {IL1ScrollMessenger} from "../L1/IL1ScrollMessenger.sol"; - -import {BatchBridgeCodec} from "./BatchBridgeCodec.sol"; -import {L2BatchBridgeGateway} from "./L2BatchBridgeGateway.sol"; - -/// @title L1BatchBridgeGateway -contract L1BatchBridgeGateway is AccessControlEnumerableUpgradeable, ReentrancyGuardUpgradeable { - using SafeERC20Upgradeable for IERC20Upgradeable; - - /********** - * Events * - **********/ - - /// @notice Emitted when some user deposited token to this contract. - /// @param sender The address of token sender. - /// @param token The address of deposited token. - /// @param batchIndex The batch index of current deposit. - /// @param amount The amount of token deposited (including fee). - /// @param fee The amount of fee charged. - event Deposit( - address indexed sender, - address indexed token, - uint256 indexed batchIndex, - uint256 amount, - uint256 fee - ); - - /// @notice Emitted when a batch deposit is initiated. - /// @param caller The address of caller who initiate the deposit. - /// @param l1Token The address of the token in L1 to deposit. - /// @param batchIndex The index of current batch deposit. - /// @param l2Token The address of the corresponding token in L2. - event BatchDeposit(address indexed caller, address indexed l1Token, uint256 indexed batchIndex, address l2Token); - - /********** - * Errors * - **********/ - - /// @dev Thrown when caller is not `messenger`. - error ErrorCallerNotMessenger(); - - /// @dev Thrown when the deposited amount is smaller than `minAmountPerTx`. - error ErrorDepositAmountTooSmall(); - - /// @dev Thrown when users try to deposit ETH with `depositERC20` method. - error ErrorIncorrectMethodForETHDeposit(); - - /// @dev Thrown when the `msg.value` is not enough for batch deposit fee. - error ErrorInsufficientMsgValueForBatchDepositFee(); - - /// @dev Thrown when the given new batch config is invalid. - error ErrorInvalidBatchConfig(); - - /// @dev Thrown when no pending batch exists. - error ErrorNoPendingBatch(); - - /// @dev Thrown when user deposits unsupported tokens. - error ErrorTokenNotSupported(); - - /// @dev Thrown when ETH transfer failed. - error ErrorTransferETHFailed(); - - /************* - * Constants * - *************/ - - /// @notice The role for batch deposit keeper. - bytes32 public constant KEEPER_ROLE = keccak256("KEEPER_ROLE"); - - /// @notice The safe gas limit for batch bridge. - uint256 private constant SAFE_BATCH_BRIDGE_GAS_LIMIT = 200000; - - /// @notice The address of corresponding `L2BatchBridgeGateway` contract. - address public immutable counterpart; - - /// @notice The address of `L1GatewayRouter` contract. - address public immutable router; - - /// @notice The address of `L1ScrollMessenger` contract. - address public immutable messenger; - - /// @notice The address of `L1MessageQueue` contract. - address public immutable queue; - - /*********** - * Structs * - ***********/ - - /// @notice The config for batch token bridge. - /// @dev Compiler will pack this into a single `bytes32`. - /// @param feeAmountPerTx The amount of fee charged for each deposit. - /// @param minAmountPerTx The minimum amount of token for each deposit. - /// @param maxTxsPerBatch The maximum number of deposit in each batch. - /// @param maxDelayPerBatch The maximum number of seconds to wait in each batch. - /// @param safeBridgeGasLimit The safe bridge gas limit for bridging token from L1 to L2. - struct BatchConfig { - uint96 feeAmountPerTx; - uint96 minAmountPerTx; - uint16 maxTxsPerBatch; - uint24 maxDelayPerBatch; - uint24 safeBridgeGasLimit; - } - - /// @dev Compiler will pack this into two `bytes32`. - /// @param amount The total amount of token to deposit in current batch. - /// @param startTime The timestamp of the first deposit. - /// @param numDeposits The total number of deposits in current batch. - /// @param hash The hash of current batch. - /// Suppose there are `n` deposits in current batch with `senders` and `amounts`. The hash is computed as - /// ```text - /// hash[0] = concat(token, batch_index) - /// hash[i] = keccak(hash[i-1], concat(senders[i], amounts[i])) - /// ``` - /// The type of `token` and `senders` is `address`, while The type of `batch_index` and `amounts[i]` is `uint96`. - /// In current way, the hash of each batch among all tokens should be different. - struct BatchState { - uint128 amount; - uint64 startTime; - uint64 numDeposits; - bytes32 hash; - } - - /// @dev Compiler will pack this into a single `bytes32`. - /// @param pending The total amount of token pending to bridge. - /// @param currentBatchIndex The index of current batch. - /// @param pendingBatchIndex The index of pending batch (next batch to bridge). - struct TokenState { - uint128 pending; - uint64 currentBatchIndex; - uint64 pendingBatchIndex; - } - - /************* - * Variables * - *************/ - - /// @notice Mapping from token address to batch bridge config. - /// @dev The `address(0)` is used for ETH. - mapping(address => BatchConfig) public configs; - - /// @notice Mapping from token address to batch index to batch state. - /// @dev The `address(0)` is used for ETH. - mapping(address => mapping(uint256 => BatchState)) public batches; - - /// @notice Mapping from token address to token state. - /// @dev The `address(0)` is used for ETH. - mapping(address => TokenState) public tokens; - - /// @notice The address of fee vault. - address public feeVault; - - /*************** - * Constructor * - ***************/ - - /// @param _counterpart The address of `L2BatchBridgeGateway` contract in L2. - /// @param _router The address of `L1GatewayRouter` contract in L1. - /// @param _messenger The address of `L1ScrollMessenger` contract in L1. - /// @param _queue The address of `L1MessageQueue` contract in L1. - constructor( - address _counterpart, - address _router, - address _messenger, - address _queue - ) { - _disableInitializers(); - - counterpart = _counterpart; - router = _router; - messenger = _messenger; - queue = _queue; - } - - /// @notice Initialize the storage of `L1BatchBridgeGateway`. - /// @param _feeVault The address of fee vault contract. - function initialize(address _feeVault) external initializer { - __Context_init(); // from ContextUpgradeable - __ERC165_init(); // from ERC165Upgradeable - __AccessControl_init(); // from AccessControlUpgradeable - __AccessControlEnumerable_init(); // from AccessControlEnumerableUpgradeable - __ReentrancyGuard_init(); // from ReentrancyGuardUpgradeable - - feeVault = _feeVault; - _grantRole(DEFAULT_ADMIN_ROLE, _msgSender()); - } - - /***************************** - * Public Mutating Functions * - *****************************/ - - /// @notice Receive refunded ETH from `L1ScrollMessenger`. - receive() external payable { - if (_msgSender() != messenger) { - revert ErrorCallerNotMessenger(); - } - } - - /// @notice Deposit ETH. - function depositETH() external payable nonReentrant { - // no safe cast check here, since no one has so much ETH yet. - _deposit(address(0), _msgSender(), uint96(msg.value)); - } - - /// @notice Deposit ERC20 token. - /// - /// @param token The address of token. - /// @param amount The amount of token to deposit. We use type `uint96`, since it is enough for most of the major tokens. - function depositERC20(address token, uint96 amount) external nonReentrant { - if (token == address(0)) revert ErrorIncorrectMethodForETHDeposit(); - - // common practice to handle fee on transfer token. - uint256 beforeBalance = IERC20Upgradeable(token).balanceOf(address(this)); - IERC20Upgradeable(token).safeTransferFrom(_msgSender(), address(this), amount); - amount = uint96(IERC20Upgradeable(token).balanceOf(address(this)) - beforeBalance); - - _deposit(token, _msgSender(), amount); - } - - /************************ - * Restricted Functions * - ************************/ - - /// @notice Add or update the batch bridge config for the given token. - /// - /// @dev The caller should make sure `safeBridgeGasLimit` is enough for batch bridging. - /// - /// @param token The address of token to update. - /// @param newConfig The new config. - function setBatchConfig(address token, BatchConfig calldata newConfig) external onlyRole(DEFAULT_ADMIN_ROLE) { - if ( - newConfig.maxTxsPerBatch == 0 || - newConfig.maxDelayPerBatch == 0 || - newConfig.feeAmountPerTx > newConfig.minAmountPerTx - ) { - revert ErrorInvalidBatchConfig(); - } - configs[token] = newConfig; - } - - /// @notice Initiate the batch bridge of current pending batch. - /// @param token The address of the token. - function executeBatchDeposit(address token) external payable onlyRole(KEEPER_ROLE) { - BatchConfig memory cachedBatchConfig = configs[token]; - TokenState memory cachedTokenState = tokens[token]; - _tryFinalizeCurrentBatch(token, cachedBatchConfig, cachedTokenState); - - // no batch to bridge - if (cachedTokenState.currentBatchIndex == cachedTokenState.pendingBatchIndex) { - revert ErrorNoPendingBatch(); - } - - // check bridge fee - uint256 depositFee = IL1MessageQueue(queue).estimateCrossDomainMessageFee(cachedBatchConfig.safeBridgeGasLimit); - uint256 batchBridgeFee = IL1MessageQueue(queue).estimateCrossDomainMessageFee(SAFE_BATCH_BRIDGE_GAS_LIMIT); - if (msg.value < depositFee + batchBridgeFee) { - revert ErrorInsufficientMsgValueForBatchDepositFee(); - } - - // take accumulated fee to fee vault - uint256 accumulatedFee; - if (token == address(0)) { - // no uncheck here just in case - accumulatedFee = address(this).balance - msg.value - cachedTokenState.pending; - } else { - // no uncheck here just in case - accumulatedFee = IERC20Upgradeable(token).balanceOf(address(this)) - cachedTokenState.pending; - } - if (accumulatedFee > 0) { - _transferToken(token, feeVault, accumulatedFee); - } - - // deposit token to L2 - BatchState memory cachedBatchState = batches[token][cachedTokenState.pendingBatchIndex]; - address l2Token; - if (token == address(0)) { - IL1ScrollMessenger(messenger).sendMessage{value: cachedBatchState.amount + depositFee}( - counterpart, - cachedBatchState.amount, - new bytes(0), - cachedBatchConfig.safeBridgeGasLimit - ); - } else { - address gateway = IL1GatewayRouter(router).getERC20Gateway(token); - l2Token = IL1ERC20Gateway(gateway).getL2ERC20Address(token); - IERC20Upgradeable(token).safeApprove(gateway, 0); - IERC20Upgradeable(token).safeApprove(gateway, cachedBatchState.amount); - IL1ERC20Gateway(gateway).depositERC20{value: depositFee}( - token, - counterpart, - cachedBatchState.amount, - cachedBatchConfig.safeBridgeGasLimit - ); - } - - // notify `L2BatchBridgeGateway` - IL1ScrollMessenger(messenger).sendMessage{value: batchBridgeFee}( - counterpart, - 0, - abi.encodeCall( - L2BatchBridgeGateway.finalizeBatchDeposit, - (token, l2Token, cachedTokenState.pendingBatchIndex, cachedBatchState.hash) - ), - SAFE_BATCH_BRIDGE_GAS_LIMIT - ); - - emit BatchDeposit(_msgSender(), token, cachedTokenState.pendingBatchIndex, l2Token); - - // update token state - unchecked { - cachedTokenState.pending -= uint128(cachedBatchState.amount); - cachedTokenState.pendingBatchIndex += 1; - } - tokens[token] = cachedTokenState; - - // refund keeper fee - unchecked { - if (msg.value > depositFee + batchBridgeFee) { - _transferToken(address(0), _msgSender(), msg.value - depositFee - batchBridgeFee); - } - } - } - - /********************** - * Internal Functions * - **********************/ - - /// @dev Internal function to deposit token. - /// @param token The address of token to deposit. - /// @param sender The address of token sender. - /// @param amount The amount of token to deposit. - function _deposit( - address token, - address sender, - uint96 amount - ) internal { - BatchConfig memory cachedBatchConfig = configs[token]; - TokenState memory cachedTokenState = tokens[token]; - _tryFinalizeCurrentBatch(token, cachedBatchConfig, cachedTokenState); - - if (amount < cachedBatchConfig.minAmountPerTx) { - revert ErrorDepositAmountTooSmall(); - } - BatchState memory cachedBatchState = batches[token][cachedTokenState.currentBatchIndex]; - - emit Deposit(sender, token, cachedTokenState.currentBatchIndex, amount, cachedBatchConfig.feeAmountPerTx); - - // deduct fee and update cached state - unchecked { - amount -= cachedBatchConfig.feeAmountPerTx; - cachedTokenState.pending += amount; - cachedBatchState.amount += amount; - cachedBatchState.numDeposits += 1; - } - - // compute the hash chain - bytes32 node = BatchBridgeCodec.encodeNode(sender, amount); - if (cachedBatchState.hash == bytes32(0)) { - bytes32 initialNode = BatchBridgeCodec.encodeInitialNode(token, cachedTokenState.currentBatchIndex); - // this is first tx in this batch - cachedBatchState.hash = BatchBridgeCodec.hash(initialNode, node); - cachedBatchState.startTime = uint64(block.timestamp); - } else { - cachedBatchState.hash = BatchBridgeCodec.hash(cachedBatchState.hash, node); - } - - batches[token][cachedTokenState.currentBatchIndex] = cachedBatchState; - tokens[token] = cachedTokenState; - } - - /// @dev Internal function to finalize current batch. - /// This function may change the value of `cachedTokenState`, which can be used in later operation. - /// @param token The address of token to finalize. - /// @param cachedBatchConfig The cached batch config in memory. - /// @param cachedTokenState The cached token state in memory. - function _tryFinalizeCurrentBatch( - address token, - BatchConfig memory cachedBatchConfig, - TokenState memory cachedTokenState - ) internal view { - if (cachedBatchConfig.maxTxsPerBatch == 0) { - revert ErrorTokenNotSupported(); - } - BatchState memory cachedBatchState = batches[token][cachedTokenState.currentBatchIndex]; - // return if it is the very first deposit in the current batch - if (cachedBatchState.numDeposits == 0) return; - - // finalize current batchIndex when `maxTxsPerBatch` or `maxDelayPerBatch` reached. - if ( - cachedBatchState.numDeposits == cachedBatchConfig.maxTxsPerBatch || - block.timestamp - cachedBatchState.startTime > cachedBatchConfig.maxDelayPerBatch - ) { - cachedTokenState.currentBatchIndex += 1; - } - } - - /// @dev Internal function to transfer token, including ETH. - /// @param token The address of token. - /// @param receiver The address of token receiver. - /// @param amount The amount of token to transfer. - function _transferToken( - address token, - address receiver, - uint256 amount - ) private { - if (token == address(0)) { - (bool success, ) = receiver.call{value: amount}(""); - if (!success) revert ErrorTransferETHFailed(); - } else { - IERC20Upgradeable(token).safeTransfer(receiver, amount); - } - } -} diff --git a/contracts/src/batch-bridge/L2BatchBridgeGateway.sol b/contracts/src/batch-bridge/L2BatchBridgeGateway.sol deleted file mode 100644 index 84b95273a..000000000 --- a/contracts/src/batch-bridge/L2BatchBridgeGateway.sol +++ /dev/null @@ -1,246 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {AccessControlEnumerableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol"; -import {IERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; - -import {IL2ScrollMessenger} from "../L2/IL2ScrollMessenger.sol"; -import {BatchBridgeCodec} from "./BatchBridgeCodec.sol"; - -/// @title L2BatchBridgeGateway -contract L2BatchBridgeGateway is AccessControlEnumerableUpgradeable { - /********** - * Events * - **********/ - - /// @notice Emitted when token mapping for ERC20 token is updated. - /// @param l2Token The address of corresponding ERC20 token in layer 2. - /// @param oldL1Token The address of the old corresponding ERC20 token in layer 1. - /// @param newL1Token The address of the new corresponding ERC20 token in layer 1. - event UpdateTokenMapping(address indexed l2Token, address indexed oldL1Token, address indexed newL1Token); - - /// @notice Emitted when batch bridge is finalized. - /// @param l1Token The address of token in L1. - /// @param l2Token The address of token in L2. - /// @param batchIndex The index of batch finalized. - event FinalizeBatchDeposit(address indexed l1Token, address indexed l2Token, uint256 indexed batchIndex); - - /// @notice Emitted when batch distribution finished. - /// @param l1Token The address of token in L1. - /// @param l2Token The address of token in L2. - /// @param batchIndex The index of batch distributed. - event BatchDistribute(address indexed l1Token, address indexed l2Token, uint256 indexed batchIndex); - - /// @notice Emitted when token distribute failed. - /// @param l2Token The address of token in L2. - /// @param batchIndex The index of the batch. - /// @param receiver The address of token receiver. - /// @param amount The amount of token to distribute. - event DistributeFailed(address indexed l2Token, uint256 indexed batchIndex, address receiver, uint256 amount); - - /********** - * Errors * - **********/ - - /// @dev Thrown when caller is not `messenger`. - error ErrorCallerNotMessenger(); - - /// @dev Thrown when the L1 token mapping mismatch with `finalizeBatchBridge`. - error ErrorL1TokenMismatched(); - - /// @dev Thrown when message sender is not `counterpart`. - error ErrorMessageSenderNotCounterpart(); - - /// @dev Thrown no failed distribution exists. - error ErrorNoFailedDistribution(); - - /// @dev Thrown when the batch hash mismatch. - error ErrorBatchHashMismatch(); - - /// @dev Thrown when distributing the same batch. - error ErrorBatchDistributed(); - - /************* - * Constants * - *************/ - - /// @notice The role for batch deposit keeper. - bytes32 public constant KEEPER_ROLE = keccak256("KEEPER_ROLE"); - - /// @notice The safe gas limit for ETH transfer - uint256 private constant SAFE_ETH_TRANSFER_GAS_LIMIT = 50000; - - /// @notice The address of corresponding `L1BatchBridgeGateway` contract. - address public immutable counterpart; - - /// @notice The address of corresponding `L2ScrollMessenger` contract. - address public immutable messenger; - - /************* - * Variables * - *************/ - - /// @notice Mapping from l2 token address to l1 token address. - mapping(address => address) public tokenMapping; - - /// @notice Mapping from L2 token address to batch index to batch hash. - mapping(address => mapping(uint256 => bytes32)) public batchHashes; - - /// @notice Mapping from token address to the amount of failed distribution. - mapping(address => uint256) public failedAmount; - - /// @notice Mapping from batch hash to the distribute status. - mapping(bytes32 => bool) public isDistributed; - - /************* - * Modifiers * - *************/ - - modifier onlyMessenger() { - if (_msgSender() != messenger) { - revert ErrorCallerNotMessenger(); - } - _; - } - - /*************** - * Constructor * - ***************/ - - /// @param _counterpart The address of `L1BatchBridgeGateway` contract in L1. - /// @param _messenger The address of `L2ScrollMessenger` contract in L2. - constructor(address _counterpart, address _messenger) { - _disableInitializers(); - - counterpart = _counterpart; - messenger = _messenger; - } - - /// @notice Initialize the storage of `L2BatchBridgeGateway`. - function initialize() external initializer { - __Context_init(); // from ContextUpgradeable - __ERC165_init(); // from ERC165Upgradeable - __AccessControl_init(); // from AccessControlUpgradeable - __AccessControlEnumerable_init(); // from AccessControlEnumerableUpgradeable - - _grantRole(DEFAULT_ADMIN_ROLE, _msgSender()); - } - - /***************************** - * Public Mutating Functions * - *****************************/ - - /// @notice Receive batch bridged ETH from `L2ScrollMessenger`. - receive() external payable onlyMessenger { - // empty - } - - /// @notice Finalize L1 initiated batch token deposit. - /// @param l1Token The address of the token in L1. - /// @param l2Token The address of the token in L2. - /// @param batchIndex The index of this batch bridge. - /// @param hash The hash of this batch. - function finalizeBatchDeposit( - address l1Token, - address l2Token, - uint256 batchIndex, - bytes32 hash - ) external onlyMessenger { - if (counterpart != IL2ScrollMessenger(messenger).xDomainMessageSender()) { - revert ErrorMessageSenderNotCounterpart(); - } - - // trust the messenger and update `tokenMapping` in first call - // another assumption is this function should never fail due to out of gas - address storedL1Token = tokenMapping[l2Token]; - if (storedL1Token == address(0) && l1Token != address(0)) { - tokenMapping[l2Token] = l1Token; - } else if (storedL1Token != l1Token) { - // this usually won't happen, check just in case. - revert ErrorL1TokenMismatched(); - } - - batchHashes[l2Token][batchIndex] = hash; - - emit FinalizeBatchDeposit(l1Token, l2Token, batchIndex); - } - - /************************ - * Restricted Functions * - ************************/ - - /// @notice Withdraw distribution failed tokens. - /// @param token The address of token to withdraw. - /// @param receiver The address of token receiver. - function withdrawFailedAmount(address token, address receiver) external onlyRole(DEFAULT_ADMIN_ROLE) { - uint256 amount = failedAmount[token]; - if (amount == 0) revert ErrorNoFailedDistribution(); - failedAmount[token] = 0; - - _transferToken(token, receiver, amount); - } - - /// @notice Distribute deposited token to corresponding receivers. - /// @param l2Token The address of L2 token. - /// @param batchIndex The index of batch to distribute. - /// @param nodes The list of encoded L1 deposits. - function distribute( - address l2Token, - uint64 batchIndex, - bytes32[] memory nodes - ) external onlyRole(KEEPER_ROLE) { - address l1Token = tokenMapping[l2Token]; - bytes32 hash = BatchBridgeCodec.encodeInitialNode(l1Token, batchIndex); - for (uint256 i = 0; i < nodes.length; i++) { - hash = BatchBridgeCodec.hash(hash, nodes[i]); - } - if (batchHashes[l2Token][batchIndex] != hash) { - revert ErrorBatchHashMismatch(); - } - if (isDistributed[hash]) { - revert ErrorBatchDistributed(); - } - isDistributed[hash] = true; - - // do transfer and allow failure to avoid DDOS attack - for (uint256 i = 0; i < nodes.length; i++) { - (address receiver, uint256 amount) = BatchBridgeCodec.decodeNode(nodes[i]); - if (!_transferToken(l2Token, receiver, amount)) { - failedAmount[l2Token] += amount; - - emit DistributeFailed(l2Token, batchIndex, receiver, amount); - } - } - - emit BatchDistribute(l1Token, l2Token, batchIndex); - } - - /********************** - * Internal Functions * - **********************/ - - /// @dev Internal function to transfer token, including ETH. - /// @param token The address of token. - /// @param receiver The address of token receiver. - /// @param amount The amount of token to transfer. - /// @return success Whether the transfer is successful. - function _transferToken( - address token, - address receiver, - uint256 amount - ) private returns (bool success) { - if (token == address(0)) { - // We add gas limit here to avoid DDOS from malicious receiver. - (success, ) = receiver.call{value: amount, gas: SAFE_ETH_TRANSFER_GAS_LIMIT}(""); - } else { - // We perform a low level call here, to bypass Solidity's return data size checking mechanism. - // Normally, the token is selected that the call would not revert unless out of gas. - bytes memory returnData; - (success, returnData) = token.call(abi.encodeCall(IERC20Upgradeable.transfer, (receiver, amount))); - if (success && returnData.length > 0) { - success = abi.decode(returnData, (bool)); - } - } - } -} diff --git a/contracts/src/gas-swap/GasSwap.sol b/contracts/src/gas-swap/GasSwap.sol deleted file mode 100644 index 61bea33c4..000000000 --- a/contracts/src/gas-swap/GasSwap.sol +++ /dev/null @@ -1,201 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; -import {ERC2771Context} from "@openzeppelin/contracts/metatx/ERC2771Context.sol"; -import {ReentrancyGuard} from "@openzeppelin/contracts/security/ReentrancyGuard.sol"; -import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; -import {IERC20Permit} from "@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol"; -import {Context} from "@openzeppelin/contracts/utils/Context.sol"; - -// solhint-disable no-empty-blocks - -contract GasSwap is ERC2771Context, Ownable, ReentrancyGuard { - using SafeERC20 for IERC20; - using SafeERC20 for IERC20Permit; - - /********** - * Events * - **********/ - - /// @notice Emitted when the fee ratio is updated. - /// @param feeRatio The new fee ratio, multiplied by 1e18. - event UpdateFeeRatio(uint256 feeRatio); - - /// @notice Emitted when the status of target is updated. - /// @param target The address of target contract. - /// @param status The status updated. - event UpdateApprovedTarget(address target, bool status); - - /************* - * Constants * - *************/ - - /// @dev The fee precision. - uint256 private constant PRECISION = 1e18; - - /*********** - * Structs * - ***********/ - - struct PermitData { - // The address of token to spend. - address token; - // The amount of token to spend. - uint256 value; - // The deadline of the permit. - uint256 deadline; - // Below three are signatures. - uint8 v; - bytes32 r; - bytes32 s; - } - - struct SwapData { - // The address of target contract to call. - address target; - // The calldata passed to target contract. - bytes data; - // The minimum amount of Ether should receive. - uint256 minOutput; - } - - /************* - * Variables * - *************/ - - /// @notice Keep track whether an address is approved. - mapping(address => bool) public approvedTargets; - - /// @notice The fee ratio charged for each swap, multiplied by 1e18. - uint256 public feeRatio; - - /*************** - * Constructor * - ***************/ - - constructor(address trustedForwarder) ERC2771Context(trustedForwarder) {} - - /***************************** - * Public Mutating Functions * - *****************************/ - - receive() external payable {} - - /// @notice Swap some token for ether. - /// @param _permit The permit data, see comments from `PermitData`. - /// @param _swap The swap data, see comments from `SwapData`. - function swap(PermitData memory _permit, SwapData memory _swap) external nonReentrant { - require(approvedTargets[_swap.target], "target not approved"); - address _sender = _msgSender(); - - // do permit - IERC20Permit(_permit.token).safePermit( - _sender, - address(this), - _permit.value, - _permit.deadline, - _permit.v, - _permit.r, - _permit.s - ); - - // record token balance in this contract - uint256 _balance = IERC20(_permit.token).balanceOf(address(this)); - - // transfer token - IERC20(_permit.token).safeTransferFrom(_sender, address(this), _permit.value); - - // approve - IERC20(_permit.token).safeApprove(_swap.target, 0); - IERC20(_permit.token).safeApprove(_swap.target, _permit.value); - - // do swap - uint256 _outputTokenAmount = address(this).balance; - // solhint-disable-next-line avoid-low-level-calls - (bool _success, bytes memory _res) = _swap.target.call(_swap.data); - require(_success, string(concat(bytes("swap failed: "), bytes(getRevertMsg(_res))))); - _outputTokenAmount = address(this).balance - _outputTokenAmount; - - // take fee - uint256 _fee = (_outputTokenAmount * feeRatio) / PRECISION; - _outputTokenAmount = _outputTokenAmount - _fee; - require(_outputTokenAmount >= _swap.minOutput, "insufficient output amount"); - - // transfer ETH to sender - (_success, ) = _sender.call{value: _outputTokenAmount}(""); - require(_success, "transfer ETH failed"); - - // refund rest token - uint256 _dust = IERC20(_permit.token).balanceOf(address(this)) - _balance; - if (_dust > 0) { - IERC20(_permit.token).safeTransfer(_sender, _dust); - } - } - - /************************ - * Restricted Functions * - ************************/ - - /// @notice Withdraw stucked tokens. - /// @param _token The address of token to withdraw. Use `address(0)` if you want to withdraw Ether. - /// @param _amount The amount of token to withdraw. - function withdraw(address _token, uint256 _amount) external onlyOwner { - if (_token == address(0)) { - (bool success, ) = _msgSender().call{value: _amount}(""); - require(success, "ETH transfer failed"); - } else { - IERC20(_token).safeTransfer(_msgSender(), _amount); - } - } - - /// @notice Update the fee ratio. - /// @param _feeRatio The new fee ratio. - function updateFeeRatio(uint256 _feeRatio) external onlyOwner { - feeRatio = _feeRatio; - - emit UpdateFeeRatio(_feeRatio); - } - - /// @notice Update the status of a target address. - /// @param _target The address of target to update. - /// @param _status The new status. - function updateApprovedTarget(address _target, bool _status) external onlyOwner { - approvedTargets[_target] = _status; - - emit UpdateApprovedTarget(_target, _status); - } - - /********************** - * Internal Functions * - **********************/ - - /// @inheritdoc Context - function _msgData() internal view virtual override(Context, ERC2771Context) returns (bytes calldata) { - return ERC2771Context._msgData(); - } - - /// @inheritdoc Context - function _msgSender() internal view virtual override(Context, ERC2771Context) returns (address) { - return ERC2771Context._msgSender(); - } - - /// @dev Internal function to concat two bytes array. - function concat(bytes memory a, bytes memory b) internal pure returns (bytes memory) { - return abi.encodePacked(a, b); - } - - /// @dev Internal function decode revert message from return data. - function getRevertMsg(bytes memory _returnData) internal pure returns (string memory) { - if (_returnData.length < 68) return "Transaction reverted silently"; - - // solhint-disable-next-line no-inline-assembly - assembly { - _returnData := add(_returnData, 0x04) - } - - return abi.decode(_returnData, (string)); - } -} diff --git a/contracts/src/interfaces/IFiatToken.sol b/contracts/src/interfaces/IFiatToken.sol deleted file mode 100644 index ce1b43d7b..000000000 --- a/contracts/src/interfaces/IFiatToken.sol +++ /dev/null @@ -1,22 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.24; - -interface IFiatToken { - /** - * @notice 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) external returns (bool); - - /** - * @notice 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) external; -} diff --git a/contracts/src/interfaces/IMessageTransmitter.sol b/contracts/src/interfaces/IMessageTransmitter.sol deleted file mode 100644 index f579f79b9..000000000 --- a/contracts/src/interfaces/IMessageTransmitter.sol +++ /dev/null @@ -1,20 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.24; - -/// @title IMessageTransmitter -/// @notice The interface of `MessageTransmitter` of Circle's Cross-Chain Transfer Protocol (CCTP). -interface IMessageTransmitter { - /// @notice Compute the nonce of a message. - /// @param _sourceAndNonce The bytes contains source and nonce. - function usedNonces(bytes32 _sourceAndNonce) external view returns (uint256); - - /** - * @notice Receives an incoming message, validating the header and passing - * the body to application-specific handler. - * @param message The message raw bytes - * @param signature The message signature - * @return success bool, true if successful - */ - function receiveMessage(bytes calldata message, bytes calldata signature) external returns (bool success); -} diff --git a/contracts/src/interfaces/ITokenMessenger.sol b/contracts/src/interfaces/ITokenMessenger.sol deleted file mode 100644 index 95de16dd2..000000000 --- a/contracts/src/interfaces/ITokenMessenger.sol +++ /dev/null @@ -1,65 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.24; - -/// @title ITokenMessenger -/// @notice The interface of `TokenMessenger` of Circle's Cross-Chain Transfer Protocol (CCTP). -interface ITokenMessenger { - /** - * @notice Deposits and burns tokens from sender to be minted on destination domain. The mint - * on the destination domain must be called by `destinationCaller`. - * WARNING: if the `destinationCaller` does not represent a valid address as bytes32, then it will not be possible - * to broadcast the message on the destination domain. This is an advanced feature, and the standard - * depositForBurn() should be preferred for use cases where a specific destination caller is not required. - * Emits a `DepositForBurn` event. - * @dev reverts if: - * - given destinationCaller is zero address - * - given burnToken is not supported - * - given destinationDomain has no TokenMessenger registered - * - transferFrom() reverts. For example, if sender's burnToken balance or approved allowance - * to this contract is less than `amount`. - * - burn() reverts. For example, if `amount` is 0. - * - MessageTransmitter returns false or reverts. - * @param amount amount of tokens to burn - * @param destinationDomain destination domain - * @param mintRecipient address of mint recipient on destination domain - * @param burnToken address of contract to burn deposited tokens, on local domain - * @param destinationCaller caller on the destination domain, as bytes32 - * @return nonce unique nonce reserved by message - */ - function depositForBurnWithCaller( - uint256 amount, - uint32 destinationDomain, - bytes32 mintRecipient, - address burnToken, - bytes32 destinationCaller - ) external returns (uint64 nonce); - - /** - * @notice Replace a BurnMessage to change the mint recipient and/or - * destination caller. Allows the sender of a previous BurnMessage - * (created by depositForBurn or depositForBurnWithCaller) - * to send a new BurnMessage to replace the original. - * The new BurnMessage will reuse the amount and burn token of the original, - * without requiring a new deposit. - * @dev The new message will reuse the original message's nonce. For a - * given nonce, all replacement message(s) and the original message are - * valid to broadcast on the destination domain, until the first message - * at the nonce confirms, at which point all others are invalidated. - * Note: The msg.sender of the replaced message must be the same as the - * msg.sender of the original message. - * @param originalMessage original message bytes (to replace) - * @param originalAttestation original attestation bytes - * @param newDestinationCaller the new destination caller, which may be the - * same as the original destination caller, a new destination caller, or an empty - * destination caller (bytes32(0), indicating that any destination caller is valid.) - * @param newMintRecipient the new mint recipient, which may be the same as the - * original mint recipient, or different. - */ - function replaceDepositForBurn( - bytes calldata originalMessage, - bytes calldata originalAttestation, - bytes32 newDestinationCaller, - bytes32 newMintRecipient - ) external; -} diff --git a/contracts/src/interfaces/IUSDCBurnableSourceBridge.sol b/contracts/src/interfaces/IUSDCBurnableSourceBridge.sol deleted file mode 100644 index 081bacfb4..000000000 --- a/contracts/src/interfaces/IUSDCBurnableSourceBridge.sol +++ /dev/null @@ -1,13 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.24; - -/// @title IUSDCBurnableSourceBridge -/// @notice The interface of `USDCBurnableSourceBridge` of Circle's upgrader in L1 (Ethereum). -interface IUSDCBurnableSourceBridge { - /** - * @notice Called by Circle, this executes a burn on the source - * chain. - */ - function burnAllLockedUSDC() external; -} diff --git a/contracts/src/interfaces/IUSDCDestinationBridge.sol b/contracts/src/interfaces/IUSDCDestinationBridge.sol deleted file mode 100644 index 9ea664814..000000000 --- a/contracts/src/interfaces/IUSDCDestinationBridge.sol +++ /dev/null @@ -1,12 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.24; - -/// @title IUSDCDestinationBridge -/// @notice The interface required for USDC bridge in the destination chain (Scroll). -interface IUSDCDestinationBridge { - /** - * @notice Called by Circle, this transfers FiatToken roles to the designated owner. - */ - function transferUSDCRoles(address owner) external; -} diff --git a/contracts/src/interfaces/IWETH.sol b/contracts/src/interfaces/IWETH.sol deleted file mode 100644 index bf10aacd3..000000000 --- a/contracts/src/interfaces/IWETH.sol +++ /dev/null @@ -1,9 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.24; - -interface IWETH { - function deposit() external payable; - - function withdraw(uint256 wad) external; -} diff --git a/contracts/src/libraries/IScrollMessenger.sol b/contracts/src/libraries/IScrollMessenger.sol deleted file mode 100644 index b5d0f46b8..000000000 --- a/contracts/src/libraries/IScrollMessenger.sol +++ /dev/null @@ -1,77 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.24; - -interface IScrollMessenger { - /********** - * Events * - **********/ - - /// @notice Emitted when a cross domain message is sent. - /// @param sender The address of the sender who initiates the message. - /// @param target The address of target contract to call. - /// @param value The amount of value passed to the target contract. - /// @param messageNonce The nonce of the message. - /// @param gasLimit The optional gas limit passed to L1 or L2. - /// @param message The calldata passed to the target contract. - event SentMessage( - address indexed sender, - address indexed target, - uint256 value, - uint256 messageNonce, - uint256 gasLimit, - bytes message - ); - - /// @notice Emitted when a cross domain message is relayed successfully. - /// @param messageHash The hash of the message. - event RelayedMessage(bytes32 indexed messageHash); - - /// @notice Emitted when a cross domain message is failed to relay. - /// @param messageHash The hash of the message. - event FailedRelayedMessage(bytes32 indexed messageHash); - - /********** - * Errors * - **********/ - - /// @dev Thrown when the given address is `address(0)`. - error ErrorZeroAddress(); - - /************************* - * Public View Functions * - *************************/ - - /// @notice Return the sender of a cross domain message. - function xDomainMessageSender() external view returns (address); - - /***************************** - * Public Mutating Functions * - *****************************/ - - /// @notice Send cross chain message from L1 to L2 or L2 to L1. - /// @param target The address of account who receive the message. - /// @param value The amount of ether passed when call target contract. - /// @param message The content of the message. - /// @param gasLimit Gas limit required to complete the message relay on corresponding chain. - function sendMessage( - address target, - uint256 value, - bytes calldata message, - uint256 gasLimit - ) external payable; - - /// @notice Send cross chain message from L1 to L2 or L2 to L1. - /// @param target The address of account who receive the message. - /// @param value The amount of ether passed when call target contract. - /// @param message The content of the message. - /// @param gasLimit Gas limit required to complete the message relay on corresponding chain. - /// @param refundAddress The address of account who will receive the refunded fee. - function sendMessage( - address target, - uint256 value, - bytes calldata message, - uint256 gasLimit, - address refundAddress - ) external payable; -} diff --git a/contracts/src/libraries/ScrollMessengerBase.sol b/contracts/src/libraries/ScrollMessengerBase.sol deleted file mode 100644 index 9d34ae1cc..000000000 --- a/contracts/src/libraries/ScrollMessengerBase.sol +++ /dev/null @@ -1,156 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.24; - -import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; -import {PausableUpgradeable} from "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol"; -import {ReentrancyGuardUpgradeable} from "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol"; - -import {ScrollConstants} from "./constants/ScrollConstants.sol"; -import {IScrollMessenger} from "./IScrollMessenger.sol"; - -// solhint-disable var-name-mixedcase - -abstract contract ScrollMessengerBase is - OwnableUpgradeable, - PausableUpgradeable, - ReentrancyGuardUpgradeable, - IScrollMessenger -{ - /********** - * Events * - **********/ - - /// @notice Emitted when owner updates fee vault contract. - /// @param _oldFeeVault The address of old fee vault contract. - /// @param _newFeeVault The address of new fee vault contract. - event UpdateFeeVault(address _oldFeeVault, address _newFeeVault); - - /************* - * Constants * - *************/ - - /// @notice The address of counterpart ScrollMessenger contract in L1/L2. - address public immutable counterpart; - - /************* - * Variables * - *************/ - - /// @notice See {IScrollMessenger-xDomainMessageSender} - address public override xDomainMessageSender; - - /// @dev The storage slot used as counterpart ScrollMessenger contract, which is deprecated now. - address private __counterpart; - - /// @notice The address of fee vault, collecting cross domain messaging fee. - address public feeVault; - - /// @dev The storage slot used as ETH rate limiter contract, which is deprecated now. - address private __rateLimiter; - - /// @dev The storage slots for future usage. - uint256[46] private __gap; - - /********************** - * Function Modifiers * - **********************/ - - modifier notInExecution() { - require( - xDomainMessageSender == ScrollConstants.DEFAULT_XDOMAIN_MESSAGE_SENDER, - "Message is already in execution" - ); - _; - } - - /*************** - * Constructor * - ***************/ - - constructor(address _counterpart) { - if (_counterpart == address(0)) { - revert ErrorZeroAddress(); - } - - counterpart = _counterpart; - } - - function __ScrollMessengerBase_init(address, address _feeVault) internal onlyInitializing { - OwnableUpgradeable.__Ownable_init(); - PausableUpgradeable.__Pausable_init(); - ReentrancyGuardUpgradeable.__ReentrancyGuard_init(); - - // initialize to a nonzero value - xDomainMessageSender = ScrollConstants.DEFAULT_XDOMAIN_MESSAGE_SENDER; - - if (_feeVault != address(0)) { - feeVault = _feeVault; - } - } - - // make sure only owner can send ether to messenger to avoid possible user fund loss. - receive() external payable onlyOwner {} - - /************************ - * Restricted Functions * - ************************/ - - /// @notice Update fee vault contract. - /// @dev This function can only called by contract owner. - /// @param _newFeeVault The address of new fee vault contract. - function updateFeeVault(address _newFeeVault) external onlyOwner { - address _oldFeeVault = feeVault; - - feeVault = _newFeeVault; - emit UpdateFeeVault(_oldFeeVault, _newFeeVault); - } - - /// @notice Pause the contract - /// @dev This function can only called by contract owner. - /// @param _status The pause status to update. - function setPause(bool _status) external onlyOwner { - if (_status) { - _pause(); - } else { - _unpause(); - } - } - - /********************** - * Internal Functions * - **********************/ - - /// @dev Internal function to generate the correct cross domain calldata for a message. - /// @param _sender Message sender address. - /// @param _target Target contract address. - /// @param _value The amount of ETH pass to the target. - /// @param _messageNonce Nonce for the provided message. - /// @param _message Message to send to the target. - /// @return ABI encoded cross domain calldata. - function _encodeXDomainCalldata( - address _sender, - address _target, - uint256 _value, - uint256 _messageNonce, - bytes memory _message - ) internal pure returns (bytes memory) { - return - abi.encodeWithSignature( - "relayMessage(address,address,uint256,uint256,bytes)", - _sender, - _target, - _value, - _messageNonce, - _message - ); - } - - /// @dev Internal function to check whether the `_target` address is allowed to avoid attack. - /// @param _target The address of target address to check. - function _validateTargetAddress(address _target) internal view { - // @note check more `_target` address to avoid attack in the future when we add more external contracts. - - require(_target != address(this), "Forbid to call self"); - } -} diff --git a/contracts/src/libraries/callbacks/IERC677Receiver.sol b/contracts/src/libraries/callbacks/IERC677Receiver.sol deleted file mode 100644 index 53e98d0f8..000000000 --- a/contracts/src/libraries/callbacks/IERC677Receiver.sol +++ /dev/null @@ -1,11 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.24; - -interface IERC677Receiver { - function onTokenTransfer( - address sender, - uint256 value, - bytes memory data - ) external; -} diff --git a/contracts/src/libraries/callbacks/IMessageDropCallback.sol b/contracts/src/libraries/callbacks/IMessageDropCallback.sol deleted file mode 100644 index e23f3cda7..000000000 --- a/contracts/src/libraries/callbacks/IMessageDropCallback.sol +++ /dev/null @@ -1,7 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.24; - -interface IMessageDropCallback { - function onDropMessage(bytes memory message) external payable; -} diff --git a/contracts/src/libraries/callbacks/IScrollGatewayCallback.sol b/contracts/src/libraries/callbacks/IScrollGatewayCallback.sol deleted file mode 100644 index 9d0d29629..000000000 --- a/contracts/src/libraries/callbacks/IScrollGatewayCallback.sol +++ /dev/null @@ -1,7 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.24; - -interface IScrollGatewayCallback { - function onScrollGatewayCallback(bytes memory data) external; -} diff --git a/contracts/src/libraries/codec/BatchHeaderV0Codec.sol b/contracts/src/libraries/codec/BatchHeaderV0Codec.sol deleted file mode 100644 index fabfe6821..000000000 --- a/contracts/src/libraries/codec/BatchHeaderV0Codec.sol +++ /dev/null @@ -1,212 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.24; - -// solhint-disable no-inline-assembly - -/// @dev Below is the encoding for `BatchHeader` V0, total 89 + ceil(l1MessagePopped / 256) * 32 bytes. -/// ```text -/// * Field Bytes Type Index Comments -/// * version 1 uint8 0 The batch version -/// * batchIndex 8 uint64 1 The index of the batch -/// * l1MessagePopped 8 uint64 9 Number of L1 messages popped in the batch -/// * totalL1MessagePopped 8 uint64 17 Number of total L1 messages popped after the batch -/// * dataHash 32 bytes32 25 The data hash of the batch -/// * parentBatchHash 32 bytes32 57 The parent batch hash -/// * skippedL1MessageBitmap dynamic uint256[] 89 A bitmap to indicate which L1 messages are skipped in the batch -/// ``` -library BatchHeaderV0Codec { - /// @dev Thrown when the length of batch header is smaller than 89 - error ErrorBatchHeaderLengthTooSmall(); - - /// @dev Thrown when the length of skippedL1MessageBitmap is incorrect. - error ErrorIncorrectBitmapLength(); - - /// @dev The length of fixed parts of the batch header. - uint256 internal constant BATCH_HEADER_FIXED_LENGTH = 89; - - /// @notice Load batch header in calldata to memory. - /// @param _batchHeader The encoded batch header bytes in calldata. - /// @return batchPtr The start memory offset of the batch header in memory. - /// @return length The length in bytes of the batch header. - function loadAndValidate(bytes calldata _batchHeader) internal pure returns (uint256 batchPtr, uint256 length) { - length = _batchHeader.length; - if (length < BATCH_HEADER_FIXED_LENGTH) revert ErrorBatchHeaderLengthTooSmall(); - - // copy batch header to memory. - assembly { - batchPtr := mload(0x40) - calldatacopy(batchPtr, _batchHeader.offset, length) - mstore(0x40, add(batchPtr, length)) - } - - // check batch header length - uint256 _l1MessagePopped = getL1MessagePopped(batchPtr); - - unchecked { - if (length != BATCH_HEADER_FIXED_LENGTH + ((_l1MessagePopped + 255) / 256) * 32) { - revert ErrorIncorrectBitmapLength(); - } - } - } - - /// @notice Get the version of the batch header. - /// @param batchPtr The start memory offset of the batch header in memory. - /// @return _version The version of the batch header. - function getVersion(uint256 batchPtr) internal pure returns (uint256 _version) { - assembly { - _version := shr(248, mload(batchPtr)) - } - } - - /// @notice Get the batch index of the batch. - /// @param batchPtr The start memory offset of the batch header in memory. - /// @return _batchIndex The batch index of the batch. - function getBatchIndex(uint256 batchPtr) internal pure returns (uint256 _batchIndex) { - assembly { - _batchIndex := shr(192, mload(add(batchPtr, 1))) - } - } - - /// @notice Get the number of L1 messages of the batch. - /// @param batchPtr The start memory offset of the batch header in memory. - /// @return _l1MessagePopped The number of L1 messages of the batch. - function getL1MessagePopped(uint256 batchPtr) internal pure returns (uint256 _l1MessagePopped) { - assembly { - _l1MessagePopped := shr(192, mload(add(batchPtr, 9))) - } - } - - /// @notice Get the number of L1 messages popped before this batch. - /// @param batchPtr The start memory offset of the batch header in memory. - /// @return _totalL1MessagePopped The number of L1 messages popped before this batch. - function getTotalL1MessagePopped(uint256 batchPtr) internal pure returns (uint256 _totalL1MessagePopped) { - assembly { - _totalL1MessagePopped := shr(192, mload(add(batchPtr, 17))) - } - } - - /// @notice Get the data hash of the batch header. - /// @param batchPtr The start memory offset of the batch header in memory. - /// @return _dataHash The data hash of the batch header. - function getDataHash(uint256 batchPtr) internal pure returns (bytes32 _dataHash) { - assembly { - _dataHash := mload(add(batchPtr, 25)) - } - } - - /// @notice Get the parent batch hash of the batch header. - /// @param batchPtr The start memory offset of the batch header in memory. - /// @return _parentBatchHash The parent batch hash of the batch header. - function getParentBatchHash(uint256 batchPtr) internal pure returns (bytes32 _parentBatchHash) { - assembly { - _parentBatchHash := mload(add(batchPtr, 57)) - } - } - - /// @notice Get the start memory offset for skipped L1 messages bitmap. - /// @param batchPtr The start memory offset of the batch header in memory. - /// @return _bitmapPtr the start memory offset for skipped L1 messages bitmap. - function getSkippedBitmapPtr(uint256 batchPtr) internal pure returns (uint256 _bitmapPtr) { - assembly { - _bitmapPtr := add(batchPtr, BATCH_HEADER_FIXED_LENGTH) - } - } - - /// @notice Get the skipped L1 messages bitmap. - /// @param batchPtr The start memory offset of the batch header in memory. - /// @param index The index of bitmap to load. - /// @return _bitmap The bitmap from bits `index * 256` to `index * 256 + 255`. - function getSkippedBitmap(uint256 batchPtr, uint256 index) internal pure returns (uint256 _bitmap) { - assembly { - batchPtr := add(batchPtr, BATCH_HEADER_FIXED_LENGTH) - _bitmap := mload(add(batchPtr, mul(index, 32))) - } - } - - /// @notice Store the version of batch header. - /// @param batchPtr The start memory offset of the batch header in memory. - /// @param _version The version of batch header. - function storeVersion(uint256 batchPtr, uint256 _version) internal pure { - assembly { - mstore8(batchPtr, _version) - } - } - - /// @notice Store the batch index of batch header. - /// @dev Because this function can overwrite the subsequent fields, it must be called before - /// `storeL1MessagePopped`, `storeTotalL1MessagePopped`, and `storeDataHash`. - /// @param batchPtr The start memory offset of the batch header in memory. - /// @param _batchIndex The batch index. - function storeBatchIndex(uint256 batchPtr, uint256 _batchIndex) internal pure { - assembly { - mstore(add(batchPtr, 1), shl(192, _batchIndex)) - } - } - - /// @notice Store the number of L1 messages popped in current batch to batch header. - /// @dev Because this function can overwrite the subsequent fields, it must be called before - /// `storeTotalL1MessagePopped` and `storeDataHash`. - /// @param batchPtr The start memory offset of the batch header in memory. - /// @param _l1MessagePopped The number of L1 messages popped in current batch. - function storeL1MessagePopped(uint256 batchPtr, uint256 _l1MessagePopped) internal pure { - assembly { - mstore(add(batchPtr, 9), shl(192, _l1MessagePopped)) - } - } - - /// @notice Store the total number of L1 messages popped after current batch to batch header. - /// @dev Because this function can overwrite the subsequent fields, it must be called before - /// `storeDataHash`. - /// @param batchPtr The start memory offset of the batch header in memory. - /// @param _totalL1MessagePopped The total number of L1 messages popped after current batch. - function storeTotalL1MessagePopped(uint256 batchPtr, uint256 _totalL1MessagePopped) internal pure { - assembly { - mstore(add(batchPtr, 17), shl(192, _totalL1MessagePopped)) - } - } - - /// @notice Store the data hash of batch header. - /// @param batchPtr The start memory offset of the batch header in memory. - /// @param _dataHash The data hash. - function storeDataHash(uint256 batchPtr, bytes32 _dataHash) internal pure { - assembly { - mstore(add(batchPtr, 25), _dataHash) - } - } - - /// @notice Store the parent batch hash of batch header. - /// @param batchPtr The start memory offset of the batch header in memory. - /// @param _parentBatchHash The parent batch hash. - function storeParentBatchHash(uint256 batchPtr, bytes32 _parentBatchHash) internal pure { - assembly { - mstore(add(batchPtr, 57), _parentBatchHash) - } - } - - /// @notice Store the skipped L1 message bitmap of batch header. - /// @param batchPtr The start memory offset of the batch header in memory. - /// @param _skippedL1MessageBitmap The skipped L1 message bitmap. - function storeSkippedBitmap(uint256 batchPtr, bytes calldata _skippedL1MessageBitmap) internal pure { - assembly { - calldatacopy( - add(batchPtr, BATCH_HEADER_FIXED_LENGTH), - _skippedL1MessageBitmap.offset, - _skippedL1MessageBitmap.length - ) - } - } - - /// @notice Compute the batch hash. - /// @dev Caller should make sure that the encoded batch header is correct. - /// - /// @param batchPtr The start memory offset of the batch header in memory. - /// @param length The length of the batch. - /// @return _batchHash The hash of the corresponding batch. - function computeBatchHash(uint256 batchPtr, uint256 length) internal pure returns (bytes32 _batchHash) { - // in the current version, the hash is: keccak(BatchHeader without timestamp) - assembly { - _batchHash := keccak256(batchPtr, length) - } - } -} diff --git a/contracts/src/libraries/codec/BatchHeaderV1Codec.sol b/contracts/src/libraries/codec/BatchHeaderV1Codec.sol deleted file mode 100644 index 228173c1e..000000000 --- a/contracts/src/libraries/codec/BatchHeaderV1Codec.sol +++ /dev/null @@ -1,230 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.24; - -// solhint-disable no-inline-assembly - -/// @dev Below is the encoding for `BatchHeader` V1, total 121 + ceil(l1MessagePopped / 256) * 32 bytes. -/// ```text -/// * Field Bytes Type Index Comments -/// * version 1 uint8 0 The batch version -/// * batchIndex 8 uint64 1 The index of the batch -/// * l1MessagePopped 8 uint64 9 Number of L1 messages popped in the batch -/// * totalL1MessagePopped 8 uint64 17 Number of total L1 messages popped after the batch -/// * dataHash 32 bytes32 25 The data hash of the batch -/// * blobVersionedHash 32 bytes32 57 The versioned hash of the blob with this batch’s data -/// * parentBatchHash 32 bytes32 89 The parent batch hash -/// * skippedL1MessageBitmap dynamic uint256[] 121 A bitmap to indicate which L1 messages are skipped in the batch -/// ``` -library BatchHeaderV1Codec { - /// @dev Thrown when the length of batch header is smaller than 121. - error ErrorBatchHeaderLengthTooSmall(); - - /// @dev Thrown when the length of skippedL1MessageBitmap is incorrect. - error ErrorIncorrectBitmapLength(); - - /// @dev The length of fixed parts of the batch header. - uint256 internal constant BATCH_HEADER_FIXED_LENGTH = 121; - - /// @notice Load batch header in calldata to memory. - /// @param _batchHeader The encoded batch header bytes in calldata. - /// @return batchPtr The start memory offset of the batch header in memory. - /// @return length The length in bytes of the batch header. - function loadAndValidate(bytes calldata _batchHeader) internal pure returns (uint256 batchPtr, uint256 length) { - length = _batchHeader.length; - if (length < BATCH_HEADER_FIXED_LENGTH) revert ErrorBatchHeaderLengthTooSmall(); - - // copy batch header to memory. - assembly { - batchPtr := mload(0x40) - calldatacopy(batchPtr, _batchHeader.offset, length) - mstore(0x40, add(batchPtr, length)) - } - - // check batch header length - uint256 _l1MessagePopped = getL1MessagePopped(batchPtr); - - unchecked { - if (length != BATCH_HEADER_FIXED_LENGTH + ((_l1MessagePopped + 255) / 256) * 32) - revert ErrorIncorrectBitmapLength(); - } - } - - /// @notice Get the version of the batch header. - /// @param batchPtr The start memory offset of the batch header in memory. - /// @return _version The version of the batch header. - function getVersion(uint256 batchPtr) internal pure returns (uint256 _version) { - assembly { - _version := shr(248, mload(batchPtr)) - } - } - - /// @notice Get the batch index of the batch. - /// @param batchPtr The start memory offset of the batch header in memory. - /// @return _batchIndex The batch index of the batch. - function getBatchIndex(uint256 batchPtr) internal pure returns (uint256 _batchIndex) { - assembly { - _batchIndex := shr(192, mload(add(batchPtr, 1))) - } - } - - /// @notice Get the number of L1 messages of the batch. - /// @param batchPtr The start memory offset of the batch header in memory. - /// @return _l1MessagePopped The number of L1 messages of the batch. - function getL1MessagePopped(uint256 batchPtr) internal pure returns (uint256 _l1MessagePopped) { - assembly { - _l1MessagePopped := shr(192, mload(add(batchPtr, 9))) - } - } - - /// @notice Get the number of L1 messages popped before this batch. - /// @param batchPtr The start memory offset of the batch header in memory. - /// @return _totalL1MessagePopped The number of L1 messages popped before this batch. - function getTotalL1MessagePopped(uint256 batchPtr) internal pure returns (uint256 _totalL1MessagePopped) { - assembly { - _totalL1MessagePopped := shr(192, mload(add(batchPtr, 17))) - } - } - - /// @notice Get the data hash of the batch header. - /// @param batchPtr The start memory offset of the batch header in memory. - /// @return _dataHash The data hash of the batch header. - function getDataHash(uint256 batchPtr) internal pure returns (bytes32 _dataHash) { - assembly { - _dataHash := mload(add(batchPtr, 25)) - } - } - - /// @notice Get the blob versioned hash of the batch header. - /// @param batchPtr The start memory offset of the batch header in memory. - /// @return _blobVersionedHash The blob versioned hash of the batch header. - function getBlobVersionedHash(uint256 batchPtr) internal pure returns (bytes32 _blobVersionedHash) { - assembly { - _blobVersionedHash := mload(add(batchPtr, 57)) - } - } - - /// @notice Get the parent batch hash of the batch header. - /// @param batchPtr The start memory offset of the batch header in memory. - /// @return _parentBatchHash The parent batch hash of the batch header. - function getParentBatchHash(uint256 batchPtr) internal pure returns (bytes32 _parentBatchHash) { - assembly { - _parentBatchHash := mload(add(batchPtr, 89)) - } - } - - /// @notice Get the start memory offset for skipped L1 messages bitmap. - /// @param batchPtr The start memory offset of the batch header in memory. - /// @return _bitmapPtr the start memory offset for skipped L1 messages bitmap. - function getSkippedBitmapPtr(uint256 batchPtr) internal pure returns (uint256 _bitmapPtr) { - assembly { - _bitmapPtr := add(batchPtr, BATCH_HEADER_FIXED_LENGTH) - } - } - - /// @notice Get the skipped L1 messages bitmap. - /// @param batchPtr The start memory offset of the batch header in memory. - /// @param index The index of bitmap to load. - /// @return _bitmap The bitmap from bits `index * 256` to `index * 256 + 255`. - function getSkippedBitmap(uint256 batchPtr, uint256 index) internal pure returns (uint256 _bitmap) { - assembly { - batchPtr := add(batchPtr, BATCH_HEADER_FIXED_LENGTH) - _bitmap := mload(add(batchPtr, mul(index, 32))) - } - } - - /// @notice Store the version of batch header. - /// @param batchPtr The start memory offset of the batch header in memory. - /// @param _version The version of batch header. - function storeVersion(uint256 batchPtr, uint256 _version) internal pure { - assembly { - mstore8(batchPtr, _version) - } - } - - /// @notice Store the batch index of batch header. - /// @dev Because this function can overwrite the subsequent fields, it must be called before - /// `storeL1MessagePopped`, `storeTotalL1MessagePopped`, and `storeDataHash`. - /// @param batchPtr The start memory offset of the batch header in memory. - /// @param _batchIndex The batch index. - function storeBatchIndex(uint256 batchPtr, uint256 _batchIndex) internal pure { - assembly { - mstore(add(batchPtr, 1), shl(192, _batchIndex)) - } - } - - /// @notice Store the number of L1 messages popped in current batch to batch header. - /// @dev Because this function can overwrite the subsequent fields, it must be called before - /// `storeTotalL1MessagePopped` and `storeDataHash`. - /// @param batchPtr The start memory offset of the batch header in memory. - /// @param _l1MessagePopped The number of L1 messages popped in current batch. - function storeL1MessagePopped(uint256 batchPtr, uint256 _l1MessagePopped) internal pure { - assembly { - mstore(add(batchPtr, 9), shl(192, _l1MessagePopped)) - } - } - - /// @notice Store the total number of L1 messages popped after current batch to batch header. - /// @dev Because this function can overwrite the subsequent fields, it must be called before - /// `storeDataHash`. - /// @param batchPtr The start memory offset of the batch header in memory. - /// @param _totalL1MessagePopped The total number of L1 messages popped after current batch. - function storeTotalL1MessagePopped(uint256 batchPtr, uint256 _totalL1MessagePopped) internal pure { - assembly { - mstore(add(batchPtr, 17), shl(192, _totalL1MessagePopped)) - } - } - - /// @notice Store the data hash of batch header. - /// @param batchPtr The start memory offset of the batch header in memory. - /// @param _dataHash The data hash. - function storeDataHash(uint256 batchPtr, bytes32 _dataHash) internal pure { - assembly { - mstore(add(batchPtr, 25), _dataHash) - } - } - - /// @notice Store the parent batch hash of batch header. - /// @param batchPtr The start memory offset of the batch header in memory. - /// @param _blobVersionedHash The versioned hash of the blob with this batch’s data. - function storeBlobVersionedHash(uint256 batchPtr, bytes32 _blobVersionedHash) internal pure { - assembly { - mstore(add(batchPtr, 57), _blobVersionedHash) - } - } - - /// @notice Store the parent batch hash of batch header. - /// @param batchPtr The start memory offset of the batch header in memory. - /// @param _parentBatchHash The parent batch hash. - function storeParentBatchHash(uint256 batchPtr, bytes32 _parentBatchHash) internal pure { - assembly { - mstore(add(batchPtr, 89), _parentBatchHash) - } - } - - /// @notice Store the skipped L1 message bitmap of batch header. - /// @param batchPtr The start memory offset of the batch header in memory. - /// @param _skippedL1MessageBitmap The skipped L1 message bitmap. - function storeSkippedBitmap(uint256 batchPtr, bytes calldata _skippedL1MessageBitmap) internal pure { - assembly { - calldatacopy( - add(batchPtr, BATCH_HEADER_FIXED_LENGTH), - _skippedL1MessageBitmap.offset, - _skippedL1MessageBitmap.length - ) - } - } - - /// @notice Compute the batch hash. - /// @dev Caller should make sure that the encoded batch header is correct. - /// - /// @param batchPtr The start memory offset of the batch header in memory. - /// @param length The length of the batch. - /// @return _batchHash The hash of the corresponding batch. - function computeBatchHash(uint256 batchPtr, uint256 length) internal pure returns (bytes32 _batchHash) { - // in the current version, the hash is: keccak(BatchHeader without timestamp) - assembly { - _batchHash := keccak256(batchPtr, length) - } - } -} diff --git a/contracts/src/libraries/codec/ChunkCodecV0.sol b/contracts/src/libraries/codec/ChunkCodecV0.sol deleted file mode 100644 index 1d4751c75..000000000 --- a/contracts/src/libraries/codec/ChunkCodecV0.sol +++ /dev/null @@ -1,130 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.24; - -/// @dev Below is the encoding for `Chunk`, total 60*n+1+m bytes. -/// ```text -/// * Field Bytes Type Index Comments -/// * numBlocks 1 uint8 0 The number of blocks in this chunk -/// * block[0] 60 BlockContext 1 The first block in this chunk -/// * ...... -/// * block[i] 60 BlockContext 60*i+1 The (i+1)'th block in this chunk -/// * ...... -/// * block[n-1] 60 BlockContext 60*n-59 The last block in this chunk -/// * l2Transactions dynamic bytes 60*n+1 -/// ``` -/// -/// @dev Below is the encoding for `BlockContext`, total 60 bytes. -/// ```text -/// * Field Bytes Type Index Comments -/// * blockNumber 8 uint64 0 The height of this block. -/// * timestamp 8 uint64 8 The timestamp of this block. -/// * baseFee 32 uint256 16 The base fee of this block. -/// * gasLimit 8 uint64 48 The gas limit of this block. -/// * numTransactions 2 uint16 56 The number of transactions in this block, both L1 & L2 txs. -/// * numL1Messages 2 uint16 58 The number of l1 messages in this block. -/// ``` -library ChunkCodecV0 { - /// @dev Thrown when no blocks in chunk. - error ErrorNoBlockInChunk(); - - /// @dev Thrown when the length of chunk is incorrect. - error ErrorIncorrectChunkLength(); - - /// @dev The length of one block context. - uint256 internal constant BLOCK_CONTEXT_LENGTH = 60; - - /// @notice Validate the length of chunk. - /// @param chunkPtr The start memory offset of the chunk in memory. - /// @param _length The length of the chunk. - /// @return _numBlocks The number of blocks in current chunk. - function validateChunkLength(uint256 chunkPtr, uint256 _length) internal pure returns (uint256 _numBlocks) { - _numBlocks = getNumBlocks(chunkPtr); - - // should contain at least one block - if (_numBlocks == 0) revert ErrorNoBlockInChunk(); - - // should contain at least the number of the blocks and block contexts - if (_length < 1 + _numBlocks * BLOCK_CONTEXT_LENGTH) revert ErrorIncorrectChunkLength(); - } - - /// @notice Return the start memory offset of `l2Transactions`. - /// @dev The caller should make sure `_numBlocks` is correct. - /// @param chunkPtr The start memory offset of the chunk in memory. - /// @param _numBlocks The number of blocks in current chunk. - /// @return _l2TxPtr the start memory offset of `l2Transactions`. - function getL2TxPtr(uint256 chunkPtr, uint256 _numBlocks) internal pure returns (uint256 _l2TxPtr) { - unchecked { - _l2TxPtr = chunkPtr + 1 + _numBlocks * BLOCK_CONTEXT_LENGTH; - } - } - - /// @notice Return the number of blocks in current chunk. - /// @param chunkPtr The start memory offset of the chunk in memory. - /// @return _numBlocks The number of blocks in current chunk. - function getNumBlocks(uint256 chunkPtr) internal pure returns (uint256 _numBlocks) { - assembly { - _numBlocks := shr(248, mload(chunkPtr)) - } - } - - /// @notice Copy the block context to another memory. - /// @param chunkPtr The start memory offset of the chunk in memory. - /// @param dstPtr The destination memory offset to store the block context. - /// @param index The index of block context to copy. - /// @return uint256 The new destination memory offset after copy. - function copyBlockContext( - uint256 chunkPtr, - uint256 dstPtr, - uint256 index - ) internal pure returns (uint256) { - // only first 58 bytes is needed. - assembly { - chunkPtr := add(chunkPtr, add(1, mul(BLOCK_CONTEXT_LENGTH, index))) - mstore(dstPtr, mload(chunkPtr)) // first 32 bytes - mstore( - add(dstPtr, 0x20), - and(mload(add(chunkPtr, 0x20)), 0xffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000) - ) // next 26 bytes - - dstPtr := add(dstPtr, 58) - } - - return dstPtr; - } - - /// @notice Return the number of transactions in current block. - /// @param blockPtr The start memory offset of the block context in memory. - /// @return _numTransactions The number of transactions in current block. - function getNumTransactions(uint256 blockPtr) internal pure returns (uint256 _numTransactions) { - assembly { - _numTransactions := shr(240, mload(add(blockPtr, 56))) - } - } - - /// @notice Return the number of L1 messages in current block. - /// @param blockPtr The start memory offset of the block context in memory. - /// @return _numL1Messages The number of L1 messages in current block. - function getNumL1Messages(uint256 blockPtr) internal pure returns (uint256 _numL1Messages) { - assembly { - _numL1Messages := shr(240, mload(add(blockPtr, 58))) - } - } - - /// @notice Compute and load the transaction hash. - /// @param _l2TxPtr The start memory offset of the transaction in memory. - /// @return bytes32 The transaction hash of the transaction. - /// @return uint256 The start memory offset of the next transaction in memory. - function loadL2TxHash(uint256 _l2TxPtr) internal pure returns (bytes32, uint256) { - bytes32 txHash; - assembly { - // first 4 bytes indicate the length - let txPayloadLength := shr(224, mload(_l2TxPtr)) - _l2TxPtr := add(_l2TxPtr, 4) - txHash := keccak256(_l2TxPtr, txPayloadLength) - _l2TxPtr := add(_l2TxPtr, txPayloadLength) - } - - return (txHash, _l2TxPtr); - } -} diff --git a/contracts/src/libraries/codec/ChunkCodecV1.sol b/contracts/src/libraries/codec/ChunkCodecV1.sol deleted file mode 100644 index 51f099308..000000000 --- a/contracts/src/libraries/codec/ChunkCodecV1.sol +++ /dev/null @@ -1,86 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.24; - -import {ChunkCodecV0} from "./ChunkCodecV0.sol"; - -/// @dev Below is the encoding for `Chunk`, total 60*n+1 bytes. -/// The only difference between `ChunkCodecV0` is we remove `l2Transactions` from chunk encoding. -/// ```text -/// * Field Bytes Type Index Comments -/// * numBlocks 1 uint8 0 The number of blocks in this chunk -/// * block[0] 60 BlockContext 1 The first block in this chunk -/// * ...... -/// * block[i] 60 BlockContext 60*i+1 The (i+1)'th block in this chunk -/// * ...... -/// * block[n-1] 60 BlockContext 60*n-59 The last block in this chunk -/// ``` -/// -/// @dev Below is the encoding for `BlockContext`, total 60 bytes. -/// ```text -/// * Field Bytes Type Index Comments -/// * blockNumber 8 uint64 0 The height of this block. -/// * timestamp 8 uint64 8 The timestamp of this block. -/// * baseFee 32 uint256 16 The base fee of this block. -/// * gasLimit 8 uint64 48 The gas limit of this block. -/// * numTransactions 2 uint16 56 The number of transactions in this block, both L1 & L2 txs. -/// * numL1Messages 2 uint16 58 The number of l1 messages in this block. -/// ``` -library ChunkCodecV1 { - /// @dev Thrown when no blocks in chunk. - error ErrorNoBlockInChunk(); - - /// @dev Thrown when the length of chunk is incorrect. - error ErrorIncorrectChunkLength(); - - /// @dev The length of one block context. - uint256 internal constant BLOCK_CONTEXT_LENGTH = 60; - - /// @notice Validate the length of chunk. - /// @param chunkPtr The start memory offset of the chunk in memory. - /// @param _length The length of the chunk. - /// @return _numBlocks The number of blocks in current chunk. - function validateChunkLength(uint256 chunkPtr, uint256 _length) internal pure returns (uint256 _numBlocks) { - _numBlocks = getNumBlocks(chunkPtr); - - // should contain at least one block - if (_numBlocks == 0) revert ErrorNoBlockInChunk(); - - // should contain the number of the blocks and block contexts - if (_length != 1 + _numBlocks * BLOCK_CONTEXT_LENGTH) revert ErrorIncorrectChunkLength(); - } - - /// @notice Return the number of blocks in current chunk. - /// @param chunkPtr The start memory offset of the chunk in memory. - /// @return _numBlocks The number of blocks in current chunk. - function getNumBlocks(uint256 chunkPtr) internal pure returns (uint256 _numBlocks) { - return ChunkCodecV0.getNumBlocks(chunkPtr); - } - - /// @notice Copy the block context to another memory. - /// @param chunkPtr The start memory offset of the chunk in memory. - /// @param dstPtr The destination memory offset to store the block context. - /// @param index The index of block context to copy. - /// @return uint256 The new destination memory offset after copy. - function copyBlockContext( - uint256 chunkPtr, - uint256 dstPtr, - uint256 index - ) internal pure returns (uint256) { - return ChunkCodecV0.copyBlockContext(chunkPtr, dstPtr, index); - } - - /// @notice Return the number of transactions in current block. - /// @param blockPtr The start memory offset of the block context in memory. - /// @return _numTransactions The number of transactions in current block. - function getNumTransactions(uint256 blockPtr) internal pure returns (uint256 _numTransactions) { - return ChunkCodecV0.getNumTransactions(blockPtr); - } - - /// @notice Return the number of L1 messages in current block. - /// @param blockPtr The start memory offset of the block context in memory. - /// @return _numL1Messages The number of L1 messages in current block. - function getNumL1Messages(uint256 blockPtr) internal pure returns (uint256 _numL1Messages) { - return ChunkCodecV0.getNumL1Messages(blockPtr); - } -} diff --git a/contracts/src/libraries/common/AddressAliasHelper.sol b/contracts/src/libraries/common/AddressAliasHelper.sol deleted file mode 100644 index b618f5869..000000000 --- a/contracts/src/libraries/common/AddressAliasHelper.sol +++ /dev/null @@ -1,28 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.24; - -library AddressAliasHelper { - /// @dev The offset added to the address in L1. - uint160 internal constant OFFSET = uint160(0x1111000000000000000000000000000000001111); - - /// @notice Utility function that converts the address in the L1 that submitted a tx to - /// the inbox to the msg.sender viewed in the L2 - /// @param l1Address the address in the L1 that triggered the tx to L2 - /// @return l2Address L2 address as viewed in msg.sender - function applyL1ToL2Alias(address l1Address) internal pure returns (address l2Address) { - unchecked { - l2Address = address(uint160(l1Address) + OFFSET); - } - } - - /// @notice Utility function that converts the msg.sender viewed in the L2 to the - /// address in the L1 that submitted a tx to the inbox - /// @param l2Address L2 address as viewed in msg.sender - /// @return l1Address the address in the L1 that triggered the tx to L2 - function undoL1ToL2Alias(address l2Address) internal pure returns (address l1Address) { - unchecked { - l1Address = address(uint160(l2Address) - OFFSET); - } - } -} diff --git a/contracts/src/libraries/common/AppendOnlyMerkleTree.sol b/contracts/src/libraries/common/AppendOnlyMerkleTree.sol deleted file mode 100644 index 23337bb3a..000000000 --- a/contracts/src/libraries/common/AppendOnlyMerkleTree.sol +++ /dev/null @@ -1,73 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.24; - -abstract contract AppendOnlyMerkleTree { - /// @dev The maximum height of the withdraw merkle tree. - uint256 private constant MAX_TREE_HEIGHT = 40; - - /// @notice The merkle root of the current merkle tree. - /// @dev This is actual equal to `branches[n]`. - bytes32 public messageRoot; - - /// @notice The next unused message index. - uint256 public nextMessageIndex; - - /// @notice The list of zero hash in each height. - bytes32[MAX_TREE_HEIGHT] private zeroHashes; - - /// @notice The list of minimum merkle proofs needed to compute next root. - /// @dev Only first `n` elements are used, where `n` is the minimum value that `2^{n-1} >= currentMaxNonce + 1`. - /// It means we only use `currentMaxNonce + 1` leaf nodes to construct the merkle tree. - bytes32[MAX_TREE_HEIGHT] public branches; - - function _initializeMerkleTree() internal { - // Compute hashes in empty sparse Merkle tree - for (uint256 height = 0; height + 1 < MAX_TREE_HEIGHT; height++) { - zeroHashes[height + 1] = _efficientHash(zeroHashes[height], zeroHashes[height]); - } - } - - function _appendMessageHash(bytes32 _messageHash) internal returns (uint256, bytes32) { - require(zeroHashes[1] != bytes32(0), "call before initialization"); - - uint256 _currentMessageIndex = nextMessageIndex; - bytes32 _hash = _messageHash; - uint256 _height = 0; - - while (_currentMessageIndex != 0) { - if (_currentMessageIndex % 2 == 0) { - // it may be used in next round. - branches[_height] = _hash; - // it's a left child, the right child must be null - _hash = _efficientHash(_hash, zeroHashes[_height]); - } else { - // it's a right child, use previously computed hash - _hash = _efficientHash(branches[_height], _hash); - } - unchecked { - _height += 1; - } - _currentMessageIndex >>= 1; - } - - branches[_height] = _hash; - messageRoot = _hash; - - _currentMessageIndex = nextMessageIndex; - unchecked { - nextMessageIndex = _currentMessageIndex + 1; - } - - return (_currentMessageIndex, _hash); - } - - function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) { - // solhint-disable-next-line no-inline-assembly - assembly { - mstore(0x00, a) - mstore(0x20, b) - value := keccak256(0x00, 0x40) - } - } -} diff --git a/contracts/src/libraries/common/IWhitelist.sol b/contracts/src/libraries/common/IWhitelist.sol deleted file mode 100644 index a5187e365..000000000 --- a/contracts/src/libraries/common/IWhitelist.sol +++ /dev/null @@ -1,9 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.24; - -interface IWhitelist { - /// @notice Check whether the sender is allowed to do something. - /// @param _sender The address of sender. - function isSenderAllowed(address _sender) external view returns (bool); -} diff --git a/contracts/src/libraries/common/OwnableBase.sol b/contracts/src/libraries/common/OwnableBase.sol deleted file mode 100644 index 71b5aefab..000000000 --- a/contracts/src/libraries/common/OwnableBase.sol +++ /dev/null @@ -1,63 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.24; - -abstract contract OwnableBase { - /********** - * Events * - **********/ - - /// @notice Emitted when owner is changed by current owner. - /// @param _oldOwner The address of previous owner. - /// @param _newOwner The address of new owner. - event OwnershipTransferred(address indexed _oldOwner, address indexed _newOwner); - - /************* - * Variables * - *************/ - - /// @notice The address of the current owner. - address public owner; - - /********************** - * Function Modifiers * - **********************/ - - /// @dev Throws if called by any account other than the owner. - modifier onlyOwner() { - require(owner == msg.sender, "caller is not the owner"); - _; - } - - /************************ - * Restricted Functions * - ************************/ - - /// @notice Leaves the contract without owner. It will not be possible to call - /// `onlyOwner` functions anymore. Can only be called by the current owner. - /// - /// @dev Renouncing ownership will leave the contract without an owner, - /// thereby removing any functionality that is only available to the owner. - function renounceOwnership() public onlyOwner { - _transferOwnership(address(0)); - } - - /// @notice Transfers ownership of the contract to a new account (`newOwner`). - /// Can only be called by the current owner. - function transferOwnership(address _newOwner) public onlyOwner { - require(_newOwner != address(0), "new owner is the zero address"); - _transferOwnership(_newOwner); - } - - /********************** - * Internal Functions * - **********************/ - - /// @dev Transfers ownership of the contract to a new account (`newOwner`). - /// Internal function without access restriction. - function _transferOwnership(address _newOwner) internal { - address _oldOwner = owner; - owner = _newOwner; - emit OwnershipTransferred(_oldOwner, _newOwner); - } -} diff --git a/contracts/src/libraries/constants/ScrollConstants.sol b/contracts/src/libraries/constants/ScrollConstants.sol deleted file mode 100644 index db9489b57..000000000 --- a/contracts/src/libraries/constants/ScrollConstants.sol +++ /dev/null @@ -1,12 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.24; - -library ScrollConstants { - /// @notice The address of default cross chain message sender. - address internal constant DEFAULT_XDOMAIN_MESSAGE_SENDER = address(1); - - /// @notice The address for dropping message. - /// @dev The first 20 bytes of keccak("drop") - address internal constant DROP_XDOMAIN_MESSAGE_SENDER = 0x6f297C61B5C92eF107fFD30CD56AFFE5A273e841; -} diff --git a/contracts/src/libraries/constants/ScrollPredeploy.sol b/contracts/src/libraries/constants/ScrollPredeploy.sol deleted file mode 100644 index 93fbeb320..000000000 --- a/contracts/src/libraries/constants/ScrollPredeploy.sol +++ /dev/null @@ -1,11 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.24; - -library ScrollPredeploy { - address internal constant L1_MESSAGE_QUEUE = 0x5300000000000000000000000000000000000000; - - address internal constant L1_BLOCK_CONTAINER = 0x5300000000000000000000000000000000000001; - - address internal constant L1_GAS_PRICE_ORACLE = 0x5300000000000000000000000000000000000002; -} diff --git a/contracts/src/libraries/gateway/CCTPGatewayBase.sol b/contracts/src/libraries/gateway/CCTPGatewayBase.sol deleted file mode 100644 index 54437042c..000000000 --- a/contracts/src/libraries/gateway/CCTPGatewayBase.sol +++ /dev/null @@ -1,100 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import {IMessageTransmitter} from "../../interfaces/IMessageTransmitter.sol"; - -import {ScrollGatewayBase} from "./ScrollGatewayBase.sol"; - -/// @title CCTPGatewayBase -/// @notice The `CCTPGatewayBase` is a base contract for USDC gateways with CCTP supports. -abstract contract CCTPGatewayBase is ScrollGatewayBase { - /********* - * Enums * - *********/ - - enum CCTPMessageStatus { - None, - Pending, - Relayed - } - - /************* - * Constants * - *************/ - - /// @notice The address of L1 USDC address. - address public immutable l1USDC; - - /// @notice The address of L2 USDC address. - address public immutable l2USDC; - - /// @notice The destination domain for layer2. - uint32 public immutable destinationDomain; - - /************* - * Variables * - *************/ - - /// @notice The address of TokenMessenger in local domain. - address public cctpMessenger; - - /// @notice The address of MessageTransmitter in local domain. - address public cctpTransmitter; - - /// @notice Mapping from destination domain CCTP nonce to status. - mapping(uint256 => CCTPMessageStatus) public status; - - /// @dev The storage slots for future usage. - uint256[47] private __gap; - - /*************** - * Constructor * - ***************/ - - constructor( - address _l1USDC, - address _l2USDC, - uint32 _destinationDomain - ) { - l1USDC = _l1USDC; - l2USDC = _l2USDC; - destinationDomain = _destinationDomain; - } - - function _initialize(address _cctpMessenger, address _cctpTransmitter) internal { - cctpMessenger = _cctpMessenger; - cctpTransmitter = _cctpTransmitter; - } - - /***************************** - * Public Mutating Functions * - *****************************/ - - /// @notice Claim USDC that has been cross chained. - /// @param _nonce The nonce of the message from CCTP. - /// @param _cctpMessage The message passed to MessageTransmitter contract in CCTP. - /// @param _cctpSignature The message passed to MessageTransmitter contract in CCTP. - function claimUSDC( - uint256 _nonce, - bytes calldata _cctpMessage, - bytes calldata _cctpSignature - ) public { - // Check `_nonce` match with `_cctpMessage`. - // According to the encoding of `_cctpMessage`, the nonce is in bytes 12 to 16. - // See here: https://github.com/circlefin/evm-cctp-contracts/blob/master/src/messages/Message.sol#L29 - uint256 _expectedMessageNonce; - assembly { - _expectedMessageNonce := and(shr(96, calldataload(_cctpMessage.offset)), 0xffffffffffffffff) - } - require(_expectedMessageNonce == _nonce, "nonce mismatch"); - - require(status[_nonce] == CCTPMessageStatus.Pending, "message not relayed"); - - // call transmitter to mint USDC - bool _success = IMessageTransmitter(cctpTransmitter).receiveMessage(_cctpMessage, _cctpSignature); - require(_success, "call transmitter failed"); - - status[_nonce] = CCTPMessageStatus.Relayed; - } -} diff --git a/contracts/src/libraries/gateway/IScrollGateway.sol b/contracts/src/libraries/gateway/IScrollGateway.sol deleted file mode 100644 index 955253d41..000000000 --- a/contracts/src/libraries/gateway/IScrollGateway.sol +++ /dev/null @@ -1,34 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.24; - -interface IScrollGateway { - /********** - * Errors * - **********/ - - /// @dev Thrown when the given address is `address(0)`. - error ErrorZeroAddress(); - - /// @dev Thrown when the caller is not corresponding `L1ScrollMessenger` or `L2ScrollMessenger`. - error ErrorCallerIsNotMessenger(); - - /// @dev Thrown when the cross chain sender is not the counterpart gateway contract. - error ErrorCallerIsNotCounterpartGateway(); - - /// @dev Thrown when ScrollMessenger is not dropping message. - error ErrorNotInDropMessageContext(); - - /************************* - * Public View Functions * - *************************/ - - /// @notice The address of corresponding L1/L2 Gateway contract. - function counterpart() external view returns (address); - - /// @notice The address of L1GatewayRouter/L2GatewayRouter contract. - function router() external view returns (address); - - /// @notice The address of corresponding L1ScrollMessenger/L2ScrollMessenger contract. - function messenger() external view returns (address); -} diff --git a/contracts/src/libraries/gateway/ScrollGatewayBase.sol b/contracts/src/libraries/gateway/ScrollGatewayBase.sol deleted file mode 100644 index 4bc49ebc8..000000000 --- a/contracts/src/libraries/gateway/ScrollGatewayBase.sol +++ /dev/null @@ -1,118 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.24; - -import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; -import {ReentrancyGuardUpgradeable} from "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol"; - -import {IScrollGateway} from "./IScrollGateway.sol"; -import {IScrollMessenger} from "../IScrollMessenger.sol"; -import {IScrollGatewayCallback} from "../callbacks/IScrollGatewayCallback.sol"; -import {ScrollConstants} from "../constants/ScrollConstants.sol"; -import {ITokenRateLimiter} from "../../rate-limiter/ITokenRateLimiter.sol"; - -/// @title ScrollGatewayBase -/// @notice The `ScrollGatewayBase` is a base contract for gateway contracts used in both in L1 and L2. -abstract contract ScrollGatewayBase is ReentrancyGuardUpgradeable, OwnableUpgradeable, IScrollGateway { - /************* - * Constants * - *************/ - - /// @inheritdoc IScrollGateway - address public immutable override counterpart; - - /// @inheritdoc IScrollGateway - address public immutable override router; - - /// @inheritdoc IScrollGateway - address public immutable override messenger; - - /************* - * Variables * - *************/ - - /// @dev The storage slot used as counterpart gateway contract, which is deprecated now. - address private __counterpart; - - /// @dev The storage slot used as gateway router contract, which is deprecated now. - address private __router; - - /// @dev The storage slot used as scroll messenger contract, which is deprecated now. - address private __messenger; - - /// @dev The storage slot used as token rate limiter contract, which is deprecated now. - address private __rateLimiter; - - /// @dev The storage slots for future usage. - uint256[46] private __gap; - - /********************** - * Function Modifiers * - **********************/ - - modifier onlyCallByCounterpart() { - // check caller is messenger - if (_msgSender() != messenger) { - revert ErrorCallerIsNotMessenger(); - } - - // check cross domain caller is counterpart gateway - if (counterpart != IScrollMessenger(messenger).xDomainMessageSender()) { - revert ErrorCallerIsNotCounterpartGateway(); - } - _; - } - - modifier onlyInDropContext() { - // check caller is messenger - if (_msgSender() != messenger) { - revert ErrorCallerIsNotMessenger(); - } - - // check we are dropping message in ScrollMessenger. - if (ScrollConstants.DROP_XDOMAIN_MESSAGE_SENDER != IScrollMessenger(messenger).xDomainMessageSender()) { - revert ErrorNotInDropMessageContext(); - } - _; - } - - /*************** - * Constructor * - ***************/ - - constructor( - address _counterpart, - address _router, - address _messenger - ) { - if (_counterpart == address(0) || _messenger == address(0)) { - revert ErrorZeroAddress(); - } - - counterpart = _counterpart; - router = _router; - messenger = _messenger; - } - - function _initialize( - address, - address, - address - ) internal { - ReentrancyGuardUpgradeable.__ReentrancyGuard_init(); - OwnableUpgradeable.__Ownable_init(); - } - - /********************** - * Internal Functions * - **********************/ - - /// @dev Internal function to forward calldata to target contract. - /// @param _to The address of contract to call. - /// @param _data The calldata passed to the contract. - function _doCallback(address _to, bytes memory _data) internal { - if (_data.length > 0 && _to.code.length > 0) { - IScrollGatewayCallback(_to).onScrollGatewayCallback(_data); - } - } -} diff --git a/contracts/src/libraries/token/IScrollERC1155.sol b/contracts/src/libraries/token/IScrollERC1155.sol deleted file mode 100644 index bbc92c075..000000000 --- a/contracts/src/libraries/token/IScrollERC1155.sol +++ /dev/null @@ -1,13 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.24; - -import {IERC1155} from "@openzeppelin/contracts/token/ERC1155/IERC1155.sol"; -import {IScrollERC1155Extension} from "./IScrollERC1155Extension.sol"; - -// The recommended ERC1155 implementation for bridge token. -// deployed in L2 when original token is on L1 -// deployed in L1 when original token is on L2 -interface IScrollERC1155 is IERC1155, IScrollERC1155Extension { - -} diff --git a/contracts/src/libraries/token/IScrollERC1155Extension.sol b/contracts/src/libraries/token/IScrollERC1155Extension.sol deleted file mode 100644 index 45176bb7d..000000000 --- a/contracts/src/libraries/token/IScrollERC1155Extension.sol +++ /dev/null @@ -1,60 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -// Functions needed on top of the ERC1155 standard to be compliant with the Scroll bridge -interface IScrollERC1155Extension { - /// @notice Return the address of Gateway the token belongs to. - function gateway() external view returns (address); - - /// @notice Return the address of counterpart token. - function counterpart() external view returns (address); - - /// @notice Mint some token to recipient's account. - /// @dev Gateway Utilities, only gateway contract can call - /// @param _to The address of recipient. - /// @param _tokenId The token id to mint. - /// @param _amount The amount of token to mint. - /// @param _data The data passed to recipient - function mint( - address _to, - uint256 _tokenId, - uint256 _amount, - bytes memory _data - ) external; - - /// @notice Burn some token from account. - /// @dev Gateway Utilities, only gateway contract can call - /// @param _from The address of account to burn token. - /// @param _tokenId The token id to burn. - /// @param _amount The amount of token to burn. - function burn( - address _from, - uint256 _tokenId, - uint256 _amount - ) external; - - /// @notice Batch mint some token to recipient's account. - /// @dev Gateway Utilities, only gateway contract can call - /// @param _to The address of recipient. - /// @param _tokenIds The token id to mint. - /// @param _amounts The list of corresponding amount of token to mint. - /// @param _data The data passed to recipient - function batchMint( - address _to, - uint256[] calldata _tokenIds, - uint256[] calldata _amounts, - bytes calldata _data - ) external; - - /// @notice Batch burn some token from account. - /// @dev Gateway Utilities, only gateway contract can call - /// @param _from The address of account to burn token. - /// @param _tokenIds The list of token ids to burn. - /// @param _amounts The list of corresponding amount of token to burn. - function batchBurn( - address _from, - uint256[] calldata _tokenIds, - uint256[] calldata _amounts - ) external; -} diff --git a/contracts/src/libraries/token/IScrollERC20.sol b/contracts/src/libraries/token/IScrollERC20.sol deleted file mode 100644 index 6904e647c..000000000 --- a/contracts/src/libraries/token/IScrollERC20.sol +++ /dev/null @@ -1,14 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.24; - -import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import {IERC20Permit} from "@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol"; -import {IScrollERC20Extension} from "./IScrollERC20Extension.sol"; - -// The recommended ERC20 implementation for bridge token. -// deployed in L2 when original token is on L1 -// deployed in L1 when original token is on L2 -interface IScrollERC20 is IERC20, IERC20Permit, IScrollERC20Extension { - -} diff --git a/contracts/src/libraries/token/IScrollERC20Extension.sol b/contracts/src/libraries/token/IScrollERC20Extension.sol deleted file mode 100644 index d6f3999b4..000000000 --- a/contracts/src/libraries/token/IScrollERC20Extension.sol +++ /dev/null @@ -1,33 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -// Functions needed on top of the ERC20 standard to be compliant with the Scroll bridge -interface IScrollERC20Extension { - /// @notice Return the address of Gateway the token belongs to. - function gateway() external view returns (address); - - /// @notice Return the address of counterpart token. - function counterpart() external view returns (address); - - /// @dev ERC677 Standard, see https://github.com/ethereum/EIPs/issues/677 - /// Defi can use this method to transfer L1/L2 token to L2/L1, - /// and deposit to L2/L1 contract in one transaction - function transferAndCall( - address receiver, - uint256 amount, - bytes calldata data - ) external returns (bool success); - - /// @notice Mint some token to recipient's account. - /// @dev Gateway Utilities, only gateway contract can call - /// @param _to The address of recipient. - /// @param _amount The amount of token to mint. - function mint(address _to, uint256 _amount) external; - - /// @notice Mint some token from account. - /// @dev Gateway Utilities, only gateway contract can call - /// @param _from The address of account to burn token. - /// @param _amount The amount of token to mint. - function burn(address _from, uint256 _amount) external; -} diff --git a/contracts/src/libraries/token/IScrollERC20Upgradeable.sol b/contracts/src/libraries/token/IScrollERC20Upgradeable.sol deleted file mode 100644 index 1358623bf..000000000 --- a/contracts/src/libraries/token/IScrollERC20Upgradeable.sol +++ /dev/null @@ -1,38 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.24; - -import {IERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; -import {IERC20PermitUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol"; - -// The recommended ERC20 implementation for bridge token. -// deployed in L2 when original token is on L1 -// deployed in L1 when original token is on L2 -interface IScrollERC20Upgradeable is IERC20Upgradeable, IERC20PermitUpgradeable { - /// @notice Return the address of Gateway the token belongs to. - function gateway() external view returns (address); - - /// @notice Return the address of counterpart token. - function counterpart() external view returns (address); - - /// @dev ERC677 Standard, see https://github.com/ethereum/EIPs/issues/677 - /// Defi can use this method to transfer L1/L2 token to L2/L1, - /// and deposit to L2/L1 contract in one transaction - function transferAndCall( - address receiver, - uint256 amount, - bytes calldata data - ) external returns (bool success); - - /// @notice Mint some token to recipient's account. - /// @dev Gateway Utilities, only gateway contract can call - /// @param _to The address of recipient. - /// @param _amount The amount of token to mint. - function mint(address _to, uint256 _amount) external; - - /// @notice Mint some token from account. - /// @dev Gateway Utilities, only gateway contract can call - /// @param _from The address of account to burn token. - /// @param _amount The amount of token to mint. - function burn(address _from, uint256 _amount) external; -} diff --git a/contracts/src/libraries/token/IScrollERC721.sol b/contracts/src/libraries/token/IScrollERC721.sol deleted file mode 100644 index 502bcb767..000000000 --- a/contracts/src/libraries/token/IScrollERC721.sol +++ /dev/null @@ -1,13 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.24; - -import {IERC721} from "@openzeppelin/contracts/token/ERC721/IERC721.sol"; -import {IScrollERC721Extension} from "./IScrollERC721Extension.sol"; - -// The recommended ERC721 implementation for bridge token. -// deployed in L2 when original token is on L1 -// deployed in L1 when original token is on L2 -interface IScrollERC721 is IERC721, IScrollERC721Extension { - -} diff --git a/contracts/src/libraries/token/IScrollERC721Extension.sol b/contracts/src/libraries/token/IScrollERC721Extension.sol deleted file mode 100644 index 14e2ce5e7..000000000 --- a/contracts/src/libraries/token/IScrollERC721Extension.sol +++ /dev/null @@ -1,23 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -// Functions needed on top of the ERC721 standard to be compliant with the Scroll bridge -interface IScrollERC721Extension { - /// @notice Return the address of Gateway the token belongs to. - function gateway() external view returns (address); - - /// @notice Return the address of counterpart token. - function counterpart() external view returns (address); - - /// @notice Mint some token to recipient's account. - /// @dev Gateway Utilities, only gateway contract can call - /// @param _to The address of recipient. - /// @param _tokenId The token id to mint. - function mint(address _to, uint256 _tokenId) external; - - /// @notice Burn some token from account. - /// @dev Gateway Utilities, only gateway contract can call - /// @param _tokenId The token id to burn. - function burn(uint256 _tokenId) external; -} diff --git a/contracts/src/libraries/token/IScrollStandardERC20Factory.sol b/contracts/src/libraries/token/IScrollStandardERC20Factory.sol deleted file mode 100644 index 6262ce08e..000000000 --- a/contracts/src/libraries/token/IScrollStandardERC20Factory.sol +++ /dev/null @@ -1,20 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.24; - -interface IScrollStandardERC20Factory { - /// @notice Emitted when a l2 token is deployed. - /// @param _l1Token The address of the l1 token. - /// @param _l2Token The address of the l2 token. - event DeployToken(address indexed _l1Token, address indexed _l2Token); - - /// @notice Compute the corresponding l2 token address given l1 token address. - /// @param _gateway The address of gateway contract. - /// @param _l1Token The address of l1 token. - function computeL2TokenAddress(address _gateway, address _l1Token) external view returns (address); - - /// @notice Deploy the corresponding l2 token address given l1 token address. - /// @param _gateway The address of gateway contract. - /// @param _l1Token The address of l1 token. - function deployL2Token(address _gateway, address _l1Token) external returns (address); -} diff --git a/contracts/src/libraries/token/ScrollStandardERC20.sol b/contracts/src/libraries/token/ScrollStandardERC20.sol deleted file mode 100644 index 05157d5fe..000000000 --- a/contracts/src/libraries/token/ScrollStandardERC20.sol +++ /dev/null @@ -1,91 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {ERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol"; -import {ERC20PermitUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol"; -import {IScrollERC20Upgradeable} from "./IScrollERC20Upgradeable.sol"; -import {IERC677Receiver} from "../callbacks/IERC677Receiver.sol"; - -/// @notice The `ScrollStandardERC20` is the ERC20 token contract created by -/// `L2StandardERC20Gateway` when the first time the L1 ERC20 is bridged via -/// `L1StandardERC20Gateway`. -/// @dev The reason that `ScrollStandardERC20` inherits `IScrollERC20Upgradeable` is because we need -/// to use the `initialize` function from the `ERC20PermitUpgradeable` to initialize the ERC20 -/// token. However, the token contract is NOT upgradable afterwards because -/// `ScrollStandardERC20Factory` uses `Clones` to deploy the `ScrollStandardERC20` contract. -contract ScrollStandardERC20 is ERC20PermitUpgradeable, IScrollERC20Upgradeable { - /// @inheritdoc IScrollERC20Upgradeable - address public override gateway; - - /// @inheritdoc IScrollERC20Upgradeable - address public override counterpart; - - uint8 private decimals_; - - modifier onlyGateway() { - require(gateway == _msgSender(), "Only Gateway"); - _; - } - - constructor() { - _disableInitializers(); - } - - function initialize( - string memory _name, - string memory _symbol, - uint8 _decimals, - address _gateway, - address _counterpart - ) external initializer { - __ERC20Permit_init(_name); - __ERC20_init(_name, _symbol); - - decimals_ = _decimals; - gateway = _gateway; - counterpart = _counterpart; - } - - function decimals() public view override returns (uint8) { - return decimals_; - } - - /// @dev ERC677 Standard, see https://github.com/ethereum/EIPs/issues/677 - /// Defi can use this method to transfer L1/L2 token to L2/L1, - /// and deposit to L2/L1 contract in one transaction - function transferAndCall( - address receiver, - uint256 amount, - bytes calldata data - ) external returns (bool success) { - ERC20Upgradeable.transfer(receiver, amount); - if (isContract(receiver)) { - contractFallback(receiver, amount, data); - } - return true; - } - - function contractFallback( - address to, - uint256 value, - bytes memory data - ) private { - IERC677Receiver receiver = IERC677Receiver(to); - receiver.onTokenTransfer(_msgSender(), value, data); - } - - function isContract(address _addr) private view returns (bool hasCode) { - hasCode = _addr.code.length > 0; - } - - /// @inheritdoc IScrollERC20Upgradeable - function mint(address _to, uint256 _amount) external onlyGateway { - _mint(_to, _amount); - } - - /// @inheritdoc IScrollERC20Upgradeable - function burn(address _from, uint256 _amount) external onlyGateway { - _burn(_from, _amount); - } -} diff --git a/contracts/src/libraries/token/ScrollStandardERC20Factory.sol b/contracts/src/libraries/token/ScrollStandardERC20Factory.sol deleted file mode 100644 index 8b7628457..000000000 --- a/contracts/src/libraries/token/ScrollStandardERC20Factory.sol +++ /dev/null @@ -1,48 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {Clones} from "@openzeppelin/contracts/proxy/Clones.sol"; -import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; - -import {IScrollStandardERC20Factory} from "./IScrollStandardERC20Factory.sol"; - -/// @title ScrollStandardERC20Factory -/// @notice The `ScrollStandardERC20Factory` is used to deploy `ScrollStandardERC20` for `L2StandardERC20Gateway`. -/// It uses the `Clones` contract to deploy contract with minimum gas usage. -/// @dev The implementation of deployed token is non-upgradable. This design may be changed in the future. -contract ScrollStandardERC20Factory is Ownable, IScrollStandardERC20Factory { - /// @notice The address of `ScrollStandardERC20` implementation. - address public implementation; - - constructor(address _implementation) { - require(_implementation != address(0), "zero implementation address"); - - implementation = _implementation; - } - - /// @inheritdoc IScrollStandardERC20Factory - function computeL2TokenAddress(address _gateway, address _l1Token) external view returns (address) { - // In StandardERC20Gateway, all corresponding l2 tokens are deployed by Create2 with salt, - // we can calculate the l2 address directly. - bytes32 _salt = _getSalt(_gateway, _l1Token); - - return Clones.predictDeterministicAddress(implementation, _salt); - } - - /// @inheritdoc IScrollStandardERC20Factory - /// @dev This function should only be called by owner to avoid DDoS attack on StandardTokenBridge. - function deployL2Token(address _gateway, address _l1Token) external onlyOwner returns (address) { - bytes32 _salt = _getSalt(_gateway, _l1Token); - - address _l2Token = Clones.cloneDeterministic(implementation, _salt); - - emit DeployToken(_l1Token, _l2Token); - - return _l2Token; - } - - function _getSalt(address _gateway, address _l1Token) internal pure returns (bytes32) { - return keccak256(abi.encodePacked(_gateway, keccak256(abi.encodePacked(_l1Token)))); - } -} diff --git a/contracts/src/libraries/verifier/IRollupVerifier.sol b/contracts/src/libraries/verifier/IRollupVerifier.sol deleted file mode 100644 index 3ae9ab1ed..000000000 --- a/contracts/src/libraries/verifier/IRollupVerifier.sol +++ /dev/null @@ -1,29 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.24; - -/// @title IRollupVerifier -/// @notice The interface for rollup verifier. -interface IRollupVerifier { - /// @notice Verify aggregate zk proof. - /// @param batchIndex The batch index to verify. - /// @param aggrProof The aggregated proof. - /// @param publicInputHash The public input hash. - function verifyAggregateProof( - uint256 batchIndex, - bytes calldata aggrProof, - bytes32 publicInputHash - ) external view; - - /// @notice Verify aggregate zk proof. - /// @param version The version of verifier to use. - /// @param batchIndex The batch index to verify. - /// @param aggrProof The aggregated proof. - /// @param publicInputHash The public input hash. - function verifyAggregateProof( - uint256 version, - uint256 batchIndex, - bytes calldata aggrProof, - bytes32 publicInputHash - ) external view; -} diff --git a/contracts/src/libraries/verifier/IZkEvmVerifier.sol b/contracts/src/libraries/verifier/IZkEvmVerifier.sol deleted file mode 100644 index 853aca159..000000000 --- a/contracts/src/libraries/verifier/IZkEvmVerifier.sol +++ /dev/null @@ -1,10 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.24; - -interface IZkEvmVerifier { - /// @notice Verify aggregate zk proof. - /// @param aggrProof The aggregated proof. - /// @param publicInputHash The public input hash. - function verify(bytes calldata aggrProof, bytes32 publicInputHash) external view; -} diff --git a/contracts/src/libraries/verifier/PatriciaMerkleTrieVerifier.sol b/contracts/src/libraries/verifier/PatriciaMerkleTrieVerifier.sol deleted file mode 100644 index 81541e43d..000000000 --- a/contracts/src/libraries/verifier/PatriciaMerkleTrieVerifier.sol +++ /dev/null @@ -1,516 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.24; - -library PatriciaMerkleTrieVerifier { - /// @notice Internal function to validates a proof from eth_getProof. - /// @param account The address of the contract. - /// @param storageKey The storage slot to verify. - /// @param proof The rlp encoding result of eth_getProof. - /// @return stateRoot The computed state root. Must be checked by the caller. - /// @return storageValue The value of `storageKey`. - /// - /// @dev The code is based on - /// 1. https://eips.ethereum.org/EIPS/eip-1186 - /// 2. https://ethereum.org/en/developers/docs/data-structures-and-encoding/rlp/ - /// 3. https://github.com/ethereum/go-ethereum/blob/master/trie/proof.go#L114 - /// 4. https://github.com/privacy-scaling-explorations/zkevm-chain/blob/master/contracts/templates/PatriciaValidator.sol - /// - /// The encoding order of `proof` is - /// ```text - /// | 1 byte | ... | 1 byte | ... | - /// | account proof length | account proof | storage proof length | storage proof | - /// ``` - function verifyPatriciaProof( - address account, - bytes32 storageKey, - bytes calldata proof - ) internal pure returns (bytes32 stateRoot, bytes32 storageValue) { - assembly { - // hashes 32 bytes of `v` - function keccak_32(v) -> r { - mstore(0x00, v) - r := keccak256(0x00, 0x20) - } - // hashes the last 20 bytes of `v` - function keccak_20(v) -> r { - mstore(0x00, v) - r := keccak256(0x0c, 0x14) - } - // reverts with error `msg`. - // make sure the length of error string <= 32 - function revertWith(msg) { - // keccak("Error(string)") - mstore(0x00, 0x08c379a000000000000000000000000000000000000000000000000000000000) - mstore(0x04, 0x20) // str.offset - mstore(0x44, msg) - let msgLen - for { - - } msg { - - } { - msg := shl(8, msg) - msgLen := add(msgLen, 1) - } - mstore(0x24, msgLen) // str.length - revert(0x00, 0x64) - } - // reverts with `msg` when condition is not matched. - // make sure the length of error string <= 32 - function require(cond, msg) { - if iszero(cond) { - revertWith(msg) - } - } - - // special function for decoding the storage value - // because of the prefix truncation if value > 31 bytes - // see `loadValue` - function decodeItem(word, len) -> ret { - // default - ret := word - - // RLP single byte - if lt(word, 0x80) { - leave - } - - // truncated - if gt(len, 32) { - leave - } - - // value is >= 0x80 and <= 32 bytes. - // `len` should be at least 2 (prefix byte + value) - // otherwise the RLP is malformed. - let bits := mul(len, 8) - // sub 8 bits - the prefix - bits := sub(bits, 8) - let mask := shl(bits, 0xff) - // invert the mask - mask := not(mask) - // should hold the value - prefix byte - ret := and(ret, mask) - } - - // returns the `len` of the whole RLP list at `ptr` - // and the offset for the first value inside the list. - function decodeListLength(ptr) -> len, startOffset { - let b0 := byte(0, calldataload(ptr)) - // In most cases, it is a long list. So we reorder the branch to reduce branch prediction miss. - - // 0xf8 - 0xff, long list, length > 55 - if gt(b0, 0xf7) { - // the RLP encoding consists of a single byte with value 0xf7 - // plus the length in bytes of the length of the payload in binary form, - // followed by the length of the payload, followed by the concatenation - // of the RLP encodings of the items. - // the extended length is ignored - let lengthBytes := sub(b0, 0xf7) - if gt(lengthBytes, 32) { - invalid() - } - - // load the extended length - startOffset := add(ptr, 1) - let extendedLen := calldataload(startOffset) - let bits := sub(256, mul(lengthBytes, 8)) - extendedLen := shr(bits, extendedLen) - - len := add(extendedLen, lengthBytes) - len := add(len, 1) - startOffset := add(startOffset, lengthBytes) - leave - } - // 0xc0 - 0xf7, short list, length <= 55 - if gt(b0, 0xbf) { - // the RLP encoding consists of a single byte with value 0xc0 - // plus the length of the list followed by the concatenation of - // the RLP encodings of the items. - len := sub(b0, 0xbf) - startOffset := add(ptr, 1) - leave - } - revertWith("Not list") - } - - // returns the kind, calldata offset of the value and the length in bytes - // for the RLP encoded data item at `ptr`. used in `decodeFlat` - // kind = 0 means string/bytes, kind = 1 means list. - function decodeValue(ptr) -> kind, dataLen, valueOffset { - let b0 := byte(0, calldataload(ptr)) - - // 0x00 - 0x7f, single byte - if lt(b0, 0x80) { - // for a single byte whose value is in the [0x00, 0x7f] range, - // that byte is its own RLP encoding. - dataLen := 1 - valueOffset := ptr - leave - } - - // 0x80 - 0xb7, short string/bytes, length <= 55 - if lt(b0, 0xb8) { - // the RLP encoding consists of a single byte with value 0x80 - // plus the length of the string followed by the string. - dataLen := sub(b0, 0x80) - valueOffset := add(ptr, 1) - leave - } - - // 0xb8 - 0xbf, long string/bytes, length > 55 - if lt(b0, 0xc0) { - // the RLP encoding consists of a single byte with value 0xb7 - // plus the length in bytes of the length of the string in binary form, - // followed by the length of the string, followed by the string. - let lengthBytes := sub(b0, 0xb7) - if gt(lengthBytes, 4) { - invalid() - } - - // load the extended length - valueOffset := add(ptr, 1) - let extendedLen := calldataload(valueOffset) - let bits := sub(256, mul(lengthBytes, 8)) - extendedLen := shr(bits, extendedLen) - - dataLen := extendedLen - valueOffset := add(valueOffset, lengthBytes) - leave - } - - kind := 1 - // 0xc0 - 0xf7, short list, length <= 55 - if lt(b0, 0xf8) { - // intentionally ignored - // dataLen := sub(firstByte, 0xc0) - valueOffset := add(ptr, 1) - leave - } - - // 0xf8 - 0xff, long list, length > 55 - { - // the extended length is ignored - dataLen := sub(b0, 0xf7) - valueOffset := add(ptr, 1) - leave - } - } - - // decodes all RLP encoded data and stores their DATA items - // [length - 128 bits | calldata offset - 128 bits] in a continuous memory region. - // Expects that the RLP starts with a list that defines the length - // of the whole RLP region. - function decodeFlat(_ptr) -> ptr, memStart, nItems, hash { - ptr := _ptr - - // load free memory ptr - // doesn't update the ptr and leaves the memory region dirty - memStart := mload(0x40) - - let payloadLen, startOffset := decodeListLength(ptr) - // reuse memStart region and hash - calldatacopy(memStart, ptr, payloadLen) - hash := keccak256(memStart, payloadLen) - - let memPtr := memStart - let ptrStop := add(ptr, payloadLen) - ptr := startOffset - - // decode until the end of the list - for { - - } lt(ptr, ptrStop) { - - } { - let kind, len, valuePtr := decodeValue(ptr) - ptr := add(len, valuePtr) - - if iszero(kind) { - // store the length of the data and the calldata offset - // low -------> high - // | 128 bits | 128 bits | - // | calldata offset | value length | - mstore(memPtr, or(shl(128, len), valuePtr)) - memPtr := add(memPtr, 0x20) - } - } - - if iszero(eq(ptr, ptrStop)) { - invalid() - } - - nItems := div(sub(memPtr, memStart), 32) - } - - // prefix gets truncated to 256 bits - // `depth` is untrusted and can lead to bogus - // shifts/masks. In that case, the remaining verification - // steps must fail or lead to an invalid stateRoot hash - // if the proof data is 'spoofed but valid' - function derivePath(key, depth) -> path { - path := key - - let bits := mul(depth, 4) - { - let mask := not(0) - mask := shr(bits, mask) - path := and(path, mask) - } - - // even prefix - let prefix := 0x20 - if mod(depth, 2) { - // odd - prefix := 0x3 - } - - // the prefix may be shifted outside bounds - // this is intended, see `loadValue` - bits := sub(256, bits) - prefix := shl(bits, prefix) - path := or(prefix, path) - } - - // loads and aligns a value from calldata - // given the `len|offset` stored at `memPtr` - function loadValue(memPtr, idx) -> value { - let tmp := mload(add(memPtr, mul(32, idx))) - // assuming 0xffffff is sufficient for storing calldata offset - let offset := and(tmp, 0xffffff) - let len := shr(128, tmp) - - if gt(len, 31) { - // special case - truncating the value is intended. - // this matches the behavior in `derivePath` that truncates to 256 bits. - offset := add(offset, sub(len, 32)) - value := calldataload(offset) - leave - } - - // everything else is - // < 32 bytes - align the value - let bits := mul(sub(32, len), 8) - value := calldataload(offset) - value := shr(bits, value) - } - - // loads and aligns a value from calldata - // given the `len|offset` stored at `memPtr` - // Same as `loadValue` except it returns also the size - // of the value. - function loadValueLen(memPtr, idx) -> value, len { - let tmp := mload(add(memPtr, mul(32, idx))) - // assuming 0xffffff is sufficient for storing calldata offset - let offset := and(tmp, 0xffffff) - len := shr(128, tmp) - - if gt(len, 31) { - // special case - truncating the value is intended. - // this matches the behavior in `derivePath` that truncates to 256 bits. - offset := add(offset, sub(len, 32)) - value := calldataload(offset) - leave - } - - // everything else is - // < 32 bytes - align the value - let bits := mul(sub(32, len), 8) - value := calldataload(offset) - value := shr(bits, value) - } - - function loadPair(memPtr, idx) -> offset, len { - let tmp := mload(add(memPtr, mul(32, idx))) - // assuming 0xffffff is sufficient for storing calldata offset - offset := and(tmp, 0xffffff) - len := shr(128, tmp) - } - - // decodes RLP at `_ptr`. - // reverts if the number of DATA items doesn't match `nValues`. - // returns the RLP data items at pos `v0`, `v1` - // and the size of `v1out` - function hashCompareSelect(_ptr, nValues, v0, v1) -> ptr, hash, v0out, v1out, v1outlen { - ptr := _ptr - - let memStart, nItems - ptr, memStart, nItems, hash := decodeFlat(ptr) - - if iszero(eq(nItems, nValues)) { - revertWith("Node items mismatch") - } - - v0out, v1outlen := loadValueLen(memStart, v0) - v1out, v1outlen := loadValueLen(memStart, v1) - } - - // traverses the tree from the root to the node before the leaf. - // based on https://github.com/ethereum/go-ethereum/blob/master/trie/proof.go#L114 - function walkTree(key, _ptr) -> ptr, rootHash, expectedHash, path { - ptr := _ptr - - // the first byte is the number of nodes - let nodes := byte(0, calldataload(ptr)) - ptr := add(ptr, 1) - - // keeps track of ascend/descend - however you may look at a tree - let depth - - // treat the leaf node with different logic - for { - let i := 1 - } lt(i, nodes) { - i := add(i, 1) - } { - let memStart, nItems, hash - ptr, memStart, nItems, hash := decodeFlat(ptr) - - // first item is considered the root node. - // Otherwise verifies that the hash of the current node - // is the same as the previous chosen one. - switch i - case 1 { - rootHash := hash - } - default { - require(eq(hash, expectedHash), "Hash mismatch") - } - - switch nItems - case 2 { - // extension node - // load the second item. - // this is the hash of the next node. - let value, len := loadValueLen(memStart, 1) - expectedHash := value - - // get the byte length of the first item - // Note: the value itself is not validated - // and it is instead assumed that any invalid - // value is invalidated by comparing the root hash. - let offset := mload(memStart) - let prefixLen := shr(128, offset) - // assuming 0xffffff is sufficient for storing calldata offset - offset := and(offset, 0xffffff) - let flag := shr(252, calldataload(offset)) - switch flag - case 0 { - // extension with even length - depth := add(depth, mul(2, sub(prefixLen, 1))) - } - case 1 { - // extension with odd length - depth := add(depth, sub(mul(2, prefixLen), 1)) - } - default { - // everything else is unexpected - revertWith("Invalid extension node") - } - } - case 17 { - let bits := sub(252, mul(depth, 4)) - let nibble := and(shr(bits, key), 0xf) - - // load the value at pos `nibble` - let value, len := loadValueLen(memStart, nibble) - - expectedHash := value - depth := add(depth, 1) - } - default { - // everything else is unexpected - revertWith("Invalid node") - } - } - - // lastly, derive the path of the chosen one (TM) - path := derivePath(key, depth) - } - - // shared variable names - let storageHash - let encodedPath - let path - let hash - let vlen - // starting point - let ptr := proof.offset - - { - // account proof - // Note: this doesn't work if there are no intermediate nodes before the leaf. - // This is not possible in practice because of the fact that there must be at least - // 2 accounts in the tree to make a transaction to a existing contract possible. - // Thus, 2 leaves. - let prevHash - let key := keccak_20(account) - // `stateRoot` is a return value and must be checked by the caller - ptr, stateRoot, prevHash, path := walkTree(key, ptr) - - let memStart, nItems - ptr, memStart, nItems, hash := decodeFlat(ptr) - - // the hash of the leaf must match the previous hash from the node - require(eq(hash, prevHash), "Account leaf hash mismatch") - - // 2 items - // - encoded path - // - account leaf RLP (4 items) - require(eq(nItems, 2), "Account leaf node mismatch") - - encodedPath := loadValue(memStart, 0) - // the calculated path must match the encoded path in the leaf - require(eq(path, encodedPath), "Account encoded path mismatch") - - // Load the position, length of the second element (RLP encoded) - let leafPtr, leafLen := loadPair(memStart, 1) - leafPtr, memStart, nItems, hash := decodeFlat(leafPtr) - - // the account leaf should contain 4 values, - // we want: - // - storageHash @ 2 - require(eq(nItems, 4), "Account leaf items mismatch") - storageHash := loadValue(memStart, 2) - } - - { - // storage proof - let rootHash - let key := keccak_32(storageKey) - ptr, rootHash, hash, path := walkTree(key, ptr) - - // leaf should contain 2 values - // - encoded path @ 0 - // - storageValue @ 1 - ptr, hash, encodedPath, storageValue, vlen := hashCompareSelect(ptr, 2, 0, 1) - // the calculated path must match the encoded path in the leaf - require(eq(path, encodedPath), "Storage encoded path mismatch") - - switch rootHash - case 0 { - // in the case that the leaf is the only element, then - // the hash of the leaf must match the value from the account leaf - require(eq(hash, storageHash), "Storage root mismatch") - } - default { - // otherwise the root hash of the storage tree - // must match the value from the account leaf - require(eq(rootHash, storageHash), "Storage root mismatch") - } - - // storageValue is a return value - storageValue := decodeItem(storageValue, vlen) - } - - // the one and only boundary check - // in case an attacker crafted a malicious payload - // and succeeds in the prior verification steps - // then this should catch any bogus accesses - if iszero(eq(ptr, add(proof.offset, proof.length))) { - revertWith("Proof length mismatch") - } - } - } -} diff --git a/contracts/src/libraries/verifier/RollupVerifier.sol b/contracts/src/libraries/verifier/RollupVerifier.sol deleted file mode 100644 index ba1a26551..000000000 --- a/contracts/src/libraries/verifier/RollupVerifier.sol +++ /dev/null @@ -1,1024 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0 - -pragma solidity ^0.8.24; - -library RollupVerifier { - function pairing(G1Point[] memory p1, G2Point[] memory p2) internal view returns (bool) { - uint256 length = p1.length * 6; - uint256[] memory input = new uint256[](length); - uint256[1] memory result; - bool ret; - - require(p1.length == p2.length); - - for (uint256 i = 0; i < p1.length; i++) { - input[0 + i * 6] = p1[i].x; - input[1 + i * 6] = p1[i].y; - input[2 + i * 6] = p2[i].x[0]; - input[3 + i * 6] = p2[i].x[1]; - input[4 + i * 6] = p2[i].y[0]; - input[5 + i * 6] = p2[i].y[1]; - } - - assembly { - ret := staticcall(gas(), 8, add(input, 0x20), mul(length, 0x20), result, 0x20) - } - require(ret); - return result[0] != 0; - } - - uint256 constant q_mod = 21888242871839275222246405745257275088548364400416034343698204186575808495617; - - function fr_invert(uint256 a) internal view returns (uint256) { - return fr_pow(a, q_mod - 2); - } - - function fr_pow(uint256 a, uint256 power) internal view returns (uint256) { - uint256[6] memory input; - uint256[1] memory result; - bool ret; - - input[0] = 32; - input[1] = 32; - input[2] = 32; - input[3] = a; - input[4] = power; - input[5] = q_mod; - - assembly { - ret := staticcall(gas(), 0x05, input, 0xc0, result, 0x20) - } - require(ret); - - return result[0]; - } - - function fr_div(uint256 a, uint256 b) internal view returns (uint256) { - require(b != 0); - return mulmod(a, fr_invert(b), q_mod); - } - - function fr_mul_add( - uint256 a, - uint256 b, - uint256 c - ) internal pure returns (uint256) { - return addmod(mulmod(a, b, q_mod), c, q_mod); - } - - function fr_mul_add_pm( - uint256[84] memory m, - uint256[] calldata proof, - uint256 opcode, - uint256 t - ) internal pure returns (uint256) { - for (uint256 i = 0; i < 32; i += 2) { - uint256 a = opcode & 0xff; - if (a != 0xff) { - opcode >>= 8; - uint256 b = opcode & 0xff; - opcode >>= 8; - t = addmod(mulmod(proof[a], m[b], q_mod), t, q_mod); - } else { - break; - } - } - - return t; - } - - function fr_mul_add_mt( - uint256[84] memory m, - uint256 base, - uint256 opcode, - uint256 t - ) internal pure returns (uint256) { - for (uint256 i = 0; i < 32; i += 1) { - uint256 a = opcode & 0xff; - if (a != 0xff) { - opcode >>= 8; - t = addmod(mulmod(base, t, q_mod), m[a], q_mod); - } else { - break; - } - } - - return t; - } - - function fr_reverse(uint256 input) internal pure returns (uint256 v) { - v = input; - - // swap bytes - v = - ((v & 0xFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00) >> 8) | - ((v & 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) << 8); - - // swap 2-byte long pairs - v = - ((v & 0xFFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000) >> 16) | - ((v & 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) << 16); - - // swap 4-byte long pairs - v = - ((v & 0xFFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000) >> 32) | - ((v & 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) << 32); - - // swap 8-byte long pairs - v = - ((v & 0xFFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF0000000000000000) >> 64) | - ((v & 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) << 64); - - // swap 16-byte long pairs - v = (v >> 128) | (v << 128); - } - - uint256 constant p_mod = 21888242871839275222246405745257275088696311157297823662689037894645226208583; - - struct G1Point { - uint256 x; - uint256 y; - } - - struct G2Point { - uint256[2] x; - uint256[2] y; - } - - function ecc_from(uint256 x, uint256 y) internal pure returns (G1Point memory r) { - r.x = x; - r.y = y; - } - - function ecc_add( - uint256 ax, - uint256 ay, - uint256 bx, - uint256 by - ) internal view returns (uint256, uint256) { - bool ret = false; - G1Point memory r; - uint256[4] memory input_points; - - input_points[0] = ax; - input_points[1] = ay; - input_points[2] = bx; - input_points[3] = by; - - assembly { - ret := staticcall(gas(), 6, input_points, 0x80, r, 0x40) - } - require(ret); - - return (r.x, r.y); - } - - function ecc_sub( - uint256 ax, - uint256 ay, - uint256 bx, - uint256 by - ) internal view returns (uint256, uint256) { - return ecc_add(ax, ay, bx, p_mod - by); - } - - function ecc_mul( - uint256 px, - uint256 py, - uint256 s - ) internal view returns (uint256, uint256) { - uint256[3] memory input; - bool ret = false; - G1Point memory r; - - input[0] = px; - input[1] = py; - input[2] = s; - - assembly { - ret := staticcall(gas(), 7, input, 0x60, r, 0x40) - } - require(ret); - - return (r.x, r.y); - } - - function _ecc_mul_add(uint256[5] memory input) internal view { - bool ret = false; - - assembly { - ret := staticcall(gas(), 7, input, 0x60, add(input, 0x20), 0x40) - } - require(ret); - - assembly { - ret := staticcall(gas(), 6, add(input, 0x20), 0x80, add(input, 0x60), 0x40) - } - require(ret); - } - - function ecc_mul_add( - uint256 px, - uint256 py, - uint256 s, - uint256 qx, - uint256 qy - ) internal view returns (uint256, uint256) { - uint256[5] memory input; - input[0] = px; - input[1] = py; - input[2] = s; - input[3] = qx; - input[4] = qy; - - _ecc_mul_add(input); - - return (input[3], input[4]); - } - - function ecc_mul_add_pm( - uint256[84] memory m, - uint256[] calldata proof, - uint256 opcode, - uint256 t0, - uint256 t1 - ) internal view returns (uint256, uint256) { - uint256[5] memory input; - input[3] = t0; - input[4] = t1; - for (uint256 i = 0; i < 32; i += 2) { - uint256 a = opcode & 0xff; - if (a != 0xff) { - opcode >>= 8; - uint256 b = opcode & 0xff; - opcode >>= 8; - input[0] = proof[a]; - input[1] = proof[a + 1]; - input[2] = m[b]; - _ecc_mul_add(input); - } else { - break; - } - } - - return (input[3], input[4]); - } - - function update_hash_scalar( - uint256 v, - uint256[144] memory absorbing, - uint256 pos - ) internal pure { - absorbing[pos++] = 0x02; - absorbing[pos++] = v; - } - - function update_hash_point( - uint256 x, - uint256 y, - uint256[144] memory absorbing, - uint256 pos - ) internal pure { - absorbing[pos++] = 0x01; - absorbing[pos++] = x; - absorbing[pos++] = y; - } - - function to_scalar(bytes32 r) private pure returns (uint256 v) { - uint256 tmp = uint256(r); - tmp = fr_reverse(tmp); - v = tmp % 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001; - } - - function hash(uint256[144] memory absorbing, uint256 length) private view returns (bytes32[1] memory v) { - bool success; - assembly { - success := staticcall(sub(gas(), 2000), 2, absorbing, length, v, 32) - switch success - case 0 { - invalid() - } - } - assert(success); - } - - function squeeze_challenge(uint256[144] memory absorbing, uint32 length) internal view returns (uint256 v) { - absorbing[length] = 0; - bytes32 res = hash(absorbing, length * 32 + 1)[0]; - v = to_scalar(res); - absorbing[0] = uint256(res); - length = 1; - } - - function get_verify_circuit_g2_s() internal pure returns (G2Point memory s) { - s.x[0] = uint256(19996377281670978687180986182441301914718493784645870391946826878753710639456); - s.x[1] = uint256(4287478848095488335912479212753150961411468232106701703291869721868407715111); - s.y[0] = uint256(6995741485533723263267942814565501722132921805029874890336635619836737653877); - s.y[1] = uint256(11126659726611658836425410744462014686753643655648740844565393330984713428953); - } - - function get_verify_circuit_g2_n() internal pure returns (G2Point memory n) { - n.x[0] = uint256(11559732032986387107991004021392285783925812861821192530917403151452391805634); - n.x[1] = uint256(10857046999023057135944570762232829481370756359578518086990519993285655852781); - n.y[0] = uint256(17805874995975841540914202342111839520379459829704422454583296818431106115052); - n.y[1] = uint256(13392588948715843804641432497768002650278120570034223513918757245338268106653); - } - - function get_target_circuit_g2_s() internal pure returns (G2Point memory s) { - s.x[0] = uint256(19996377281670978687180986182441301914718493784645870391946826878753710639456); - s.x[1] = uint256(4287478848095488335912479212753150961411468232106701703291869721868407715111); - s.y[0] = uint256(6995741485533723263267942814565501722132921805029874890336635619836737653877); - s.y[1] = uint256(11126659726611658836425410744462014686753643655648740844565393330984713428953); - } - - function get_target_circuit_g2_n() internal pure returns (G2Point memory n) { - n.x[0] = uint256(11559732032986387107991004021392285783925812861821192530917403151452391805634); - n.x[1] = uint256(10857046999023057135944570762232829481370756359578518086990519993285655852781); - n.y[0] = uint256(17805874995975841540914202342111839520379459829704422454583296818431106115052); - n.y[1] = uint256(13392588948715843804641432497768002650278120570034223513918757245338268106653); - } - - function get_wx_wg(uint256[] calldata proof, uint256[6] memory instances) - internal - view - returns ( - uint256, - uint256, - uint256, - uint256 - ) - { - uint256[84] memory m; - uint256[144] memory absorbing; - uint256 t0 = 0; - uint256 t1 = 0; - - (t0, t1) = ( - ecc_mul( - 16273630658577275004922498653030603356133576819117084202553121866583118864964, - 6490159372778831696763963776713702553449715395136256408127406430701013586737, - instances[0] - ) - ); - (t0, t1) = ( - ecc_mul_add( - 21465583338900056601761668793508143213048509206826828900542864688378093593107, - 18916078441896187703473496284050716429170517783995157941513585201547834049281, - instances[1], - t0, - t1 - ) - ); - (t0, t1) = ( - ecc_mul_add( - 6343857336395576108841088300387244434710621968858839561085778033655098739860, - 8647137667680968494319179221347060255241434220013711910139382436020093396308, - instances[2], - t0, - t1 - ) - ); - (t0, t1) = ( - ecc_mul_add( - 17609998990685530094209191702545036897101285294398654477281719279316619940710, - 7891327626892441842954365090016786852185025910332850053066512639794082797200, - instances[3], - t0, - t1 - ) - ); - (t0, t1) = ( - ecc_mul_add( - 1271298011119556361067568041994358027954229594187408866479678256322993207430, - 16519855264988006509000373008036578681979317060055767197977112967887569978562, - instances[4], - t0, - t1 - ) - ); - (m[0], m[1]) = ( - ecc_mul_add( - 9106880861932848269529912338578777683259870408474914617967634470292361865683, - 3191458938194545761508145121615374474619318896841102235687991186359560600763, - instances[5], - t0, - t1 - ) - ); - update_hash_scalar(2139959605475961860937015093717899596443860272195454718006038460622762772338, absorbing, 0); - update_hash_point(m[0], m[1], absorbing, 2); - for (t0 = 0; t0 <= 4; t0++) { - update_hash_point(proof[0 + t0 * 2], proof[1 + t0 * 2], absorbing, 5 + t0 * 3); - } - m[2] = (squeeze_challenge(absorbing, 20)); - for (t0 = 0; t0 <= 13; t0++) { - update_hash_point(proof[10 + t0 * 2], proof[11 + t0 * 2], absorbing, 1 + t0 * 3); - } - m[3] = (squeeze_challenge(absorbing, 43)); - m[4] = (squeeze_challenge(absorbing, 1)); - for (t0 = 0; t0 <= 9; t0++) { - update_hash_point(proof[38 + t0 * 2], proof[39 + t0 * 2], absorbing, 1 + t0 * 3); - } - m[5] = (squeeze_challenge(absorbing, 31)); - for (t0 = 0; t0 <= 3; t0++) { - update_hash_point(proof[58 + t0 * 2], proof[59 + t0 * 2], absorbing, 1 + t0 * 3); - } - m[6] = (squeeze_challenge(absorbing, 13)); - for (t0 = 0; t0 <= 70; t0++) { - update_hash_scalar(proof[66 + t0 * 1], absorbing, 1 + t0 * 2); - } - m[7] = (squeeze_challenge(absorbing, 143)); - for (t0 = 0; t0 <= 3; t0++) { - update_hash_point(proof[137 + t0 * 2], proof[138 + t0 * 2], absorbing, 1 + t0 * 3); - } - m[8] = (squeeze_challenge(absorbing, 13)); - m[9] = (mulmod(m[6], 13446667982376394161563610564587413125564757801019538732601045199901075958935, q_mod)); - m[10] = (mulmod(m[6], 16569469942529664681363945218228869388192121720036659574609237682362097667612, q_mod)); - m[11] = (mulmod(m[6], 14803907026430593724305438564799066516271154714737734572920456128449769927233, q_mod)); - m[12] = (fr_pow(m[6], 67108864)); - m[13] = (addmod(m[12], q_mod - 1, q_mod)); - m[14] = (mulmod(21888242545679039938882419398440172875981108180010270949818755658014750055173, m[13], q_mod)); - t0 = (addmod(m[6], q_mod - 1, q_mod)); - m[14] = (fr_div(m[14], t0)); - m[15] = (mulmod(3495999257316610708652455694658595065970881061159015347599790211259094641512, m[13], q_mod)); - t0 = ( - addmod(m[6], q_mod - 14803907026430593724305438564799066516271154714737734572920456128449769927233, q_mod) - ); - m[15] = (fr_div(m[15], t0)); - m[16] = (mulmod(12851378806584061886934576302961450669946047974813165594039554733293326536714, m[13], q_mod)); - t0 = ( - addmod(m[6], q_mod - 11377606117859914088982205826922132024839443553408109299929510653283289974216, q_mod) - ); - m[16] = (fr_div(m[16], t0)); - m[17] = (mulmod(14638077285440018490948843142723135319134576188472316769433007423695824509066, m[13], q_mod)); - t0 = ( - addmod(m[6], q_mod - 3693565015985198455139889557180396682968596245011005461846595820698933079918, q_mod) - ); - m[17] = (fr_div(m[17], t0)); - m[18] = (mulmod(18027939092386982308810165776478549635922357517986691900813373197616541191289, m[13], q_mod)); - t0 = ( - addmod(m[6], q_mod - 17329448237240114492580865744088056414251735686965494637158808787419781175510, q_mod) - ); - m[18] = (fr_div(m[18], t0)); - m[19] = (mulmod(912591536032578604421866340844550116335029274442283291811906603256731601654, m[13], q_mod)); - t0 = ( - addmod(m[6], q_mod - 6047398202650739717314770882059679662647667807426525133977681644606291529311, q_mod) - ); - m[19] = (fr_div(m[19], t0)); - m[20] = (mulmod(17248638560015646562374089181598815896736916575459528793494921668169819478628, m[13], q_mod)); - t0 = ( - addmod(m[6], q_mod - 16569469942529664681363945218228869388192121720036659574609237682362097667612, q_mod) - ); - m[20] = (fr_div(m[20], t0)); - t0 = (addmod(m[15], m[16], q_mod)); - t0 = (addmod(t0, m[17], q_mod)); - t0 = (addmod(t0, m[18], q_mod)); - m[15] = (addmod(t0, m[19], q_mod)); - t0 = (fr_mul_add(proof[74], proof[72], proof[73])); - t0 = (fr_mul_add(proof[75], proof[67], t0)); - t0 = (fr_mul_add(proof[76], proof[68], t0)); - t0 = (fr_mul_add(proof[77], proof[69], t0)); - t0 = (fr_mul_add(proof[78], proof[70], t0)); - m[16] = (fr_mul_add(proof[79], proof[71], t0)); - t0 = (mulmod(proof[67], proof[68], q_mod)); - m[16] = (fr_mul_add(proof[80], t0, m[16])); - t0 = (mulmod(proof[69], proof[70], q_mod)); - m[16] = (fr_mul_add(proof[81], t0, m[16])); - t0 = (addmod(1, q_mod - proof[97], q_mod)); - m[17] = (mulmod(m[14], t0, q_mod)); - t0 = (mulmod(proof[100], proof[100], q_mod)); - t0 = (addmod(t0, q_mod - proof[100], q_mod)); - m[18] = (mulmod(m[20], t0, q_mod)); - t0 = (addmod(proof[100], q_mod - proof[99], q_mod)); - m[19] = (mulmod(t0, m[14], q_mod)); - m[21] = (mulmod(m[3], m[6], q_mod)); - t0 = (addmod(m[20], m[15], q_mod)); - m[15] = (addmod(1, q_mod - t0, q_mod)); - m[22] = (addmod(proof[67], m[4], q_mod)); - t0 = (fr_mul_add(proof[91], m[3], m[22])); - m[23] = (mulmod(t0, proof[98], q_mod)); - t0 = (addmod(m[22], m[21], q_mod)); - m[22] = (mulmod(t0, proof[97], q_mod)); - m[24] = (mulmod(4131629893567559867359510883348571134090853742863529169391034518566172092834, m[21], q_mod)); - m[25] = (addmod(proof[68], m[4], q_mod)); - t0 = (fr_mul_add(proof[92], m[3], m[25])); - m[23] = (mulmod(t0, m[23], q_mod)); - t0 = (addmod(m[25], m[24], q_mod)); - m[22] = (mulmod(t0, m[22], q_mod)); - m[24] = (mulmod(4131629893567559867359510883348571134090853742863529169391034518566172092834, m[24], q_mod)); - m[25] = (addmod(proof[69], m[4], q_mod)); - t0 = (fr_mul_add(proof[93], m[3], m[25])); - m[23] = (mulmod(t0, m[23], q_mod)); - t0 = (addmod(m[25], m[24], q_mod)); - m[22] = (mulmod(t0, m[22], q_mod)); - m[24] = (mulmod(4131629893567559867359510883348571134090853742863529169391034518566172092834, m[24], q_mod)); - t0 = (addmod(m[23], q_mod - m[22], q_mod)); - m[22] = (mulmod(t0, m[15], q_mod)); - m[21] = (mulmod(m[21], 11166246659983828508719468090013646171463329086121580628794302409516816350802, q_mod)); - m[23] = (addmod(proof[70], m[4], q_mod)); - t0 = (fr_mul_add(proof[94], m[3], m[23])); - m[24] = (mulmod(t0, proof[101], q_mod)); - t0 = (addmod(m[23], m[21], q_mod)); - m[23] = (mulmod(t0, proof[100], q_mod)); - m[21] = (mulmod(4131629893567559867359510883348571134090853742863529169391034518566172092834, m[21], q_mod)); - m[25] = (addmod(proof[71], m[4], q_mod)); - t0 = (fr_mul_add(proof[95], m[3], m[25])); - m[24] = (mulmod(t0, m[24], q_mod)); - t0 = (addmod(m[25], m[21], q_mod)); - m[23] = (mulmod(t0, m[23], q_mod)); - m[21] = (mulmod(4131629893567559867359510883348571134090853742863529169391034518566172092834, m[21], q_mod)); - m[25] = (addmod(proof[66], m[4], q_mod)); - t0 = (fr_mul_add(proof[96], m[3], m[25])); - m[24] = (mulmod(t0, m[24], q_mod)); - t0 = (addmod(m[25], m[21], q_mod)); - m[23] = (mulmod(t0, m[23], q_mod)); - m[21] = (mulmod(4131629893567559867359510883348571134090853742863529169391034518566172092834, m[21], q_mod)); - t0 = (addmod(m[24], q_mod - m[23], q_mod)); - m[21] = (mulmod(t0, m[15], q_mod)); - t0 = (addmod(proof[104], m[3], q_mod)); - m[23] = (mulmod(proof[103], t0, q_mod)); - t0 = (addmod(proof[106], m[4], q_mod)); - m[23] = (mulmod(m[23], t0, q_mod)); - m[24] = (mulmod(proof[67], proof[82], q_mod)); - m[2] = (mulmod(0, m[2], q_mod)); - m[24] = (addmod(m[2], m[24], q_mod)); - m[25] = (addmod(m[2], proof[83], q_mod)); - m[26] = (addmod(proof[104], q_mod - proof[106], q_mod)); - t0 = (addmod(1, q_mod - proof[102], q_mod)); - m[27] = (mulmod(m[14], t0, q_mod)); - t0 = (mulmod(proof[102], proof[102], q_mod)); - t0 = (addmod(t0, q_mod - proof[102], q_mod)); - m[28] = (mulmod(m[20], t0, q_mod)); - t0 = (addmod(m[24], m[3], q_mod)); - m[24] = (mulmod(proof[102], t0, q_mod)); - m[25] = (addmod(m[25], m[4], q_mod)); - t0 = (mulmod(m[24], m[25], q_mod)); - t0 = (addmod(m[23], q_mod - t0, q_mod)); - m[23] = (mulmod(t0, m[15], q_mod)); - m[24] = (mulmod(m[14], m[26], q_mod)); - t0 = (addmod(proof[104], q_mod - proof[105], q_mod)); - t0 = (mulmod(m[26], t0, q_mod)); - m[26] = (mulmod(t0, m[15], q_mod)); - t0 = (addmod(proof[109], m[3], q_mod)); - m[29] = (mulmod(proof[108], t0, q_mod)); - t0 = (addmod(proof[111], m[4], q_mod)); - m[29] = (mulmod(m[29], t0, q_mod)); - m[30] = (fr_mul_add(proof[82], proof[68], m[2])); - m[31] = (addmod(proof[109], q_mod - proof[111], q_mod)); - t0 = (addmod(1, q_mod - proof[107], q_mod)); - m[32] = (mulmod(m[14], t0, q_mod)); - t0 = (mulmod(proof[107], proof[107], q_mod)); - t0 = (addmod(t0, q_mod - proof[107], q_mod)); - m[33] = (mulmod(m[20], t0, q_mod)); - t0 = (addmod(m[30], m[3], q_mod)); - t0 = (mulmod(proof[107], t0, q_mod)); - t0 = (mulmod(t0, m[25], q_mod)); - t0 = (addmod(m[29], q_mod - t0, q_mod)); - m[29] = (mulmod(t0, m[15], q_mod)); - m[30] = (mulmod(m[14], m[31], q_mod)); - t0 = (addmod(proof[109], q_mod - proof[110], q_mod)); - t0 = (mulmod(m[31], t0, q_mod)); - m[31] = (mulmod(t0, m[15], q_mod)); - t0 = (addmod(proof[114], m[3], q_mod)); - m[34] = (mulmod(proof[113], t0, q_mod)); - t0 = (addmod(proof[116], m[4], q_mod)); - m[34] = (mulmod(m[34], t0, q_mod)); - m[35] = (fr_mul_add(proof[82], proof[69], m[2])); - m[36] = (addmod(proof[114], q_mod - proof[116], q_mod)); - t0 = (addmod(1, q_mod - proof[112], q_mod)); - m[37] = (mulmod(m[14], t0, q_mod)); - t0 = (mulmod(proof[112], proof[112], q_mod)); - t0 = (addmod(t0, q_mod - proof[112], q_mod)); - m[38] = (mulmod(m[20], t0, q_mod)); - t0 = (addmod(m[35], m[3], q_mod)); - t0 = (mulmod(proof[112], t0, q_mod)); - t0 = (mulmod(t0, m[25], q_mod)); - t0 = (addmod(m[34], q_mod - t0, q_mod)); - m[34] = (mulmod(t0, m[15], q_mod)); - m[35] = (mulmod(m[14], m[36], q_mod)); - t0 = (addmod(proof[114], q_mod - proof[115], q_mod)); - t0 = (mulmod(m[36], t0, q_mod)); - m[36] = (mulmod(t0, m[15], q_mod)); - t0 = (addmod(proof[119], m[3], q_mod)); - m[39] = (mulmod(proof[118], t0, q_mod)); - t0 = (addmod(proof[121], m[4], q_mod)); - m[39] = (mulmod(m[39], t0, q_mod)); - m[40] = (fr_mul_add(proof[82], proof[70], m[2])); - m[41] = (addmod(proof[119], q_mod - proof[121], q_mod)); - t0 = (addmod(1, q_mod - proof[117], q_mod)); - m[42] = (mulmod(m[14], t0, q_mod)); - t0 = (mulmod(proof[117], proof[117], q_mod)); - t0 = (addmod(t0, q_mod - proof[117], q_mod)); - m[43] = (mulmod(m[20], t0, q_mod)); - t0 = (addmod(m[40], m[3], q_mod)); - t0 = (mulmod(proof[117], t0, q_mod)); - t0 = (mulmod(t0, m[25], q_mod)); - t0 = (addmod(m[39], q_mod - t0, q_mod)); - m[25] = (mulmod(t0, m[15], q_mod)); - m[39] = (mulmod(m[14], m[41], q_mod)); - t0 = (addmod(proof[119], q_mod - proof[120], q_mod)); - t0 = (mulmod(m[41], t0, q_mod)); - m[40] = (mulmod(t0, m[15], q_mod)); - t0 = (addmod(proof[124], m[3], q_mod)); - m[41] = (mulmod(proof[123], t0, q_mod)); - t0 = (addmod(proof[126], m[4], q_mod)); - m[41] = (mulmod(m[41], t0, q_mod)); - m[44] = (fr_mul_add(proof[84], proof[67], m[2])); - m[45] = (addmod(m[2], proof[85], q_mod)); - m[46] = (addmod(proof[124], q_mod - proof[126], q_mod)); - t0 = (addmod(1, q_mod - proof[122], q_mod)); - m[47] = (mulmod(m[14], t0, q_mod)); - t0 = (mulmod(proof[122], proof[122], q_mod)); - t0 = (addmod(t0, q_mod - proof[122], q_mod)); - m[48] = (mulmod(m[20], t0, q_mod)); - t0 = (addmod(m[44], m[3], q_mod)); - m[44] = (mulmod(proof[122], t0, q_mod)); - t0 = (addmod(m[45], m[4], q_mod)); - t0 = (mulmod(m[44], t0, q_mod)); - t0 = (addmod(m[41], q_mod - t0, q_mod)); - m[41] = (mulmod(t0, m[15], q_mod)); - m[44] = (mulmod(m[14], m[46], q_mod)); - t0 = (addmod(proof[124], q_mod - proof[125], q_mod)); - t0 = (mulmod(m[46], t0, q_mod)); - m[45] = (mulmod(t0, m[15], q_mod)); - t0 = (addmod(proof[129], m[3], q_mod)); - m[46] = (mulmod(proof[128], t0, q_mod)); - t0 = (addmod(proof[131], m[4], q_mod)); - m[46] = (mulmod(m[46], t0, q_mod)); - m[49] = (fr_mul_add(proof[86], proof[67], m[2])); - m[50] = (addmod(m[2], proof[87], q_mod)); - m[51] = (addmod(proof[129], q_mod - proof[131], q_mod)); - t0 = (addmod(1, q_mod - proof[127], q_mod)); - m[52] = (mulmod(m[14], t0, q_mod)); - t0 = (mulmod(proof[127], proof[127], q_mod)); - t0 = (addmod(t0, q_mod - proof[127], q_mod)); - m[53] = (mulmod(m[20], t0, q_mod)); - t0 = (addmod(m[49], m[3], q_mod)); - m[49] = (mulmod(proof[127], t0, q_mod)); - t0 = (addmod(m[50], m[4], q_mod)); - t0 = (mulmod(m[49], t0, q_mod)); - t0 = (addmod(m[46], q_mod - t0, q_mod)); - m[46] = (mulmod(t0, m[15], q_mod)); - m[49] = (mulmod(m[14], m[51], q_mod)); - t0 = (addmod(proof[129], q_mod - proof[130], q_mod)); - t0 = (mulmod(m[51], t0, q_mod)); - m[50] = (mulmod(t0, m[15], q_mod)); - t0 = (addmod(proof[134], m[3], q_mod)); - m[51] = (mulmod(proof[133], t0, q_mod)); - t0 = (addmod(proof[136], m[4], q_mod)); - m[51] = (mulmod(m[51], t0, q_mod)); - m[54] = (fr_mul_add(proof[88], proof[67], m[2])); - m[2] = (addmod(m[2], proof[89], q_mod)); - m[55] = (addmod(proof[134], q_mod - proof[136], q_mod)); - t0 = (addmod(1, q_mod - proof[132], q_mod)); - m[56] = (mulmod(m[14], t0, q_mod)); - t0 = (mulmod(proof[132], proof[132], q_mod)); - t0 = (addmod(t0, q_mod - proof[132], q_mod)); - m[20] = (mulmod(m[20], t0, q_mod)); - t0 = (addmod(m[54], m[3], q_mod)); - m[3] = (mulmod(proof[132], t0, q_mod)); - t0 = (addmod(m[2], m[4], q_mod)); - t0 = (mulmod(m[3], t0, q_mod)); - t0 = (addmod(m[51], q_mod - t0, q_mod)); - m[2] = (mulmod(t0, m[15], q_mod)); - m[3] = (mulmod(m[14], m[55], q_mod)); - t0 = (addmod(proof[134], q_mod - proof[135], q_mod)); - t0 = (mulmod(m[55], t0, q_mod)); - m[4] = (mulmod(t0, m[15], q_mod)); - t0 = (fr_mul_add(m[5], 0, m[16])); - t0 = ( - fr_mul_add_mt(m, m[5], 24064768791442479290152634096194013545513974547709823832001394403118888981009, t0) - ); - t0 = (fr_mul_add_mt(m, m[5], 4704208815882882920750, t0)); - m[2] = (fr_div(t0, m[13])); - m[3] = (mulmod(m[8], m[8], q_mod)); - m[4] = (mulmod(m[3], m[8], q_mod)); - (t0, t1) = (ecc_mul(proof[143], proof[144], m[4])); - (t0, t1) = (ecc_mul_add_pm(m, proof, 281470825071501, t0, t1)); - (m[14], m[15]) = (ecc_add(t0, t1, proof[137], proof[138])); - m[5] = (mulmod(m[4], m[11], q_mod)); - m[11] = (mulmod(m[4], m[7], q_mod)); - m[13] = (mulmod(m[11], m[7], q_mod)); - m[16] = (mulmod(m[13], m[7], q_mod)); - m[17] = (mulmod(m[16], m[7], q_mod)); - m[18] = (mulmod(m[17], m[7], q_mod)); - m[19] = (mulmod(m[18], m[7], q_mod)); - t0 = (mulmod(m[19], proof[135], q_mod)); - t0 = (fr_mul_add_pm(m, proof, 79227007564587019091207590530, t0)); - m[20] = (fr_mul_add(proof[105], m[4], t0)); - m[10] = (mulmod(m[3], m[10], q_mod)); - m[20] = (fr_mul_add(proof[99], m[3], m[20])); - m[9] = (mulmod(m[8], m[9], q_mod)); - m[21] = (mulmod(m[8], m[7], q_mod)); - for (t0 = 0; t0 < 8; t0++) { - m[22 + t0 * 1] = (mulmod(m[21 + t0 * 1], m[7 + t0 * 0], q_mod)); - } - t0 = (mulmod(m[29], proof[133], q_mod)); - t0 = (fr_mul_add_pm(m, proof, 1461480058012745347196003969984389955172320353408, t0)); - m[20] = (addmod(m[20], t0, q_mod)); - m[3] = (addmod(m[3], m[21], q_mod)); - m[21] = (mulmod(m[7], m[7], q_mod)); - m[30] = (mulmod(m[21], m[7], q_mod)); - for (t0 = 0; t0 < 50; t0++) { - m[31 + t0 * 1] = (mulmod(m[30 + t0 * 1], m[7 + t0 * 0], q_mod)); - } - m[81] = (mulmod(m[80], proof[90], q_mod)); - m[82] = (mulmod(m[79], m[12], q_mod)); - m[83] = (mulmod(m[82], m[12], q_mod)); - m[12] = (mulmod(m[83], m[12], q_mod)); - t0 = (fr_mul_add(m[79], m[2], m[81])); - t0 = ( - fr_mul_add_pm(m, proof, 28637501128329066231612878461967933875285131620580756137874852300330784214624, t0) - ); - t0 = ( - fr_mul_add_pm(m, proof, 21474593857386732646168474467085622855647258609351047587832868301163767676495, t0) - ); - t0 = ( - fr_mul_add_pm(m, proof, 14145600374170319983429588659751245017860232382696106927048396310641433325177, t0) - ); - t0 = (fr_mul_add_pm(m, proof, 18446470583433829957, t0)); - t0 = (addmod(t0, proof[66], q_mod)); - m[2] = (addmod(m[20], t0, q_mod)); - m[19] = (addmod(m[19], m[54], q_mod)); - m[20] = (addmod(m[29], m[53], q_mod)); - m[18] = (addmod(m[18], m[51], q_mod)); - m[28] = (addmod(m[28], m[50], q_mod)); - m[17] = (addmod(m[17], m[48], q_mod)); - m[27] = (addmod(m[27], m[47], q_mod)); - m[16] = (addmod(m[16], m[45], q_mod)); - m[26] = (addmod(m[26], m[44], q_mod)); - m[13] = (addmod(m[13], m[42], q_mod)); - m[25] = (addmod(m[25], m[41], q_mod)); - m[11] = (addmod(m[11], m[39], q_mod)); - m[24] = (addmod(m[24], m[38], q_mod)); - m[4] = (addmod(m[4], m[36], q_mod)); - m[23] = (addmod(m[23], m[35], q_mod)); - m[22] = (addmod(m[22], m[34], q_mod)); - m[3] = (addmod(m[3], m[33], q_mod)); - m[8] = (addmod(m[8], m[32], q_mod)); - (t0, t1) = (ecc_mul(proof[143], proof[144], m[5])); - (t0, t1) = ( - ecc_mul_add_pm( - m, - proof, - 10933423423422768024429730621579321771439401845242250760130969989159573132066, - t0, - t1 - ) - ); - (t0, t1) = (ecc_mul_add_pm(m, proof, 1461486238301980199876269201563775120819706402602, t0, t1)); - (t0, t1) = ( - ecc_mul_add( - 12307352371204071280982447264592356604770557236167151424765174303760462590176, - 6738828114747374257112102922036038748323647805843324928244611619348440720206, - m[78], - t0, - t1 - ) - ); - (t0, t1) = ( - ecc_mul_add( - 3572242117438706971950566231972492037272493617550220451749916794782159485990, - 16886246169673548502689746904271067387916898759455168062589790036798273590349, - m[77], - t0, - t1 - ) - ); - (t0, t1) = ( - ecc_mul_add( - 11667701672179251391428332036216303114114878686596844372637022183683605784102, - 4424360138861548935598382331834755349352382522764859897096077224499379358893, - m[76], - t0, - t1 - ) - ); - (t0, t1) = ( - ecc_mul_add( - 11240594699132670076282994399620649156234033942671103470791998382362667407672, - 17410590891928584702846573685036010315759947034684539213237289080064757682376, - m[75], - t0, - t1 - ) - ); - (t0, t1) = ( - ecc_mul_add( - 10431705595614601525988802826965197285907257500319030545448174217748190806819, - 1722933959999977963181823060205533471550038234474886371618129746215350346061, - m[74], - t0, - t1 - ) - ); - (t0, t1) = ( - ecc_mul_add( - 14863668788118458080709552309780821215832907388990302710391373385352975619400, - 9169018986198736700730396443421849971028048839478170199874313312628076354525, - m[73], - t0, - t1 - ) - ); - (t0, t1) = ( - ecc_mul_add( - 5422170891120229182360564594866246906567981360038071999127508208070564034524, - 14722029885921976755274052080011416898514630484317773275415621146460924728182, - m[72], - t0, - t1 - ) - ); - (t0, t1) = ( - ecc_mul_add( - 16688566313919879798220881603072582217705901250983507280549353151657923151225, - 445098670208016740953162173980757005967278816602831621939241146108331296000, - m[71], - t0, - t1 - ) - ); - (t0, t1) = ( - ecc_mul_add( - 18451207565454686459225553564649439057698581050443267052774483067774590965003, - 4419693978684087696088612463773850574955779922948673330581664932100506990694, - m[70], - t0, - t1 - ) - ); - (t0, t1) = ( - ecc_mul_add( - 513112338211370645376563601122653940299862742690848745156963955674379550556, - 19810928912892354135597308070341362773960905471215656964629317311935270323996, - m[69], - t0, - t1 - ) - ); - (t0, t1) = ( - ecc_mul_add( - 5422170891120229182360564594866246906567981360038071999127508208070564034524, - 14722029885921976755274052080011416898514630484317773275415621146460924728182, - m[68], - t0, - t1 - ) - ); - (t0, t1) = ( - ecc_mul_add( - 17445679909532066182757122062586547291967150697181781539174006766798005273657, - 17920199801340037140434307313099628133732498466723263177150297206806678079555, - m[67], - t0, - t1 - ) - ); - (t0, t1) = ( - ecc_mul_add( - 21537162186981550637121053147454964150809482185492418377558290311964245821909, - 2173324946696678910860567153502925685634606622474439126082176533839311460335, - m[66], - t0, - t1 - ) - ); - (t0, t1) = ( - ecc_mul_add( - 13379886303467716633100661055108788127518098273159576422399393845531832231957, - 21249906638915552082114032161592926549649883644681146775463416600414893201674, - m[65], - t0, - t1 - ) - ); - (t0, t1) = ( - ecc_mul_add( - 15157693885943911041713554408535787389704098552723039519149609571282120709253, - 8962689722656126928294285568371442660369086845752902597634306189893971808811, - m[64], - t0, - t1 - ) - ); - (t0, t1) = ( - ecc_mul_add( - 282500810502773337615392632832701051006147314629556169662041861893490731214, - 1405529063404455180686378299193347180609188503983796479637225424184561469680, - m[63], - t0, - t1 - ) - ); - (t0, t1) = ( - ecc_mul_add( - 11581441121680069988106695739022834936323842874155303510513226862110129423436, - 2637320643329934410767647331146883629269877662310710930543876671326457005009, - m[62], - t0, - t1 - ) - ); - (t0, t1) = ( - ecc_mul_add( - 6360815457536167490502686961772031084682621045969143466863419537587018809166, - 10001859183015380960752959272517632163813167330052728059681917034087071226990, - m[61], - t0, - t1 - ) - ); - (t0, t1) = ( - ecc_mul_add( - 21781254208176618175216351429386597067185902632164357922466579817402010196650, - 18011967939699408822151124361783982305672777114883443865079846085493004089455, - m[60], - t0, - t1 - ) - ); - (t0, t1) = ( - ecc_mul_add( - 12550056285320974621731132541688213633166264204189969052965198828791126689449, - 12418566505549505379214997261574757719056298067095922377233136904055538090780, - m[59], - t0, - t1 - ) - ); - (t0, t1) = ( - ecc_mul_add( - 9820677253892770121706802995351466260380886278639412117111326545845072594611, - 2704926883961612314233615484035572222203996626426533880905375148146034288774, - m[58], - t0, - t1 - ) - ); - (t0, t1) = ( - ecc_mul_add( - 3929991866827575569085896493971875891867580103388188978578999736252850472742, - 19719633293434441328320083084584841400798470465761819534504206259130079607839, - m[57], - t0, - t1 - ) - ); - (t0, t1) = ( - ecc_mul_add( - 7226449887868214736840321440792751573104787954076714575187805312000538789936, - 10412613750159988958028585780050254212547419910094153825608548817586948534492, - m[56], - t0, - t1 - ) - ); - (t0, t1) = (ecc_mul_add_pm(m, proof, 6277008573546246765208814532330797927747086570010716419876, t0, t1)); - (m[0], m[1]) = (ecc_add(t0, t1, m[0], m[1])); - (t0, t1) = (ecc_mul(1, 2, m[2])); - (m[0], m[1]) = (ecc_sub(m[0], m[1], t0, t1)); - return (m[14], m[15], m[0], m[1]); - } - - function verify(uint256[] calldata proof, uint256[] calldata target_circuit_final_pair) public view { - uint256[6] memory instances; - instances[0] = target_circuit_final_pair[0] & ((1 << 136) - 1); - instances[1] = (target_circuit_final_pair[0] >> 136) + ((target_circuit_final_pair[1] & 1) << 136); - instances[2] = target_circuit_final_pair[2] & ((1 << 136) - 1); - instances[3] = (target_circuit_final_pair[2] >> 136) + ((target_circuit_final_pair[3] & 1) << 136); - - instances[4] = target_circuit_final_pair[4]; - instances[5] = target_circuit_final_pair[5]; - - uint256 x0 = 0; - uint256 x1 = 0; - uint256 y0 = 0; - uint256 y1 = 0; - - G1Point[] memory g1_points = new G1Point[](2); - G2Point[] memory g2_points = new G2Point[](2); - bool checked = false; - - (x0, y0, x1, y1) = get_wx_wg(proof, instances); - g1_points[0].x = x0; - g1_points[0].y = y0; - g1_points[1].x = x1; - g1_points[1].y = y1; - g2_points[0] = get_verify_circuit_g2_s(); - g2_points[1] = get_verify_circuit_g2_n(); - - checked = pairing(g1_points, g2_points); - require(checked); - - g1_points[0].x = target_circuit_final_pair[0]; - g1_points[0].y = target_circuit_final_pair[1]; - g1_points[1].x = target_circuit_final_pair[2]; - g1_points[1].y = target_circuit_final_pair[3]; - g2_points[0] = get_target_circuit_g2_s(); - g2_points[1] = get_target_circuit_g2_n(); - - checked = pairing(g1_points, g2_points); - require(checked); - } -} diff --git a/contracts/src/libraries/verifier/WithdrawTrieVerifier.sol b/contracts/src/libraries/verifier/WithdrawTrieVerifier.sol deleted file mode 100644 index c54092545..000000000 --- a/contracts/src/libraries/verifier/WithdrawTrieVerifier.sol +++ /dev/null @@ -1,54 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.24; - -// solhint-disable no-inline-assembly - -library WithdrawTrieVerifier { - /// @dev Verify the merkle proof given root, leaf node and proof. - /// - /// Vulnerability: - /// The initially provided message hash can be hashed with the first hash of the proof, - /// thereby giving an intermediate node of the trie. This can then be used with a shortened - /// proof to pass the verification, which may lead to replayability. - /// - /// However, it is designed to verify the withdraw trie in `L2MessageQueue`. The `_hash` given - /// in the parameter is always a leaf node. So we assume the length of proof is correct and - /// cannot be shortened. - /// @param _root The expected root node hash of the withdraw trie. - /// @param _hash The leaf node hash of the withdraw trie. - /// @param _nonce The index of the leaf node from left to right, starting from 0. - /// @param _proof The concatenated merkle proof verified the leaf node. - function verifyMerkleProof( - bytes32 _root, - bytes32 _hash, - uint256 _nonce, - bytes memory _proof - ) internal pure returns (bool) { - require(_proof.length % 32 == 0, "Invalid proof"); - uint256 _length = _proof.length / 32; - - for (uint256 i = 0; i < _length; i++) { - bytes32 item; - assembly { - item := mload(add(add(_proof, 0x20), mul(i, 0x20))) - } - if (_nonce % 2 == 0) { - _hash = _efficientHash(_hash, item); - } else { - _hash = _efficientHash(item, _hash); - } - _nonce /= 2; - } - return _hash == _root; - } - - function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) { - // solhint-disable-next-line no-inline-assembly - assembly { - mstore(0x00, a) - mstore(0x20, b) - value := keccak256(0x00, 0x40) - } - } -} diff --git a/contracts/src/libraries/verifier/ZkEvmVerifierV1.sol b/contracts/src/libraries/verifier/ZkEvmVerifierV1.sol deleted file mode 100644 index 45bfe909d..000000000 --- a/contracts/src/libraries/verifier/ZkEvmVerifierV1.sol +++ /dev/null @@ -1,65 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {IZkEvmVerifier} from "./IZkEvmVerifier.sol"; - -// solhint-disable no-inline-assembly - -contract ZkEvmVerifierV1 is IZkEvmVerifier { - /********** - * Errors * - **********/ - - /// @dev Thrown when aggregate zk proof verification is failed. - error VerificationFailed(); - - /************* - * Constants * - *************/ - - /// @notice The address of highly optimized plonk verifier contract. - address public immutable plonkVerifier; - - /*************** - * Constructor * - ***************/ - - constructor(address _verifier) { - plonkVerifier = _verifier; - } - - /************************* - * Public View Functions * - *************************/ - - /// @inheritdoc IZkEvmVerifier - function verify(bytes calldata aggrProof, bytes32 publicInputHash) external view override { - address _verifier = plonkVerifier; - bool success; - - // 1. the first 12 * 32 (0x180) bytes of `aggrProof` is `accumulator` - // 2. the rest bytes of `aggrProof` is the actual `batch_aggregated_proof` - // 3. each byte of the `public_input_hash` should be converted to a `uint256` and the - // 1024 (0x400) bytes should inserted between `accumulator` and `batch_aggregated_proof`. - assembly { - let p := mload(0x40) - calldatacopy(p, aggrProof.offset, 0x180) - for { - let i := 0 - } lt(i, 0x400) { - i := add(i, 0x20) - } { - mstore(add(p, sub(0x560, i)), and(publicInputHash, 0xff)) - publicInputHash := shr(8, publicInputHash) - } - calldatacopy(add(p, 0x580), add(aggrProof.offset, 0x180), sub(aggrProof.length, 0x180)) - - success := staticcall(gas(), _verifier, p, add(aggrProof.length, 0x400), 0x00, 0x00) - } - - if (!success) { - revert VerificationFailed(); - } - } -} diff --git a/contracts/src/libraries/verifier/ZkTrieVerifier.sol b/contracts/src/libraries/verifier/ZkTrieVerifier.sol deleted file mode 100644 index 4bb5932d8..000000000 --- a/contracts/src/libraries/verifier/ZkTrieVerifier.sol +++ /dev/null @@ -1,273 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.24; - -// solhint-disable no-inline-assembly - -library ZkTrieVerifier { - /// @notice Internal function to validates a proof from eth_getProof. - /// @param poseidon The address of poseidon hash contract. - /// @param account The address of the contract. - /// @param storageKey The storage slot to verify. - /// @param proof The rlp encoding result of eth_getProof. - /// @return stateRoot The computed state root. Must be checked by the caller. - /// @return storageValue The value of `storageKey`. - /// - /// @dev The code is based on - /// 1. https://github.com/scroll-tech/go-ethereum/blob/staging/trie/zk_trie.go#L176 - /// 2. https://github.com/scroll-tech/zktrie/blob/main/trie/zk_trie_proof.go#L30 - /// - /// The encoding order of `proof` is - /// ```text - /// | 1 byte | ... | 1 byte | ... | - /// | account proof length | account proof | storage proof length | storage proof | - /// ``` - /// - /// Possible attack vector: - /// + Malicious users can influence how many levels the proof must go through by predicting addresses - /// (or storage slots) that would branch the Trie until a certain depth. Even though artificially - /// increasing the proof's depth of a certain account or storage will not cause a DoS scenario, since - /// the depth can still reach the maximum depth size in the worst-case scenario, artificially increasing - /// the proof's depth will increase the number of iterations the `walkTree` method has to perform in order - /// to reach the respective leaf. If protocols that use this verifier limit the gas used on-chain to perform - /// such a verification (to a reasonable value), then a malicious user might be able to increase it for a - /// particular transaction by reaching a similar hashed key to a certain depth in the Trie. - function verifyZkTrieProof( - address poseidon, - address account, - bytes32 storageKey, - bytes calldata proof - ) internal view returns (bytes32 stateRoot, bytes32 storageValue) { - assembly { - // reverts with error `msg`. - // make sure the length of error string <= 32 - function revertWith(msg) { - // keccak("Error(string)") - mstore(0x00, 0x08c379a000000000000000000000000000000000000000000000000000000000) - mstore(0x04, 0x20) // str.offset - mstore(0x44, msg) - let msgLen - for { - - } msg { - - } { - msg := shl(8, msg) - msgLen := add(msgLen, 1) - } - mstore(0x24, msgLen) // str.length - revert(0x00, 0x64) - } - // reverts with `msg` when condition is not matched. - // make sure the length of error string <= 32 - function require(cond, msg) { - if iszero(cond) { - revertWith(msg) - } - } - // compute poseidon hash of two uint256 - function poseidonHash(hasher, v0, v1, domain) -> r { - let x := mload(0x40) - // keccack256("poseidon(uint256[2],uint256)") - mstore(x, 0xa717016c00000000000000000000000000000000000000000000000000000000) - mstore(add(x, 0x04), v0) - mstore(add(x, 0x24), v1) - mstore(add(x, 0x44), domain) - let success := staticcall(gas(), hasher, x, 0x64, 0x20, 0x20) - require(success, "poseidon hash failed") - r := mload(0x20) - } - // compute poseidon hash of 1 uint256 - function hashUint256(hasher, v) -> r { - r := poseidonHash(hasher, shr(128, v), and(v, 0xffffffffffffffffffffffffffffffff), 512) - } - - // traverses the tree from the root to the node before the leaf. - // based on https://github.com/ethereum/go-ethereum/blob/master/trie/proof.go#L114 - function walkTree(hasher, key, _ptr) -> ptr, rootHash, expectedHash { - ptr := _ptr - - // the first byte is the number of nodes + 1 - let nodes := sub(byte(0, calldataload(ptr)), 1) - require(lt(nodes, 249), "InvalidNodeDepth") - ptr := add(ptr, 0x01) - - // treat the leaf node with different logic - for { - let depth := 1 - } lt(depth, nodes) { - depth := add(depth, 1) - } { - // must be a parent node with two children - let nodeType := byte(0, calldataload(ptr)) - // 6 <= nodeType && nodeType < 10 - require(lt(sub(nodeType, 6), 4), "InvalidBranchNodeType") - ptr := add(ptr, 0x01) - - // load left/right child hash - let childHashL := calldataload(ptr) - ptr := add(ptr, 0x20) - let childHashR := calldataload(ptr) - ptr := add(ptr, 0x20) - let hash := poseidonHash(hasher, childHashL, childHashR, nodeType) - - // first item is considered the root node. - // Otherwise verifies that the hash of the current node - // is the same as the previous chosen one. - switch depth - case 1 { - rootHash := hash - } - default { - require(eq(hash, expectedHash), "BranchHashMismatch") - } - - // decide which path to walk based on key - switch and(key, 1) - case 0 { - expectedHash := childHashL - } - default { - expectedHash := childHashR - } - key := shr(1, key) - } - } - - function checkProofMagicBytes(hasher, _ptr) -> ptr { - ptr := _ptr - let x := mload(0x40) - calldatacopy(x, ptr, 0x2d) - x := keccak256(x, 0x2d) - require( - eq(x, 0x950654da67865a81bc70e45f3230f5179f08e29c66184bf746f71050f117b3b8), - "InvalidProofMagicBytes" - ) - ptr := add(ptr, 0x2d) // skip ProofMagicBytes - } - - function verifyAccountProof(hasher, _account, _ptr) -> ptr, storageRootHash, _stateRoot { - ptr := _ptr - - let leafHash - let key := hashUint256(hasher, shl(96, _account)) - - // `stateRoot` is a return value and must be checked by the caller - ptr, _stateRoot, leafHash := walkTree(hasher, key, ptr) - - switch byte(0, calldataload(ptr)) - case 4 { - // nonempty leaf node - ptr := add(ptr, 0x01) // skip NodeType - require(eq(calldataload(ptr), key), "AccountKeyMismatch") - ptr := add(ptr, 0x20) // skip NodeKey - require(eq(shr(224, calldataload(ptr)), 0x05080000), "InvalidAccountCompressedFlag") - ptr := add(ptr, 0x04) // skip CompressedFlag - - // compute value hash for State Account Leaf Node, details can be found in - // https://github.com/scroll-tech/mpt-circuit/blob/v0.7/spec/mpt-proof.md#account-segmenttypes - // [nonce||codesize||0, balance, storage_root, keccak codehash, poseidon codehash] - mstore(0x00, calldataload(ptr)) - ptr := add(ptr, 0x20) // skip nonce||codesize||0 - mstore(0x00, poseidonHash(hasher, mload(0x00), calldataload(ptr), 1280)) - ptr := add(ptr, 0x20) // skip balance - storageRootHash := calldataload(ptr) - ptr := add(ptr, 0x20) // skip StorageRoot - let tmpHash := hashUint256(hasher, calldataload(ptr)) - ptr := add(ptr, 0x20) // skip KeccakCodeHash - tmpHash := poseidonHash(hasher, storageRootHash, tmpHash, 1280) - tmpHash := poseidonHash(hasher, mload(0x00), tmpHash, 1280) - tmpHash := poseidonHash(hasher, tmpHash, calldataload(ptr), 1280) - ptr := add(ptr, 0x20) // skip PoseidonCodeHash - - tmpHash := poseidonHash(hasher, key, tmpHash, 4) - require(eq(leafHash, tmpHash), "InvalidAccountLeafNodeHash") - - require(eq(0x20, byte(0, calldataload(ptr))), "InvalidAccountKeyPreimageLength") - ptr := add(ptr, 0x01) // skip KeyPreimage length - require(eq(shl(96, _account), calldataload(ptr)), "InvalidAccountKeyPreimage") - ptr := add(ptr, 0x20) // skip KeyPreimage - } - case 5 { - ptr := add(ptr, 0x01) // skip NodeType - } - default { - revertWith("InvalidAccountLeafNodeType") - } - - // compare ProofMagicBytes - ptr := checkProofMagicBytes(hasher, ptr) - } - - function verifyStorageProof(hasher, _storageKey, storageRootHash, _ptr) -> ptr, _storageValue { - ptr := _ptr - - let leafHash - let key := hashUint256(hasher, _storageKey) - let rootHash - ptr, rootHash, leafHash := walkTree(hasher, key, ptr) - - // The root hash of the storage tree must match the value from the account leaf. - // But when the leaf node is the same as the root node, the function `walkTree` will return - // `rootHash=0` and `leafHash=0`. In such case, we don't need to check the value of `rootHash`. - // And the value of `leafHash` should be the same as `storageRootHash`. - switch rootHash - case 0 { - leafHash := storageRootHash - } - default { - require(eq(rootHash, storageRootHash), "StorageRootMismatch") - } - - switch byte(0, calldataload(ptr)) - case 4 { - ptr := add(ptr, 0x01) // skip NodeType - require(eq(calldataload(ptr), key), "StorageKeyMismatch") - ptr := add(ptr, 0x20) // skip NodeKey - require(eq(shr(224, calldataload(ptr)), 0x01010000), "InvalidStorageCompressedFlag") - ptr := add(ptr, 0x04) // skip CompressedFlag - _storageValue := calldataload(ptr) - ptr := add(ptr, 0x20) // skip StorageValue - - // compute leaf node hash and compare, details can be found in - // https://github.com/scroll-tech/mpt-circuit/blob/v0.7/spec/mpt-proof.md#storage-segmenttypes - mstore(0x00, hashUint256(hasher, _storageValue)) - mstore(0x00, poseidonHash(hasher, key, mload(0x00), 4)) - require(eq(leafHash, mload(0x00)), "InvalidStorageLeafNodeHash") - - require(eq(0x20, byte(0, calldataload(ptr))), "InvalidStorageKeyPreimageLength") - ptr := add(ptr, 0x01) // skip KeyPreimage length - require(eq(_storageKey, calldataload(ptr)), "InvalidStorageKeyPreimage") - ptr := add(ptr, 0x20) // skip KeyPreimage - } - case 5 { - ptr := add(ptr, 0x01) // skip NodeType - require(eq(leafHash, 0), "InvalidStorageEmptyLeafNodeHash") - } - default { - revertWith("InvalidStorageLeafNodeType") - } - - // compare ProofMagicBytes - ptr := checkProofMagicBytes(hasher, ptr) - } - - let storageRootHash - let ptr := proof.offset - - // check the correctness of account proof - ptr, storageRootHash, stateRoot := verifyAccountProof(poseidon, account, ptr) - - // check the correctness of storage proof - ptr, storageValue := verifyStorageProof(poseidon, storageKey, storageRootHash, ptr) - - // the one and only boundary check - // in case an attacker crafted a malicious payload - // and succeeds in the prior verification steps - // then this should catch any bogus accesses - if iszero(eq(ptr, add(proof.offset, proof.length))) { - revertWith("ProofLengthMismatch") - } - } - } -} diff --git a/contracts/src/libraries/verifier/plonk-verifier/plonk_verifier_0.9.8.bin b/contracts/src/libraries/verifier/plonk-verifier/plonk_verifier_0.9.8.bin deleted file mode 100644 index 6b38f5da8..000000000 Binary files a/contracts/src/libraries/verifier/plonk-verifier/plonk_verifier_0.9.8.bin and /dev/null differ diff --git a/contracts/src/lido/L1LidoGateway.sol b/contracts/src/lido/L1LidoGateway.sol deleted file mode 100644 index c3b87e91f..000000000 --- a/contracts/src/lido/L1LidoGateway.sol +++ /dev/null @@ -1,154 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {IL1ERC20Gateway} from "../L1/gateways/IL1ERC20Gateway.sol"; -import {L1ERC20Gateway} from "../L1/gateways/L1ERC20Gateway.sol"; -import {IL1ScrollMessenger} from "../L1/IL1ScrollMessenger.sol"; -import {IL2ERC20Gateway} from "../L2/gateways/IL2ERC20Gateway.sol"; -import {ScrollGatewayBase} from "../libraries/gateway/ScrollGatewayBase.sol"; - -import {LidoBridgeableTokens} from "./LidoBridgeableTokens.sol"; -import {LidoGatewayManager} from "./LidoGatewayManager.sol"; - -contract L1LidoGateway is L1ERC20Gateway, LidoBridgeableTokens, LidoGatewayManager { - /********** - * Errors * - **********/ - - /// @dev Thrown when deposit zero amount token. - error ErrorDepositZeroAmount(); - - /// @dev Thrown when deposit erc20 with calldata. - error DepositAndCallIsNotAllowed(); - - /************* - * Variables * - *************/ - - /// @dev The initial version of `L1LidoGateway` use `L1CustomERC20Gateway`. We keep the storage - /// slot for `tokenMapping` for compatibility. It should no longer be used. - mapping(address => address) private __tokenMapping; - - /*************** - * Constructor * - ***************/ - - /// @notice Constructor for `L1LidoGateway` implementation contract. - /// - /// @param _l1Token The address of the bridged token in the L1 chain - /// @param _l2Token The address of the token minted on the L2 chain when token bridged - /// @param _counterpart The address of `L2LidoGateway` contract in L2. - /// @param _router The address of `L1GatewayRouter` contract. - /// @param _messenger The address of `L1ScrollMessenger` contract. - constructor( - address _l1Token, - address _l2Token, - address _counterpart, - address _router, - address _messenger - ) LidoBridgeableTokens(_l1Token, _l2Token) ScrollGatewayBase(_counterpart, _router, _messenger) { - if (_l1Token == address(0) || _l2Token == address(0) || _router == address(0)) { - revert ErrorZeroAddress(); - } - - _disableInitializers(); - } - - /// @notice Initialize the storage of L1LidoGateway v1. - /// - /// @dev The parameters `_counterpart`, `_router` and `_messenger` are no longer used. - /// - /// @param _counterpart The address of `L2LidoGateway` contract in L2. - /// @param _router The address of `L1GatewayRouter` contract. - /// @param _messenger The address of `L1ScrollMessenger` contract. - function initialize( - address _counterpart, - address _router, - address _messenger - ) external initializer { - ScrollGatewayBase._initialize(_counterpart, _router, _messenger); - } - - /// @notice Initialize the storage of L1LidoGateway v2. - /// @param _depositsEnabler The address of user who can enable deposits - /// @param _depositsEnabler The address of user who can disable deposits - /// @param _withdrawalsEnabler The address of user who can enable withdrawals - /// @param _withdrawalsDisabler The address of user who can disable withdrawals - function initializeV2( - address _depositsEnabler, - address _depositsDisabler, - address _withdrawalsEnabler, - address _withdrawalsDisabler - ) external reinitializer(2) { - __LidoGatewayManager_init(_depositsEnabler, _depositsDisabler, _withdrawalsEnabler, _withdrawalsDisabler); - } - - /************************* - * Public View Functions * - *************************/ - - /// @inheritdoc IL1ERC20Gateway - function getL2ERC20Address(address _l1Token) - external - view - override - onlySupportedL1Token(_l1Token) - returns (address) - { - return l2Token; - } - - /********************** - * Internal Functions * - **********************/ - - /// @inheritdoc L1ERC20Gateway - /// @dev The length of `_data` always be zero, which guarantee by `L2LidoGateway`. - function _beforeFinalizeWithdrawERC20( - address _l1Token, - address _l2Token, - address, - address, - uint256, - bytes calldata - ) internal virtual override onlySupportedL1Token(_l1Token) onlySupportedL2Token(_l2Token) whenWithdrawalsEnabled { - if (msg.value != 0) revert ErrorNonZeroMsgValue(); - } - - /// @inheritdoc L1ERC20Gateway - function _beforeDropMessage( - address _token, - address, - uint256 - ) internal virtual override onlySupportedL1Token(_token) { - if (msg.value != 0) revert ErrorNonZeroMsgValue(); - } - - /// @inheritdoc L1ERC20Gateway - function _deposit( - address _token, - address _to, - uint256 _amount, - bytes memory _data, - uint256 _gasLimit - ) internal virtual override nonReentrant onlySupportedL1Token(_token) onlyNonZeroAccount(_to) whenDepositsEnabled { - if (_amount == 0) revert ErrorDepositZeroAmount(); - - // 1. Transfer token into this contract. - address _from; - (_from, _amount, _data) = _transferERC20In(_token, _amount, _data); - if (_data.length != 0) revert DepositAndCallIsNotAllowed(); - - // 2. Generate message passed to L2LidoGateway. - bytes memory _message = abi.encodeCall( - IL2ERC20Gateway.finalizeDepositERC20, - (_token, l2Token, _from, _to, _amount, _data) - ); - - // 3. Send message to L1ScrollMessenger. - IL1ScrollMessenger(messenger).sendMessage{value: msg.value}(counterpart, 0, _message, _gasLimit, _from); - - emit DepositERC20(_token, l2Token, _from, _to, _amount, _data); - } -} diff --git a/contracts/src/lido/L2LidoGateway.sol b/contracts/src/lido/L2LidoGateway.sol deleted file mode 100644 index 310b44ced..000000000 --- a/contracts/src/lido/L2LidoGateway.sol +++ /dev/null @@ -1,187 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {IL1ERC20Gateway} from "../L1/gateways/IL1ERC20Gateway.sol"; -import {IL2ERC20Gateway} from "../L2/gateways/IL2ERC20Gateway.sol"; -import {L2ERC20Gateway} from "../L2/gateways/L2ERC20Gateway.sol"; -import {IL2ScrollMessenger} from "../L2/IL2ScrollMessenger.sol"; -import {IScrollERC20Upgradeable} from "../libraries/token/IScrollERC20Upgradeable.sol"; -import {ScrollGatewayBase} from "../libraries/gateway/ScrollGatewayBase.sol"; - -import {LidoBridgeableTokens} from "./LidoBridgeableTokens.sol"; -import {LidoGatewayManager} from "./LidoGatewayManager.sol"; - -contract L2LidoGateway is L2ERC20Gateway, LidoBridgeableTokens, LidoGatewayManager { - /********** - * Errors * - **********/ - - /// @dev Thrown when withdraw zero amount token. - error ErrorWithdrawZeroAmount(); - - /// @dev Thrown when withdraw erc20 with calldata. - error WithdrawAndCallIsNotAllowed(); - - /************* - * Variables * - *************/ - - /// @dev The initial version of `L2LidoGateway` use `L2CustomERC20Gateway`. We keep the storage - /// slot for `tokenMapping` for compatibility. It should no longer be used. - mapping(address => address) private __tokenMapping; - - /*************** - * Constructor * - ***************/ - - /// @notice Constructor for `L2LidoGateway` implementation contract. - /// - /// @param _l1Token The address of the bridged token in the L1 chain - /// @param _l2Token The address of the token minted on the L2 chain when token bridged - /// @param _counterpart The address of `L1LidoGateway` contract in L1. - /// @param _router The address of `L2GatewayRouter` contract in L2. - /// @param _messenger The address of `L2ScrollMessenger` contract in L2. - constructor( - address _l1Token, - address _l2Token, - address _counterpart, - address _router, - address _messenger - ) LidoBridgeableTokens(_l1Token, _l2Token) ScrollGatewayBase(_counterpart, _router, _messenger) { - if (_l1Token == address(0) || _l2Token == address(0) || _router == address(0)) { - revert ErrorZeroAddress(); - } - - _disableInitializers(); - } - - /// @notice Initialize the storage of L2LidoGateway v1. - /// - /// @dev The parameters `_counterpart`, `_router` and `_messenger` are no longer used. - /// - /// @param _counterpart The address of `L1LidoGateway` contract in L1. - /// @param _router The address of `L2GatewayRouter` contract in L2. - /// @param _messenger The address of `L2ScrollMessenger` contract in L2. - function initialize( - address _counterpart, - address _router, - address _messenger - ) external initializer { - ScrollGatewayBase._initialize(_counterpart, _router, _messenger); - } - - /// @notice Initialize the storage of L2LidoGateway v2. - /// @param _depositsEnabler The address of user who can enable deposits - /// @param _depositsEnabler The address of user who can disable deposits - /// @param _withdrawalsEnabler The address of user who can enable withdrawals - /// @param _withdrawalsDisabler The address of user who can disable withdrawals - function initializeV2( - address _depositsEnabler, - address _depositsDisabler, - address _withdrawalsEnabler, - address _withdrawalsDisabler - ) external reinitializer(2) { - __LidoGatewayManager_init(_depositsEnabler, _depositsDisabler, _withdrawalsEnabler, _withdrawalsDisabler); - } - - /************************* - * Public View Functions * - *************************/ - - /// @inheritdoc IL2ERC20Gateway - function getL1ERC20Address(address _l2Token) - external - view - override - onlySupportedL2Token(_l2Token) - returns (address) - { - return l1Token; - } - - /// @inheritdoc IL2ERC20Gateway - function getL2ERC20Address(address _l1Token) - external - view - override - onlySupportedL1Token(_l1Token) - returns (address) - { - return l2Token; - } - - /***************************** - * Public Mutating Functions * - *****************************/ - - /// @inheritdoc IL2ERC20Gateway - /// @dev The length of `_data` always be zero, which guarantee by `L1LidoGateway`. - function finalizeDepositERC20( - address _l1Token, - address _l2Token, - address _from, - address _to, - uint256 _amount, - bytes calldata _data - ) - external - payable - override - onlyCallByCounterpart - nonReentrant - onlySupportedL1Token(_l1Token) - onlySupportedL2Token(_l2Token) - whenDepositsEnabled - { - if (msg.value != 0) revert ErrorNonZeroMsgValue(); - - IScrollERC20Upgradeable(_l2Token).mint(_to, _amount); - - emit FinalizeDepositERC20(_l1Token, _l2Token, _from, _to, _amount, _data); - } - - /********************** - * Internal Functions * - **********************/ - - /// @inheritdoc L2ERC20Gateway - function _withdraw( - address _l2Token, - address _to, - uint256 _amount, - bytes memory _data, - uint256 _gasLimit - ) - internal - virtual - override - nonReentrant - onlySupportedL2Token(_l2Token) - onlyNonZeroAccount(_to) - whenWithdrawalsEnabled - { - if (_amount == 0) revert ErrorWithdrawZeroAmount(); - - // 1. Extract real sender if this call is from L2GatewayRouter. - address _from = _msgSender(); - if (router == _from) { - (_from, _data) = abi.decode(_data, (address, bytes)); - } - if (_data.length != 0) revert WithdrawAndCallIsNotAllowed(); - - // 2. Burn token. - IScrollERC20Upgradeable(_l2Token).burn(_from, _amount); - - // 3. Generate message passed to L1LidoGateway. - bytes memory _message = abi.encodeCall( - IL1ERC20Gateway.finalizeWithdrawERC20, - (l1Token, _l2Token, _from, _to, _amount, _data) - ); - - // 4. send message to L2ScrollMessenger - IL2ScrollMessenger(messenger).sendMessage{value: msg.value}(counterpart, 0, _message, _gasLimit); - - emit WithdrawERC20(l1Token, _l2Token, _from, _to, _amount, _data); - } -} diff --git a/contracts/src/lido/L2WstETHToken.sol b/contracts/src/lido/L2WstETHToken.sol deleted file mode 100644 index 63e90c0c8..000000000 --- a/contracts/src/lido/L2WstETHToken.sol +++ /dev/null @@ -1,49 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {IERC20PermitUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20PermitUpgradeable.sol"; -import {ERC20PermitUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20PermitUpgradeable.sol"; -import {SignatureCheckerUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/SignatureCheckerUpgradeable.sol"; - -import {ScrollStandardERC20} from "../libraries/token/ScrollStandardERC20.sol"; - -contract L2WstETHToken is ScrollStandardERC20 { - /************* - * Constants * - *************/ - - /// @dev See {ERC20PermitUpgradeable-_PERMIT_TYPEHASH} - bytes32 private constant _PERMIT_TYPEHASH = - keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"); - - /***************************** - * Public Mutating Functions * - *****************************/ - - /// @inheritdoc IERC20PermitUpgradeable - /// - /// @dev The code is copied from `ERC20PermitUpgradeable` with modifications to support ERC-1271. - function permit( - address owner, - address spender, - uint256 value, - uint256 deadline, - uint8 v, - bytes32 r, - bytes32 s - ) public virtual override(ERC20PermitUpgradeable, IERC20PermitUpgradeable) { - require(block.timestamp <= deadline, "ERC20Permit: expired deadline"); - - bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline)); - - bytes32 hash = _hashTypedDataV4(structHash); - - require( - SignatureCheckerUpgradeable.isValidSignatureNow(owner, hash, abi.encodePacked(r, s, v)), - "ERC20Permit: invalid signature" - ); - - _approve(owner, spender, value); - } -} diff --git a/contracts/src/lido/LidoBridgeableTokens.sol b/contracts/src/lido/LidoBridgeableTokens.sol deleted file mode 100644 index 2da95ba1b..000000000 --- a/contracts/src/lido/LidoBridgeableTokens.sol +++ /dev/null @@ -1,70 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -abstract contract LidoBridgeableTokens { - /************* - * Constants * - *************/ - - /// @notice The address of bridged token in L1 chain. - address public immutable l1Token; - - /// @notice The address of the token minted on the L2 chain when token bridged. - address public immutable l2Token; - - /********** - * Errors * - **********/ - - /// @dev Thrown the given `l1Token` is not supported. - error ErrorUnsupportedL1Token(); - - /// @dev Thrown the given `l2Token` is not supported. - error ErrorUnsupportedL2Token(); - - /// @dev Thrown the given account is zero address. - error ErrorAccountIsZeroAddress(); - - /// @dev Thrown the `msg.value` is not zero. - error ErrorNonZeroMsgValue(); - - /********************** - * Function Modifiers * - **********************/ - - /// @dev Validates that passed `_l1Token` is supported by the bridge - modifier onlySupportedL1Token(address _l1Token) { - if (_l1Token != l1Token) { - revert ErrorUnsupportedL1Token(); - } - _; - } - - /// @dev Validates that passed `_l2Token` is supported by the bridge - modifier onlySupportedL2Token(address _l2Token) { - if (_l2Token != l2Token) { - revert ErrorUnsupportedL2Token(); - } - _; - } - - /// @dev validates that `_account` is not zero address - modifier onlyNonZeroAccount(address _account) { - if (_account == address(0)) { - revert ErrorAccountIsZeroAddress(); - } - _; - } - - /*************** - * Constructor * - ***************/ - - /// @param _l1Token The address of the bridged token in the L1 chain - /// @param _l2Token The address of the token minted on the L2 chain when token bridged - constructor(address _l1Token, address _l2Token) { - l1Token = _l1Token; - l2Token = _l2Token; - } -} diff --git a/contracts/src/lido/LidoGatewayManager.sol b/contracts/src/lido/LidoGatewayManager.sol deleted file mode 100644 index dd4d80984..000000000 --- a/contracts/src/lido/LidoGatewayManager.sol +++ /dev/null @@ -1,288 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {EnumerableSetUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol"; - -import {ScrollGatewayBase} from "../libraries/gateway/ScrollGatewayBase.sol"; - -// solhint-disable func-name-mixedcase - -abstract contract LidoGatewayManager is ScrollGatewayBase { - using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet; - - /********** - * Events * - **********/ - - /// @notice Emitted then caller enable deposits. - /// @param enabler The address of caller. - event DepositsEnabled(address indexed enabler); - - /// @notice Emitted then caller disable deposits. - /// @param disabler The address of caller. - event DepositsDisabled(address indexed disabler); - - /// @notice Emitted then caller enable withdrawals. - /// @param enabler The address of caller. - event WithdrawalsEnabled(address indexed enabler); - - /// @notice Emitted then caller disable withdrawals. - /// @param disabler The address of caller. - event WithdrawalsDisabled(address indexed disabler); - - /// @notice Emitted when `account` is granted `role`. - /// - /// @param role The role granted. - /// @param account The address of account to grant the role. - /// @param sender The address of owner. - event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); - - /// @notice Emitted when `account` is revoked `role`. - /// - /// @param role The role revoked. - /// @param account The address of account to revoke the role. - /// @param sender The address of owner. - event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); - - /********** - * Errors * - **********/ - - /// @dev Thrown when deposits are enabled while caller try to enable it again. - error ErrorDepositsEnabled(); - - /// @dev Thrown when deposits are disable while caller try to deposits related operation. - error ErrorDepositsDisabled(); - - /// @dev Thrown when withdrawals are enabled while caller try to enable it again. - error ErrorWithdrawalsEnabled(); - - /// @dev Thrown when withdrawals are disable while caller try to withdrawals related operation. - error ErrorWithdrawalsDisabled(); - - /// @dev Thrown when caller is not deposits enabler. - error ErrorCallerIsNotDepositsEnabler(); - - /// @dev Thrown when caller is not deposits disabler. - error ErrorCallerIsNotDepositsDisabler(); - - /// @dev Thrown when caller is not withdrawals enabler. - error ErrorCallerIsNotWithdrawalsEnabler(); - - /// @dev Thrown when caller is not withdrawals disabler. - error ErrorCallerIsNotWithdrawalsDisabler(); - - /*********** - * Structs * - ***********/ - - /// @dev Stores the state of the bridging - /// @param isDepositsEnabled Stores the state of the deposits - /// @param isWithdrawalsEnabled Stores the state of the withdrawals - /// @param roles Mapping from role to list of role members. - struct State { - bool isDepositsEnabled; - bool isWithdrawalsEnabled; - mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) roles; - } - - /************* - * Constants * - *************/ - - /// @dev The location of the slot with State - bytes32 private constant STATE_SLOT = keccak256("LidoGatewayManager.bridgingState"); - - /// @notice The role for deposits enabler. - bytes32 public constant DEPOSITS_ENABLER_ROLE = keccak256("BridgingManager.DEPOSITS_ENABLER_ROLE"); - - /// @notice The role for deposits disabler. - bytes32 public constant DEPOSITS_DISABLER_ROLE = keccak256("BridgingManager.DEPOSITS_DISABLER_ROLE"); - - /// @notice The role for withdrawals enabler. - bytes32 public constant WITHDRAWALS_ENABLER_ROLE = keccak256("BridgingManager.WITHDRAWALS_ENABLER_ROLE"); - - /// @notice The role for withdrawals disabler. - bytes32 public constant WITHDRAWALS_DISABLER_ROLE = keccak256("BridgingManager.WITHDRAWALS_DISABLER_ROLE"); - - /********************** - * Function Modifiers * - **********************/ - - /// @dev Validates that deposits are enabled - modifier whenDepositsEnabled() { - if (!isDepositsEnabled()) revert ErrorDepositsDisabled(); - _; - } - - /// @dev Validates that withdrawals are enabled - modifier whenWithdrawalsEnabled() { - if (!isWithdrawalsEnabled()) revert ErrorWithdrawalsDisabled(); - _; - } - - /*************** - * Constructor * - ***************/ - - /// @notice Initialize the storage of LidoGatewayManager. - /// @param _depositsEnabler The address of user who can enable deposits - /// @param _depositsEnabler The address of user who can disable deposits - /// @param _withdrawalsEnabler The address of user who can enable withdrawals - /// @param _withdrawalsDisabler The address of user who can disable withdrawals - function __LidoGatewayManager_init( - address _depositsEnabler, - address _depositsDisabler, - address _withdrawalsEnabler, - address _withdrawalsDisabler - ) internal onlyInitializing { - State storage s = _loadState(); - - s.isDepositsEnabled = true; - emit DepositsEnabled(_msgSender()); - - s.isWithdrawalsEnabled = true; - emit WithdrawalsEnabled(_msgSender()); - - _grantRole(DEPOSITS_ENABLER_ROLE, _depositsEnabler); - _grantRole(DEPOSITS_DISABLER_ROLE, _depositsDisabler); - _grantRole(WITHDRAWALS_ENABLER_ROLE, _withdrawalsEnabler); - _grantRole(WITHDRAWALS_DISABLER_ROLE, _withdrawalsDisabler); - } - - /************************* - * Public View Functions * - *************************/ - - /// @notice Returns whether the deposits are enabled or not - function isDepositsEnabled() public view returns (bool) { - return _loadState().isDepositsEnabled; - } - - /// @notice Returns whether the withdrawals are enabled or not - function isWithdrawalsEnabled() public view returns (bool) { - return _loadState().isWithdrawalsEnabled; - } - - /// @notice Returns `true` if `_account` has been granted `_role`. - function hasRole(bytes32 _role, address _account) public view returns (bool) { - return _loadState().roles[_role].contains(_account); - } - - /// @notice Returns one of the accounts that have `_role`. - /// - /// @param _role The role to query. - /// @param _index The index of account to query. It must be a value between 0 and {getRoleMemberCount}, non-inclusive. - function getRoleMember(bytes32 _role, uint256 _index) external view returns (address) { - return _loadState().roles[_role].at(_index); - } - - /// @notice Returns the number of accounts that have `role`. - /// - /// @dev Can be used together with {getRoleMember} to enumerate all bearers of a role. - /// - /// @param _role The role to query. - function getRoleMemberCount(bytes32 _role) external view returns (uint256) { - return _loadState().roles[_role].length(); - } - - /************************ - * Restricted Functions * - ************************/ - - /// @notice Enables the deposits if they are disabled - function enableDeposits() external { - if (isDepositsEnabled()) revert ErrorDepositsEnabled(); - if (!hasRole(DEPOSITS_ENABLER_ROLE, _msgSender())) { - revert ErrorCallerIsNotDepositsEnabler(); - } - - _loadState().isDepositsEnabled = true; - emit DepositsEnabled(_msgSender()); - } - - /// @notice Disables the deposits if they aren't disabled yet - function disableDeposits() external whenDepositsEnabled { - if (!hasRole(DEPOSITS_DISABLER_ROLE, _msgSender())) { - revert ErrorCallerIsNotDepositsDisabler(); - } - - _loadState().isDepositsEnabled = false; - emit DepositsDisabled(_msgSender()); - } - - /// @notice Enables the withdrawals if they are disabled - function enableWithdrawals() external { - if (isWithdrawalsEnabled()) revert ErrorWithdrawalsEnabled(); - if (!hasRole(WITHDRAWALS_ENABLER_ROLE, _msgSender())) { - revert ErrorCallerIsNotWithdrawalsEnabler(); - } - - _loadState().isWithdrawalsEnabled = true; - emit WithdrawalsEnabled(_msgSender()); - } - - /// @notice Disables the withdrawals if they aren't disabled yet - function disableWithdrawals() external whenWithdrawalsEnabled { - if (!hasRole(WITHDRAWALS_DISABLER_ROLE, _msgSender())) { - revert ErrorCallerIsNotWithdrawalsDisabler(); - } - - _loadState().isWithdrawalsEnabled = false; - emit WithdrawalsDisabled(_msgSender()); - } - - /// @notice Grants `_role` from `_account`. - /// If `account` had been granted `role`, emits a {RoleGranted} event. - /// - /// @param _role The role to grant. - /// @param _account The address of account to grant. - function grantRole(bytes32 _role, address _account) external onlyOwner { - _grantRole(_role, _account); - } - - /// @notice Revokes `_role` from `_account`. - /// If `account` had been granted `role`, emits a {RoleRevoked} event. - /// - /// @param _role The role to revoke. - /// @param _account The address of account to revoke. - function revokeRole(bytes32 _role, address _account) external onlyOwner { - _revokeRole(_role, _account); - } - - /********************** - * Internal Functions * - **********************/ - - /// @dev Returns the reference to the slot with State struct - function _loadState() private pure returns (State storage r) { - bytes32 slot = STATE_SLOT; - // solhint-disable-next-line no-inline-assembly - assembly { - r.slot := slot - } - } - - /// @dev Internal function to grant `_role` from `_account`. - /// If `account` had been granted `role`, emits a {RoleGranted} event. - /// - /// @param _role The role to grant. - /// @param _account The address of account to grant. - function _grantRole(bytes32 _role, address _account) internal { - if (_loadState().roles[_role].add(_account)) { - emit RoleGranted(_role, _account, _msgSender()); - } - } - - /// @dev Internal function to revoke `_role` from `_account`. - /// If `account` had been granted `role`, emits a {RoleRevoked} event. - /// - /// @param _role The role to revoke. - /// @param _account The address of account to revoke. - function _revokeRole(bytes32 _role, address _account) internal { - if (_loadState().roles[_role].remove(_account)) { - emit RoleRevoked(_role, _account, _msgSender()); - } - } -} diff --git a/contracts/src/lido/README.md b/contracts/src/lido/README.md deleted file mode 100644 index 85bda92e6..000000000 --- a/contracts/src/lido/README.md +++ /dev/null @@ -1,105 +0,0 @@ -# Lido's Scroll Bridge - -The document details the implementation of the bridging of the ERC20 compatible tokens[^*] between Ethereum and Scroll chains. - -It's the first step of Lido's integration into the Scroll protocol. The main goal of the current implementation is to be the strong foundation for the long-term goals of the Lido expansion in the Scroll chain. The long-run picture of the Lido's integration into L2s includes: - -- Bridging of Lido's tokens from L1 to L2 chains -- Instant ETH staking on L2 chains with receiving stETH/wstETH on the corresponding L2 immediately -- Keeping UX on L2 as close as possible to the UX on Ethereum mainnet - -At this point, the implementation must provide a scalable and reliable solution for Lido to bridge ERC20 compatible tokens between Scroll and the Ethereum chain. - -[^*]: The current implementation might not support the non-standard functionality of the ERC20 tokens. For example, rebasable tokens or tokens with transfers fee will work incorrectly. In case your token implements some non-typical ERC20 logic, make sure it is compatible with the bridge before usage. - -## Security surface overview - -| Statement | Answer | -| -------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| It is possible to bridge wstETH forth and back using this bridge | Yes | -| The bridge using a canonical mechanism for message/value passing | Yes | -| The bridge is upgradeable | Yes | -| Upgrade authority for the bridge | TBA | -| Emergency pause/cancel mechanisms and their authorities | TBA | -| The bridged token support permits and ERC-1271 | Yes | -| Are the following things in the scope of this bridge deployment: | | -| - Passing the (w)stETH/USD price feed | No | -| - Passing Lido DAO governance decisions | [Lido DAO Agent](https://etherscan.io/address/0x3e40D73EB977Dc6a537aF587D48316feE66E9C8c) representation [on Scroll (address TBD)] via [ScrollBridgeExecutor](https://github.com/scroll-tech/governance-crosschain-bridges/blob/scroll/contracts/bridges/ScrollBridgeExecutor.sol) | -| Bridges are complicated in that the transaction can succeed on one side and fail on the other. What's the handling mechanism for this issue? | TBA | -| Is there a deployment script that sets all the parameters and authorities correctly? | No, we are upgrading from existing gateway, will need to involve multisig operation by Scroll | -| Is there a post-deploy check script that, given a deployment, checks that all parameters and authorities are set correctly? | No | - -## Scroll's Bridging Flow - -The default implementation of the Scroll bridging solution consists of two parts: `L1StandardERC20Gateway` and `L2StandardERC20Gateway`. These contracts allow bridging the ERC20 tokens between Ethereum and Scroll chains. - -In the standard bridge, when ERC20 is deposited on L1 and transferred to the bridge contract it remains "locked" there while the equivalent amount is minted in the L2 token. For withdrawals, the opposite happens the L2 token amount is burned then the same amount of L1 tokens is transferred to the recipient. - -The default Scroll bridge is suitable for the short-term goal of the Lido (bridging of the wstETH token into Scroll), but it complicates the achievement of the long-term goals. For example, implementation of the staking from L2's very likely will require extending the token and gateway implementations. - -Additionally, Scroll provides functionality to implement the custom bridge solution utilizing the same cross-domain infrastructure as the Standard bridge. The only constraint for the custom bridge to be compatible with the default Scroll Gateway is the implementation of the `IL1ERC20Gateway` and `IL2ERC20Gateway` interfaces. - -The rest of the document provides a technical specification of the bridge Lido will use to transfer tokens between Ethereum and Scroll chains. - -## Lido's Bridge Implementation - -The current implementation of the tokens bridge provides functionality to bridge the specified type of ERC20 compatible token between Ethereum and Scroll chains. Additionally, the bridge provides some administrative features, like the **temporary disabling of the deposits and withdrawals**. It's necessary when bridging must be disabled fast because of the malicious usage of the bridge or vulnerability in the contracts. Also, it might be helpful in the implementation upgrade process. - -The technical implementation focuses on the following requirements for the contracts: - -- **Scalability** - current implementation must provide the ability to be extended with new functionality in the future. -- **Simplicity** - implemented contracts must be clear, simple, and expressive for developers who will work with code in the future. -- **Gas efficiency** - implemented solution must be efficient in terms of gas costs for the end-user, but at the same time, it must not violate the previous requirement. - -A high-level overview of the proposed solution might be found in the below diagram: - -![](https://i.imgur.com/7UaVuto.png) - -- [**`LidoGatewayManager`**](./LidoGatewayManager.sol) - contains administrative methods to retrieve and control the state of the bridging process. -- [**`LidoBridgeableTokens`**](./LidoBridgeableTokens.sol) - contains the logic for validation of tokens used in the bridging process. -- [**`L1LidoGateway`**](./L1LidoGateway.sol) - Ethereum's counterpart of the bridge to bridge registered ERC20 compatible tokens between Ethereum and Scroll chains. -- [**`L2LidoGateway`**](./L2LidoGateway.sol) - Scroll's counterpart of the bridge to bridge registered ERC20 compatible tokens between Ethereum and Scroll chains -- [**`ScrollStandardERC20`**](../libraries/token/ScrollStandardERC20.sol) - an implementation of the `ERC20` token with administrative methods to mint and burn tokens. -- [**`TransparentUpgradeableProxy`**](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/proxy/transparent/TransparentUpgradeableProxy.sol) - the ERC1967 proxy with extra admin functionality. - -## Scroll's Bridging Flow - -The general process of bridging tokens via Scroll's Lido bridge can be found here: [ETH and ERC20 Token Bridge](https://docs.scroll.io/en/developers/l1-and-l2-bridging/eth-and-erc20-token-bridge/). - -## Deployment Process - -To reduce the gas costs for users, contracts `L1LidoGateway`, `L2LidoGateway`, and `ScrollStandardERC20` contracts use immutable variables as much as possible. But some of those variables are cross-referred. For example, `L1LidoGateway` has reference to `L2LidoGateway` and vice versa. As we use proxies, we can deploy proxies at first and without calling the `initialize` function from each gateway. Then call the `initialize` function with correct contract addresses. - -Another option - pre-calculate the future address of the deployed contract offchain and deployed the implementation using pre-calculated addresses. But it is less fault-tolerant than the solution above. - -## Integration Risks - -As an additional link in the tokens flow chain, the Scroll protocol and bridges add points of failure. Below are the main risks of the current integration: - -### Minting of uncollateralized L2 token - -Such an attack might happen if an attacker obtains the right to call `L2LidoGateway.finalizeDepositERC20()` directly. In such a scenario, an attacker can mint uncollaterized tokens on L2 and initiate withdrawal later. - -The best way to detect such an attack is an offchain monitoring of the minting and depositing/withdrawal events. Based on such events might be tracked following stats: - -- `l1ERC20TokenBridgeBalance` - a total number of locked tokens on the L1 bridge contract -- `l2TokenTotalSupply` - total number of minted L2 tokens -- `l2TokenNotWithdrawn` - total number of burned L2 tokens which aren’t withdrawn from the L1 bridge - -At any time following invariant must be satisfied: `l1ERC20TokenBridgeBalance == l2TokenTotalSupply + l2TokenNotWithdrawn`. - -In the case of invariant violation, Lido will have a dispute period to suspend the L1 and L2 bridges. Disabled bridges forbid the minting of L2Token and withdrawal of minted tokens till the resolution of the issue. - -### Attack to L1ScrollMessenger - -According to the Scroll documentation, `L1ScrollMessenger`: - -> The L1 Scroll Messenger contract sends messages from L1 to L2 and relays messages from L2 onto L1. - -This contract is central in the L2-to-L1 communication process since all messages from L2 that verified by the zkevm proof are executed on behalf of this contract. - -In case of a vulnerability in the `L1ScrollMessenger`, which allows the attacker to send arbitrary messages bypassing the zkevm proof, an attacker can immediately drain tokens from the L1 bridge. - -Additional risk creates the upgradeability of the `L1ScrollMessenger`. Exist a risk of an attack with the replacement of the implementation with some malicious functionality. Such an attack might be reduced to the above vulnerability and steal all locked tokens on the L1 bridge. - -To respond quickly to such an attack, Lido can set up monitoring of the Proxy contract, which will ring the alarm in case of an implementation upgrade. diff --git a/contracts/src/misc/ERC2771Forwarder.sol b/contracts/src/misc/ERC2771Forwarder.sol deleted file mode 100644 index 8e1b4d690..000000000 --- a/contracts/src/misc/ERC2771Forwarder.sol +++ /dev/null @@ -1,391 +0,0 @@ -// SPDX-License-Identifier: MIT - -// @note This file is directly copied from OpenZeppelin's master branch: -// https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/metatx/ERC2771Forwarder.sol -// Modifications are made to make it compatible with solidity 0.8.16. - -pragma solidity =0.8.24; - -import {ERC2771Context} from "@openzeppelin/contracts/metatx/ERC2771Context.sol"; -import {ECDSA} from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; -import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol"; -import {Nonces} from "./Nonces.sol"; -import {Address} from "@openzeppelin/contracts/utils/Address.sol"; - -/** - * @dev A forwarder compatible with ERC2771 contracts. See {ERC2771Context}. - * - * This forwarder operates on forward requests that include: - * - * * `from`: An address to operate on behalf of. It is required to be equal to the request signer. - * * `to`: The address that should be called. - * * `value`: The amount of native token to attach with the requested call. - * * `gas`: The amount of gas limit that will be forwarded with the requested call. - * * `nonce`: A unique transaction ordering identifier to avoid replayability and request invalidation. - * * `deadline`: A timestamp after which the request is not executable anymore. - * * `data`: Encoded `msg.data` to send with the requested call. - * - * Relayers are able to submit batches if they are processing a high volume of requests. With high - * throughput, relayers may run into limitations of the chain such as limits on the number of - * transactions in the mempool. In these cases the recommendation is to distribute the load among - * multiple accounts. - * - * NOTE: Batching requests includes an optional refund for unused `msg.value` that is achieved by - * performing a call with empty calldata. While this is within the bounds of ERC-2771 compliance, - * if the refund receiver happens to consider the forwarder a trusted forwarder, it MUST properly - * handle `msg.data.length == 0`. `ERC2771Context` in OpenZeppelin Contracts versions prior to 4.9.3 - * do not handle this properly. - * - * ==== Security Considerations - * - * If a relayer submits a forward request, it should be willing to pay up to 100% of the gas amount - * specified in the request. This contract does not implement any kind of retribution for this gas, - * and it is assumed that there is an out of band incentive for relayers to pay for execution on - * behalf of signers. Often, the relayer is operated by a project that will consider it a user - * acquisition cost. - * - * By offering to pay for gas, relayers are at risk of having that gas used by an attacker toward - * some other purpose that is not aligned with the expected out of band incentives. If you operate a - * relayer, consider whitelisting target contracts and function selectors. When relaying ERC-721 or - * ERC-1155 transfers specifically, consider rejecting the use of the `data` field, since it can be - * used to execute arbitrary code. - */ -contract ERC2771Forwarder is EIP712, Nonces { - using ECDSA for bytes32; - - struct ForwardRequestData { - address from; - address to; - uint256 value; - uint256 gas; - uint48 deadline; - bytes data; - bytes signature; - } - - bytes32 internal constant _FORWARD_REQUEST_TYPEHASH = - keccak256( - "ForwardRequest(address from,address to,uint256 value,uint256 gas,uint256 nonce,uint48 deadline,bytes data)" - ); - - /** - * @dev Emitted when a `ForwardRequest` is executed. - * - * NOTE: An unsuccessful forward request could be due to an invalid signature, an expired deadline, - * or simply a revert in the requested call. The contract guarantees that the relayer is not able to force - * the requested call to run out of gas. - */ - event ExecutedForwardRequest(address indexed signer, uint256 nonce, bool success); - - /** - * @dev The request `from` doesn't match with the recovered `signer`. - */ - error ERC2771ForwarderInvalidSigner(address signer, address from); - - /** - * @dev The `requestedValue` doesn't match with the available `msgValue`. - */ - error ERC2771ForwarderMismatchedValue(uint256 requestedValue, uint256 msgValue); - - /** - * @dev The request `deadline` has expired. - */ - error ERC2771ForwarderExpiredRequest(uint48 deadline); - - /** - * @dev The request target doesn't trust the `forwarder`. - */ - error ERC2771UntrustfulTarget(address target, address forwarder); - - /** - * @dev A call to an address target failed. The target may have reverted. - */ - error FailedInnerCall(); - - /** - * @dev See {EIP712-constructor}. - */ - constructor(string memory name) EIP712(name, "1") {} - - /** - * @dev Returns `true` if a request is valid for a provided `signature` at the current block timestamp. - * - * A transaction is considered valid when the target trusts this forwarder, the request hasn't expired - * (deadline is not met), and the signer matches the `from` parameter of the signed request. - * - * NOTE: A request may return false here but it won't cause {executeBatch} to revert if a refund - * receiver is provided. - */ - function verify(ForwardRequestData calldata request) public view virtual returns (bool) { - (bool isTrustedForwarder, bool active, bool signerMatch, ) = _validate(request); - return isTrustedForwarder && active && signerMatch; - } - - /** - * @dev Executes a `request` on behalf of `signature`'s signer using the ERC-2771 protocol. The gas - * provided to the requested call may not be exactly the amount requested, but the call will not run - * out of gas. Will revert if the request is invalid or the call reverts, in this case the nonce is not consumed. - * - * Requirements: - * - * - The request value should be equal to the provided `msg.value`. - * - The request should be valid according to {verify}. - */ - function execute(ForwardRequestData calldata request) public payable virtual { - // We make sure that msg.value and request.value match exactly. - // If the request is invalid or the call reverts, this whole function - // will revert, ensuring value isn't stuck. - if (msg.value != request.value) { - revert ERC2771ForwarderMismatchedValue(request.value, msg.value); - } - - if (!_execute(request, true)) { - revert FailedInnerCall(); - } - } - - /** - * @dev Batch version of {execute} with optional refunding and atomic execution. - * - * In case a batch contains at least one invalid request (see {verify}), the - * request will be skipped and the `refundReceiver` parameter will receive back the - * unused requested value at the end of the execution. This is done to prevent reverting - * the entire batch when a request is invalid or has already been submitted. - * - * If the `refundReceiver` is the `address(0)`, this function will revert when at least - * one of the requests was not valid instead of skipping it. This could be useful if - * a batch is required to get executed atomically (at least at the top-level). For example, - * refunding (and thus atomicity) can be opt-out if the relayer is using a service that avoids - * including reverted transactions. - * - * Requirements: - * - * - The sum of the requests' values should be equal to the provided `msg.value`. - * - All of the requests should be valid (see {verify}) when `refundReceiver` is the zero address. - * - * NOTE: Setting a zero `refundReceiver` guarantees an all-or-nothing requests execution only for - * the first-level forwarded calls. In case a forwarded request calls to a contract with another - * subcall, the second-level call may revert without the top-level call reverting. - */ - function executeBatch(ForwardRequestData[] calldata requests, address payable refundReceiver) - public - payable - virtual - { - bool atomic = refundReceiver == address(0); - - uint256 requestsValue; - uint256 refundValue; - - for (uint256 i; i < requests.length; ++i) { - requestsValue += requests[i].value; - bool success = _execute(requests[i], atomic); - if (!success) { - refundValue += requests[i].value; - } - } - - // The batch should revert if there's a mismatched msg.value provided - // to avoid request value tampering - if (requestsValue != msg.value) { - revert ERC2771ForwarderMismatchedValue(requestsValue, msg.value); - } - - // Some requests with value were invalid (possibly due to frontrunning). - // To avoid leaving ETH in the contract this value is refunded. - if (refundValue != 0) { - // We know refundReceiver != address(0) && requestsValue == msg.value - // meaning we can ensure refundValue is not taken from the original contract's balance - // and refundReceiver is a known account. - Address.sendValue(refundReceiver, refundValue); - } - } - - /** - * @dev Validates if the provided request can be executed at current block timestamp with - * the given `request.signature` on behalf of `request.signer`. - */ - function _validate(ForwardRequestData calldata request) - internal - view - virtual - returns ( - bool isTrustedForwarder, - bool active, - bool signerMatch, - address signer - ) - { - (bool isValid, address recovered) = _recoverForwardRequestSigner(request); - - return ( - _isTrustedByTarget(request.to), - request.deadline >= block.timestamp, - isValid && recovered == request.from, - recovered - ); - } - - /** - * @dev Returns a tuple with the recovered the signer of an EIP712 forward request message hash - * and a boolean indicating if the signature is valid. - * - * NOTE: The signature is considered valid if {ECDSA-tryRecover} indicates no recover error for it. - */ - function _recoverForwardRequestSigner(ForwardRequestData calldata request) - internal - view - virtual - returns (bool, address) - { - (address recovered, ECDSA.RecoverError err) = _hashTypedDataV4( - keccak256( - abi.encode( - _FORWARD_REQUEST_TYPEHASH, - request.from, - request.to, - request.value, - request.gas, - nonces(request.from), - request.deadline, - keccak256(request.data) - ) - ) - ).tryRecover(request.signature); - - return (err == ECDSA.RecoverError.NoError, recovered); - } - - /** - * @dev Validates and executes a signed request returning the request call `success` value. - * - * Internal function without msg.value validation. - * - * Requirements: - * - * - The caller must have provided enough gas to forward with the call. - * - The request must be valid (see {verify}) if the `requireValidRequest` is true. - * - * Emits an {ExecutedForwardRequest} event. - * - * IMPORTANT: Using this function doesn't check that all the `msg.value` was sent, potentially - * leaving value stuck in the contract. - */ - function _execute(ForwardRequestData calldata request, bool requireValidRequest) - internal - virtual - returns (bool success) - { - (bool isTrustedForwarder, bool active, bool signerMatch, address signer) = _validate(request); - - // Need to explicitly specify if a revert is required since non-reverting is default for - // batches and reversion is opt-in since it could be useful in some scenarios - if (requireValidRequest) { - if (!isTrustedForwarder) { - revert ERC2771UntrustfulTarget(request.to, address(this)); - } - - if (!active) { - revert ERC2771ForwarderExpiredRequest(request.deadline); - } - - if (!signerMatch) { - revert ERC2771ForwarderInvalidSigner(signer, request.from); - } - } - - // Ignore an invalid request because requireValidRequest = false - if (isTrustedForwarder && signerMatch && active) { - // Nonce should be used before the call to prevent reusing by reentrancy - uint256 currentNonce = _useNonce(signer); - - uint256 reqGas = request.gas; - address to = request.to; - uint256 value = request.value; - bytes memory data = abi.encodePacked(request.data, request.from); - - uint256 gasLeft; - - assembly { - success := call(reqGas, to, value, add(data, 0x20), mload(data), 0, 0) - gasLeft := gas() - } - - _checkForwardedGas(gasLeft, request); - - emit ExecutedForwardRequest(signer, currentNonce, success); - } - } - - /** - * @dev Returns whether the target trusts this forwarder. - * - * This function performs a static call to the target contract calling the - * {ERC2771Context-isTrustedForwarder} function. - */ - function _isTrustedByTarget(address target) private view returns (bool) { - bytes memory encodedParams = abi.encodeCall(ERC2771Context.isTrustedForwarder, (address(this))); - - bool success; - uint256 returnSize; - uint256 returnValue; - /// @solidity memory-safe-assembly - assembly { - // Perform the staticcal and save the result in the scratch space. - // | Location | Content | Content (Hex) | - // |-----------|----------|--------------------------------------------------------------------| - // | | | result ↓ | - // | 0x00:0x1F | selector | 0x0000000000000000000000000000000000000000000000000000000000000001 | - success := staticcall(gas(), target, add(encodedParams, 0x20), mload(encodedParams), 0, 0x20) - returnSize := returndatasize() - returnValue := mload(0) - } - - return success && returnSize >= 0x20 && returnValue > 0; - } - - /** - * @dev Checks if the requested gas was correctly forwarded to the callee. - * - * As a consequence of https://eips.ethereum.org/EIPS/eip-150[EIP-150]: - * - At most `gasleft() - floor(gasleft() / 64)` is forwarded to the callee. - * - At least `floor(gasleft() / 64)` is kept in the caller. - * - * It reverts consuming all the available gas if the forwarded gas is not the requested gas. - * - * IMPORTANT: The `gasLeft` parameter should be measured exactly at the end of the forwarded call. - * Any gas consumed in between will make room for bypassing this check. - */ - function _checkForwardedGas(uint256 gasLeft, ForwardRequestData calldata request) private pure { - // To avoid insufficient gas griefing attacks, as referenced in https://ronan.eth.limo/blog/ethereum-gas-dangers/ - // - // A malicious relayer can attempt to shrink the gas forwarded so that the underlying call reverts out-of-gas - // but the forwarding itself still succeeds. In order to make sure that the subcall received sufficient gas, - // we will inspect gasleft() after the forwarding. - // - // Let X be the gas available before the subcall, such that the subcall gets at most X * 63 / 64. - // We can't know X after CALL dynamic costs, but we want it to be such that X * 63 / 64 >= req.gas. - // Let Y be the gas used in the subcall. gasleft() measured immediately after the subcall will be gasleft() = X - Y. - // If the subcall ran out of gas, then Y = X * 63 / 64 and gasleft() = X - Y = X / 64. - // Under this assumption req.gas / 63 > gasleft() is true is true if and only if - // req.gas / 63 > X / 64, or equivalently req.gas > X * 63 / 64. - // This means that if the subcall runs out of gas we are able to detect that insufficient gas was passed. - // - // We will now also see that req.gas / 63 > gasleft() implies that req.gas >= X * 63 / 64. - // The contract guarantees Y <= req.gas, thus gasleft() = X - Y >= X - req.gas. - // - req.gas / 63 > gasleft() - // - req.gas / 63 >= X - req.gas - // - req.gas >= X * 63 / 64 - // In other words if req.gas < X * 63 / 64 then req.gas / 63 <= gasleft(), thus if the relayer behaves honestly - // the forwarding does not revert. - if (gasLeft < request.gas / 63) { - // We explicitly trigger invalid opcode to consume all gas and bubble-up the effects, since - // neither revert or assert consume all gas since Solidity 0.8.20 - // https://docs.soliditylang.org/en/v0.8.20/control-structures.html#panic-via-assert-and-error-via-require - /// @solidity memory-safe-assembly - assembly { - invalid() - } - } - } -} diff --git a/contracts/src/misc/EmptyContract.sol b/contracts/src/misc/EmptyContract.sol deleted file mode 100644 index 635e8565d..000000000 --- a/contracts/src/misc/EmptyContract.sol +++ /dev/null @@ -1,8 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity =0.8.24; - -// solhint-disable no-empty-blocks - -contract EmptyContract { - -} diff --git a/contracts/src/misc/Fallback.sol b/contracts/src/misc/Fallback.sol deleted file mode 100644 index ba12f3d68..000000000 --- a/contracts/src/misc/Fallback.sol +++ /dev/null @@ -1,36 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; -import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; - -contract Fallback is Ownable { - using SafeERC20 for IERC20; - - /// @notice Withdraw stucked token from this contract. - /// @param _token The address of token to withdraw, use `address(0)` if withdraw ETH. - /// @param _amount The amount of token to withdraw. - /// @param _recipient The address of receiver. - function withdraw( - address _token, - uint256 _amount, - address _recipient - ) external onlyOwner { - if (_token == address(0)) { - (bool _success, ) = _recipient.call{value: _amount}(""); - require(_success, "transfer ETH failed"); - } else { - IERC20(_token).safeTransfer(_recipient, _amount); - } - } - - /// @notice Execute an arbitrary message. - /// @param _target The address of contract to call. - /// @param _data The calldata passed to target contract. - function execute(address _target, bytes calldata _data) external payable onlyOwner { - (bool _success, ) = _target.call{value: msg.value}(_data); - require(_success, "call failed"); - } -} diff --git a/contracts/src/misc/Nonces.sol b/contracts/src/misc/Nonces.sol deleted file mode 100644 index 7c761498b..000000000 --- a/contracts/src/misc/Nonces.sol +++ /dev/null @@ -1,51 +0,0 @@ -// SPDX-License-Identifier: MIT - -// @note This file is directly copied from OpenZeppelin's master branch: -// https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Nonces.sol -// Modifications are made to make it compatible with solidity 0.8.16. - -pragma solidity ^0.8.24; - -/** - * @dev Provides tracking nonces for addresses. Nonces will only increment. - */ -abstract contract Nonces { - /** - * @dev The nonce used for an `account` is not the expected current nonce. - */ - error InvalidAccountNonce(address account, uint256 currentNonce); - - mapping(address => uint256) private _nonces; - - /** - * @dev Returns an the next unused nonce for an address. - */ - function nonces(address owner) public view virtual returns (uint256) { - return _nonces[owner]; - } - - /** - * @dev Consumes a nonce. - * - * Returns the current value and increments nonce. - */ - function _useNonce(address owner) internal virtual returns (uint256) { - // For each account, the nonce has an initial value of 0, can only be incremented by one, and cannot be - // decremented or reset. This guarantees that the nonce never overflows. - unchecked { - // It is important to do x++ and not ++x here. - return _nonces[owner]++; - } - } - - /** - * @dev Same as {_useNonce} but checking that `nonce` is the next valid for `owner`. - */ - function _useCheckedNonce(address owner, uint256 nonce) internal virtual returns (uint256) { - uint256 current = _useNonce(owner); - if (nonce != current) { - revert InvalidAccountNonce(owner, current); - } - return current; - } -} diff --git a/contracts/src/misc/ScrollOwner.sol b/contracts/src/misc/ScrollOwner.sol deleted file mode 100644 index bb3bace7c..000000000 --- a/contracts/src/misc/ScrollOwner.sol +++ /dev/null @@ -1,150 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {AccessControlEnumerable} from "@openzeppelin/contracts/access/AccessControlEnumerable.sol"; -import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; - -// solhint-disable no-empty-blocks - -contract ScrollOwner is AccessControlEnumerable { - using EnumerableSet for EnumerableSet.Bytes32Set; - - /********** - * Events * - **********/ - - /// @notice Emitted when the access to target contract is granted. - /// @param role The role to grant access. - /// @param target The address of target contract. - /// @param selectors The list of function selectors to grant access. - event GrantAccess(bytes32 indexed role, address indexed target, bytes4[] selectors); - - /// @notice Emitted when the access to target contract is revoked. - /// @param role The role to revoke access. - /// @param target The address of target contract. - /// @param selectors The list of function selectors to revoke access. - event RevokeAccess(bytes32 indexed role, address indexed target, bytes4[] selectors); - - /************* - * Variables * - *************/ - - /// @notice Mapping from target address to selector to the list of accessible roles. - mapping(address => mapping(bytes4 => EnumerableSet.Bytes32Set)) private targetAccess; - - /********************** - * Function Modifiers * - **********************/ - - modifier hasAccess( - address _target, - bytes4 _selector, - bytes32 _role - ) { - // admin has access to all methods - require(_role == DEFAULT_ADMIN_ROLE || targetAccess[_target][_selector].contains(_role), "no access"); - _; - } - - /*************** - * Constructor * - ***************/ - - constructor() { - _grantRole(DEFAULT_ADMIN_ROLE, _msgSender()); - } - - /************************* - * Public View Functions * - *************************/ - - /// @notice Return a list of roles which has access to the function. - /// @param _target The address of target contract. - /// @param _selector The function selector to query. - /// @return _roles The list of roles. - function callableRoles(address _target, bytes4 _selector) external view returns (bytes32[] memory _roles) { - EnumerableSet.Bytes32Set storage _lists = targetAccess[_target][_selector]; - _roles = new bytes32[](_lists.length()); - for (uint256 i = 0; i < _roles.length; i++) { - _roles[i] = _lists.at(i); - } - } - - /***************************** - * Public Mutating Functions * - *****************************/ - - /// @notice Perform a function call from arbitrary role. - /// @param _target The address of target contract. - /// @param _value The value passing to target contract. - /// @param _data The calldata passing to target contract. - /// @param _role The expected role of the caller. - function execute( - address _target, - uint256 _value, - bytes calldata _data, - bytes32 _role - ) external payable onlyRole(_role) hasAccess(_target, bytes4(_data[0:4]), _role) { - _execute(_target, _value, _data); - } - - // allow others to send ether to this contract. - receive() external payable {} - - /************************ - * Restricted Functions * - ************************/ - - /// @notice Update the access to target contract. - /// @param _target The address of target contract. - /// @param _selectors The list of function selectors to update. - /// @param _role The role to change. - /// @param _status True if we are going to add the role, otherwise remove the role. - function updateAccess( - address _target, - bytes4[] memory _selectors, - bytes32 _role, - bool _status - ) external onlyRole(DEFAULT_ADMIN_ROLE) { - if (_status) { - for (uint256 i = 0; i < _selectors.length; i++) { - targetAccess[_target][_selectors[i]].add(_role); - } - - emit GrantAccess(_role, _target, _selectors); - } else { - for (uint256 i = 0; i < _selectors.length; i++) { - targetAccess[_target][_selectors[i]].remove(_role); - } - - emit RevokeAccess(_role, _target, _selectors); - } - } - - /********************** - * Internal Functions * - **********************/ - - /// @dev Internal function to call contract. If the call reverted, the error will be popped up. - /// @param _target The address of target contract. - /// @param _value The value passing to target contract. - /// @param _data The calldata passing to target contract. - function _execute( - address _target, - uint256 _value, - bytes calldata _data - ) private { - // solhint-disable-next-line avoid-low-level-calls - (bool success, ) = _target.call{value: _value}(_data); - if (!success) { - // solhint-disable-next-line no-inline-assembly - assembly { - let ptr := mload(0x40) - let size := returndatasize() - returndatacopy(ptr, 0, size) - revert(ptr, size) - } - } - } -} diff --git a/contracts/src/mocks/MockCaller.sol b/contracts/src/mocks/MockCaller.sol deleted file mode 100644 index 9c253c2c7..000000000 --- a/contracts/src/mocks/MockCaller.sol +++ /dev/null @@ -1,19 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -contract MockCaller { - function callTarget(address to, bytes calldata data) external payable { - // solhint-disable-next-line avoid-low-level-calls - (bool success, ) = address(to).call{value: msg.value}(data); - if (!success) { - // solhint-disable-next-line no-inline-assembly - assembly { - let ptr := mload(0x40) - let size := returndatasize() - returndatacopy(ptr, 0, size) - revert(ptr, size) - } - } - } -} diff --git a/contracts/src/mocks/MockERC20.sol b/contracts/src/mocks/MockERC20.sol deleted file mode 100644 index 3e3e4997a..000000000 --- a/contracts/src/mocks/MockERC20.sol +++ /dev/null @@ -1,37 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; -import "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol"; - -contract MockERC20 is Ownable, ERC20Permit { - uint8 private decimals_; - - constructor( - string memory _name, - string memory _symbol, - uint8 _decimals - ) ERC20(_name, _symbol) ERC20Permit(_name) { - decimals_ = _decimals; - } - - function decimals() public view virtual override returns (uint8) { - return decimals_; - } - - function mint(address _recipient, uint256 _amount) external returns (bool) { - _mint(_recipient, _amount); - return true; - } - - function burn(uint256 _amount) external returns (bool) { - _burn(msg.sender, _amount); - return true; - } - - function burn(address _from, uint256 _amount) public virtual returns (bool) { - _burn(_from, _amount); - return true; - } -} diff --git a/contracts/src/mocks/MockGasSwapTarget.sol b/contracts/src/mocks/MockGasSwapTarget.sol deleted file mode 100644 index 919315f54..000000000 --- a/contracts/src/mocks/MockGasSwapTarget.sol +++ /dev/null @@ -1,36 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; - -// solhint-disable no-empty-blocks - -contract MockGasSwapTarget { - address public token; - - uint256 public amountIn; - - uint256 public refund; - - receive() external payable {} - - function setToken(address _token) external { - token = _token; - } - - function setAmountIn(uint256 _amountIn) external { - amountIn = _amountIn; - } - - function setRefund(uint256 _refund) external { - refund = _refund; - } - - function swap() external { - IERC20(token).transferFrom(msg.sender, address(this), amountIn); - (bool success, ) = msg.sender.call{value: address(this).balance}(""); - require(success, "transfer ETH failed"); - IERC20(token).transfer(msg.sender, refund); - } -} diff --git a/contracts/src/mocks/MockPatriciaMerkleTrieVerifier.sol b/contracts/src/mocks/MockPatriciaMerkleTrieVerifier.sol deleted file mode 100644 index 98d541c6a..000000000 --- a/contracts/src/mocks/MockPatriciaMerkleTrieVerifier.sol +++ /dev/null @@ -1,25 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {PatriciaMerkleTrieVerifier} from "../libraries/verifier/PatriciaMerkleTrieVerifier.sol"; - -contract MockPatriciaMerkleTrieVerifier { - function verifyPatriciaProof( - address account, - bytes32 storageKey, - bytes calldata proof - ) - external - view - returns ( - bytes32 stateRoot, - bytes32 storageValue, - uint256 gasUsed - ) - { - uint256 start = gasleft(); - (stateRoot, storageValue) = PatriciaMerkleTrieVerifier.verifyPatriciaProof(account, storageKey, proof); - gasUsed = start - gasleft(); - } -} diff --git a/contracts/src/mocks/MockZkTrieVerifier.sol b/contracts/src/mocks/MockZkTrieVerifier.sol deleted file mode 100644 index fe863678d..000000000 --- a/contracts/src/mocks/MockZkTrieVerifier.sol +++ /dev/null @@ -1,31 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {ZkTrieVerifier} from "../libraries/verifier/ZkTrieVerifier.sol"; - -contract MockZkTrieVerifier { - address public immutable poseidon; - - constructor(address _poseidon) { - poseidon = _poseidon; - } - - function verifyZkTrieProof( - address account, - bytes32 storageKey, - bytes calldata proof - ) - external - view - returns ( - bytes32 stateRoot, - bytes32 storageValue, - uint256 gasUsed - ) - { - uint256 start = gasleft(); - (stateRoot, storageValue) = ZkTrieVerifier.verifyZkTrieProof(poseidon, account, storageKey, proof); - gasUsed = start - gasleft(); - } -} diff --git a/contracts/src/mocks/README.md b/contracts/src/mocks/README.md deleted file mode 100644 index 0f90fcb1c..000000000 --- a/contracts/src/mocks/README.md +++ /dev/null @@ -1,3 +0,0 @@ -## Mocks - -These are mock contracts for hardhat tests. \ No newline at end of file diff --git a/contracts/src/package.json b/contracts/src/package.json deleted file mode 100644 index 51566006f..000000000 --- a/contracts/src/package.json +++ /dev/null @@ -1,54 +0,0 @@ -{ - "name": "@scroll-tech/contracts", - "description": "A library for interacting with Scroll contracts.", - "version": "0.0.4", - "repository": { - "type": "git", - "url": "https://github.com/scroll-tech/scroll.git" - }, - "files": [ - "L1/gateways", - "L1/rollup/IL1MessageQueue.sol", - "L1/rollup/IL2GasPriceOracle.sol", - "L1/rollup/IScrollChain.sol", - "L1/IL1ScrollMessenger.sol", - "L2/gateways", - "L2/predeploys/IL1BlockContainer.sol", - "L2/predeploys/IL1GasPriceOracle.sol", - "L2/IL2ScrollMessenger.sol", - "interfaces", - "libraries/callbacks", - "libraries/gateway", - "libraries/oracle/IGasOracle.sol", - "libraries/token/IScrollERC20.sol", - "libraries/token/IScrollERC20Extension.sol", - "libraries/token/IScrollERC1155.sol", - "libraries/token/IScrollERC1155Extension.sol", - "libraries/token/IScrollERC721.sol", - "libraries/token/IScrollERC721Extension.sol", - "libraries/token/IScrollStandardERC20.sol", - "libraries/token/IScrollStandardERC20Factory.sol", - "libraries/IScrollMessenger.sol" - ], - "keywords": [ - "solidity", - "ethereum", - "smart", - "contracts", - "layer2", - "l2", - "scroll", - "zkevm", - "zkp", - "bridge", - "erc20", - "erc712", - "erc1155" - ], - "author": "Scroll", - "license": "MIT", - "bugs": { - "url": "https://github.com/scroll-tech/scroll-contracts/issues" - }, - "homepage": "https://scroll.io/" - } diff --git a/contracts/src/rate-limiter/ETHRateLimiter.sol b/contracts/src/rate-limiter/ETHRateLimiter.sol deleted file mode 100644 index 31ba904c7..000000000 --- a/contracts/src/rate-limiter/ETHRateLimiter.sol +++ /dev/null @@ -1,122 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; -import {SafeCast} from "@openzeppelin/contracts/utils/math/SafeCast.sol"; - -import {IETHRateLimiter} from "./IETHRateLimiter.sol"; - -// solhint-disable func-name-mixedcase -// solhint-disable not-rely-on-time - -contract ETHRateLimiter is Ownable, IETHRateLimiter { - /*********** - * Structs * - ***********/ - - struct ETHAmount { - // The timestamp when the amount is updated. - uint48 lastUpdateTs; - // The ETH limit in wei. - uint104 limit; - // The amount of ETH in current period. - uint104 amount; - } - - /************* - * Constants * - *************/ - - /// @notice The period length in seconds. - /// @dev The time frame for the `k`-th period is `[periodDuration * k, periodDuration * (k + 1))`. - uint256 public immutable periodDuration; - - /// @notice The address of ETH spender. - address public immutable spender; - - /************* - * Variables * - *************/ - - /// @notice The ETH amount used in current period. - ETHAmount public currentPeriod; - - /*************** - * Constructor * - ***************/ - - constructor( - uint256 _periodDuration, - address _spender, - uint104 _totalLimit - ) { - if (_periodDuration == 0) { - revert PeriodIsZero(); - } - - periodDuration = _periodDuration; - spender = _spender; - - _updateTotalLimit(_totalLimit); - } - - /***************************** - * Public Mutating Functions * - *****************************/ - - /// @inheritdoc IETHRateLimiter - function addUsedAmount(uint256 _amount) external override { - if (_msgSender() != spender) { - revert CallerNotSpender(); - } - if (_amount == 0) return; - - uint256 _currentPeriodStart = (block.timestamp / periodDuration) * periodDuration; - - // check total limit - uint256 _currentTotalAmount; - ETHAmount memory _currentPeriod = currentPeriod; - - if (uint256(_currentPeriod.lastUpdateTs) < _currentPeriodStart) { - _currentTotalAmount = _amount; - } else { - _currentTotalAmount = _currentPeriod.amount + _amount; - } - if (_currentTotalAmount > _currentPeriod.limit) { - revert ExceedTotalLimit(); - } - - _currentPeriod.lastUpdateTs = uint48(block.timestamp); - _currentPeriod.amount = SafeCast.toUint104(_currentTotalAmount); - - currentPeriod = _currentPeriod; - } - - /************************ - * Restricted Functions * - ************************/ - - /// @notice Update the total ETH amount limit. - /// @param _newTotalLimit The new total limit. - function updateTotalLimit(uint104 _newTotalLimit) external onlyOwner { - _updateTotalLimit(_newTotalLimit); - } - - /********************** - * Internal Functions * - **********************/ - - /// @dev Internal function to update the total token amount limit. - /// @param _newTotalLimit The new total limit. - function _updateTotalLimit(uint104 _newTotalLimit) private { - if (_newTotalLimit == 0) { - revert TotalLimitIsZero(); - } - - uint256 _oldTotalLimit = currentPeriod.limit; - currentPeriod.limit = _newTotalLimit; - - emit UpdateTotalLimit(_oldTotalLimit, _newTotalLimit); - } -} diff --git a/contracts/src/rate-limiter/IETHRateLimiter.sol b/contracts/src/rate-limiter/IETHRateLimiter.sol deleted file mode 100644 index 43db682e5..000000000 --- a/contracts/src/rate-limiter/IETHRateLimiter.sol +++ /dev/null @@ -1,38 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.24; - -interface IETHRateLimiter { - /********** - * Events * - **********/ - - /// @notice Emitted when the total limit is updated. - /// @param oldTotalLimit The previous value of total limit before updating. - /// @param newTotalLimit The current value of total limit after updating. - event UpdateTotalLimit(uint256 oldTotalLimit, uint256 newTotalLimit); - - /********** - * Errors * - **********/ - - /// @dev Thrown when the `periodDuration` is initialized to zero. - error PeriodIsZero(); - - /// @dev Thrown when the `totalAmount` is initialized to zero. - error TotalLimitIsZero(); - - /// @dev Thrown when an amount breaches the total limit in the period. - error ExceedTotalLimit(); - - /// @dev Thrown when the call is not spender. - error CallerNotSpender(); - - /***************************** - * Public Mutating Functions * - *****************************/ - - /// @notice Request some ETH usage for `sender`. - /// @param _amount The amount of ETH to use. - function addUsedAmount(uint256 _amount) external; -} diff --git a/contracts/src/rate-limiter/ITokenRateLimiter.sol b/contracts/src/rate-limiter/ITokenRateLimiter.sol deleted file mode 100644 index 050680efc..000000000 --- a/contracts/src/rate-limiter/ITokenRateLimiter.sol +++ /dev/null @@ -1,38 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.24; - -interface ITokenRateLimiter { - /********** - * Events * - **********/ - - /// @notice Emitted when the total limit is updated. - /// @param oldTotalLimit The previous value of total limit before updating. - /// @param newTotalLimit The current value of total limit after updating. - event UpdateTotalLimit(address indexed token, uint256 oldTotalLimit, uint256 newTotalLimit); - - /********** - * Errors * - **********/ - - /// @dev Thrown when the `periodDuration` is initialized to zero. - error PeriodIsZero(); - - /// @dev Thrown when the `totalAmount` is initialized to zero. - /// @param token The address of the token. - error TotalLimitIsZero(address token); - - /// @dev Thrown when an amount breaches the total limit in the period. - /// @param token The address of the token. - error ExceedTotalLimit(address token); - - /***************************** - * Public Mutating Functions * - *****************************/ - - /// @notice Request some token usage for `sender`. - /// @param token The address of the token. - /// @param amount The amount of token to use. - function addUsedAmount(address token, uint256 amount) external; -} diff --git a/contracts/src/rate-limiter/TokenRateLimiter.sol b/contracts/src/rate-limiter/TokenRateLimiter.sol deleted file mode 100644 index dab08e8a2..000000000 --- a/contracts/src/rate-limiter/TokenRateLimiter.sol +++ /dev/null @@ -1,106 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {AccessControlEnumerable} from "@openzeppelin/contracts/access/AccessControlEnumerable.sol"; -import {SafeCast} from "@openzeppelin/contracts/utils/math/SafeCast.sol"; - -import {ITokenRateLimiter} from "./ITokenRateLimiter.sol"; - -// solhint-disable func-name-mixedcase -// solhint-disable not-rely-on-time - -contract TokenRateLimiter is AccessControlEnumerable, ITokenRateLimiter { - /*********** - * Structs * - ***********/ - - struct TokenAmount { - // The timestamp when the amount is updated. - uint48 lastUpdateTs; - // The token limit. - uint104 limit; - // The amount of token in current period. - uint104 amount; - } - - /************* - * Constants * - *************/ - - /// @notice The role for token spender. - bytes32 public constant TOKEN_SPENDER_ROLE = keccak256("TOKEN_SPENDER_ROLE"); - - /// @notice The period length in seconds. - /// @dev The time frame for the `k`-th period is `[periodDuration * k, periodDuration * (k + 1))`. - uint256 public immutable periodDuration; - - /************* - * Variables * - *************/ - - /// @notice Mapping from token address to the total amounts used in current period and total token amount limit. - mapping(address => TokenAmount) public currentPeriod; - - /// @dev The storage slots for future usage. - uint256[49] private __gap; - - /*************** - * Constructor * - ***************/ - - constructor(uint256 _periodDuration) { - if (_periodDuration == 0) { - revert PeriodIsZero(); - } - - _grantRole(DEFAULT_ADMIN_ROLE, _msgSender()); - - periodDuration = _periodDuration; - } - - /***************************** - * Public Mutating Functions * - *****************************/ - - /// @inheritdoc ITokenRateLimiter - function addUsedAmount(address _token, uint256 _amount) external override onlyRole(TOKEN_SPENDER_ROLE) { - if (_amount == 0) return; - - uint256 _currentPeriodStart = (block.timestamp / periodDuration) * periodDuration; - - // check total limit, `0` means no limit at all. - uint256 _currentTotalAmount; - TokenAmount memory _currentPeriod = currentPeriod[_token]; - if (uint256(_currentPeriod.lastUpdateTs) < _currentPeriodStart) { - _currentTotalAmount = _amount; - } else { - _currentTotalAmount = _currentPeriod.amount + _amount; - } - if (_currentPeriod.limit != 0 && _currentTotalAmount > _currentPeriod.limit) { - revert ExceedTotalLimit(_token); - } - - _currentPeriod.lastUpdateTs = uint48(block.timestamp); - _currentPeriod.amount = SafeCast.toUint104(_currentTotalAmount); - - currentPeriod[_token] = _currentPeriod; - } - - /************************ - * Restricted Functions * - ************************/ - - /// @notice Update the total token amount limit. - /// @param _newTotalLimit The new total limit. - function updateTotalLimit(address _token, uint104 _newTotalLimit) external onlyRole(DEFAULT_ADMIN_ROLE) { - if (_newTotalLimit == 0) { - revert TotalLimitIsZero(_token); - } - - uint256 _oldTotalLimit = currentPeriod[_token].limit; - currentPeriod[_token].limit = _newTotalLimit; - - emit UpdateTotalLimit(_token, _oldTotalLimit, _newTotalLimit); - } -} diff --git a/contracts/src/test/ETHRateLimiter.t.sol b/contracts/src/test/ETHRateLimiter.t.sol deleted file mode 100644 index 31c537253..000000000 --- a/contracts/src/test/ETHRateLimiter.t.sol +++ /dev/null @@ -1,75 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {DSTestPlus} from "solmate/test/utils/DSTestPlus.sol"; - -import {ETHRateLimiter} from "../rate-limiter/ETHRateLimiter.sol"; -import {IETHRateLimiter} from "../rate-limiter/IETHRateLimiter.sol"; - -contract ETHRateLimiterTest is DSTestPlus { - event UpdateTotalLimit(uint256 oldTotalLimit, uint256 newTotalLimit); - - ETHRateLimiter private limiter; - - function setUp() public { - hevm.warp(86400); - limiter = new ETHRateLimiter(86400, address(this), 100 ether); - } - - function testUpdateTotalLimit(uint104 _newTotalLimit) external { - hevm.assume(_newTotalLimit > 0); - - // not owner, revert - hevm.startPrank(address(1)); - hevm.expectRevert("Ownable: caller is not the owner"); - limiter.updateTotalLimit(_newTotalLimit); - hevm.stopPrank(); - - // zero revert - hevm.expectRevert(IETHRateLimiter.TotalLimitIsZero.selector); - limiter.updateTotalLimit(0); - - // success - hevm.expectEmit(false, false, false, true); - emit UpdateTotalLimit(100 ether, _newTotalLimit); - limiter.updateTotalLimit(_newTotalLimit); - (, uint104 _totalLimit, ) = limiter.currentPeriod(); - assertEq(_totalLimit, _newTotalLimit); - } - - function testAddUsedAmount() external { - // non-spender, revert - hevm.startPrank(address(1)); - hevm.expectRevert(IETHRateLimiter.CallerNotSpender.selector); - limiter.addUsedAmount(0); - hevm.stopPrank(); - - // exceed total limit on first call - hevm.expectRevert(IETHRateLimiter.ExceedTotalLimit.selector); - limiter.addUsedAmount(100 ether + 1); - _checkTotalCurrentPeriodAmountAmount(0); - - // exceed total limit on second call - limiter.addUsedAmount(50 ether); - _checkTotalCurrentPeriodAmountAmount(50 ether); - hevm.expectRevert(IETHRateLimiter.ExceedTotalLimit.selector); - limiter.addUsedAmount(50 ether + 1); - _checkTotalCurrentPeriodAmountAmount(50 ether); - - // one period passed - hevm.warp(86400 * 2); - limiter.addUsedAmount(1 ether); - _checkTotalCurrentPeriodAmountAmount(1 ether); - - // exceed - hevm.expectRevert(IETHRateLimiter.ExceedTotalLimit.selector); - limiter.addUsedAmount(99 ether + 1); - _checkTotalCurrentPeriodAmountAmount(1 ether); - } - - function _checkTotalCurrentPeriodAmountAmount(uint256 expected) internal { - (, , uint256 totalAmount) = limiter.currentPeriod(); - assertEq(totalAmount, expected); - } -} diff --git a/contracts/src/test/L1CustomERC20Gateway.t.sol b/contracts/src/test/L1CustomERC20Gateway.t.sol deleted file mode 100644 index a1b667d26..000000000 --- a/contracts/src/test/L1CustomERC20Gateway.t.sol +++ /dev/null @@ -1,671 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {MockERC20} from "solmate/test/utils/mocks/MockERC20.sol"; - -import {ITransparentUpgradeableProxy} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; - -import {IL1ERC20Gateway, L1CustomERC20Gateway} from "../L1/gateways/L1CustomERC20Gateway.sol"; -import {L1GatewayRouter} from "../L1/gateways/L1GatewayRouter.sol"; -import {IL1ScrollMessenger} from "../L1/IL1ScrollMessenger.sol"; -import {L1ScrollMessenger} from "../L1/L1ScrollMessenger.sol"; -import {IL2ERC20Gateway, L2CustomERC20Gateway} from "../L2/gateways/L2CustomERC20Gateway.sol"; -import {AddressAliasHelper} from "../libraries/common/AddressAliasHelper.sol"; -import {ScrollConstants} from "../libraries/constants/ScrollConstants.sol"; - -import {L1GatewayTestBase} from "./L1GatewayTestBase.t.sol"; -import {MockScrollMessenger} from "./mocks/MockScrollMessenger.sol"; -import {MockGatewayRecipient} from "./mocks/MockGatewayRecipient.sol"; - -contract L1CustomERC20GatewayTest is L1GatewayTestBase { - // from L1CustomERC20Gateway - event FinalizeWithdrawERC20( - address indexed _l1Token, - address indexed _l2Token, - address indexed _from, - address _to, - uint256 _amount, - bytes _data - ); - event DepositERC20( - address indexed _l1Token, - address indexed _l2Token, - address indexed _from, - address _to, - uint256 _amount, - bytes _data - ); - event RefundERC20(address indexed token, address indexed recipient, uint256 amount); - - L1CustomERC20Gateway private gateway; - L1GatewayRouter private router; - - L2CustomERC20Gateway private counterpartGateway; - - MockERC20 private l1Token; - MockERC20 private l2Token; - - function setUp() public { - __L1GatewayTestBase_setUp(); - - // Deploy tokens - l1Token = new MockERC20("Mock L1", "ML1", 18); - l2Token = new MockERC20("Mock L2", "ML2", 18); - - // Deploy L2 contracts - counterpartGateway = new L2CustomERC20Gateway(address(1), address(1), address(1)); - - // Deploy L1 contracts - router = L1GatewayRouter(_deployProxy(address(new L1GatewayRouter()))); - gateway = _deployGateway(address(l1Messenger)); - - // Initialize L1 contracts - gateway.initialize(address(counterpartGateway), address(router), address(l1Messenger)); - router.initialize(address(0), address(gateway)); - - // Prepare token balances - l1Token.mint(address(this), type(uint128).max); - l1Token.approve(address(gateway), type(uint256).max); - l1Token.approve(address(router), type(uint256).max); - } - - function testInitialized() public { - assertEq(address(this), gateway.owner()); - assertEq(address(counterpartGateway), gateway.counterpart()); - assertEq(address(router), gateway.router()); - assertEq(address(l1Messenger), gateway.messenger()); - - assertEq(address(0), gateway.getL2ERC20Address(address(l1Token))); - - hevm.expectRevert("Initializable: contract is already initialized"); - gateway.initialize(address(counterpartGateway), address(router), address(l1Messenger)); - } - - function testUpdateTokenMappingFailed(address token1) public { - // call by non-owner, should revert - hevm.startPrank(address(1)); - hevm.expectRevert("Ownable: caller is not the owner"); - gateway.updateTokenMapping(token1, token1); - hevm.stopPrank(); - - // l2 token is zero, should revert - hevm.expectRevert("token address cannot be 0"); - gateway.updateTokenMapping(token1, address(0)); - } - - function testUpdateTokenMappingSuccess(address token1, address token2) public { - hevm.assume(token2 != address(0)); - hevm.assume(token1 != address(l1Token)); - - assertEq(gateway.getL2ERC20Address(token1), address(0)); - gateway.updateTokenMapping(token1, token2); - assertEq(gateway.getL2ERC20Address(token1), token2); - } - - function testDepositERC20( - uint256 amount, - uint256 gasLimit, - uint256 feePerGas - ) public { - _depositERC20(false, amount, gasLimit, feePerGas); - } - - function testDepositERC20WithRecipient( - uint256 amount, - address recipient, - uint256 gasLimit, - uint256 feePerGas - ) public { - _depositERC20WithRecipient(false, amount, recipient, gasLimit, feePerGas); - } - - function testDepositERC20WithRecipientAndCalldata( - uint256 amount, - address recipient, - bytes memory dataToCall, - uint256 gasLimit, - uint256 feePerGas - ) public { - _depositERC20WithRecipientAndCalldata(false, amount, recipient, dataToCall, gasLimit, feePerGas); - } - - function testDropMessageMocking() public { - MockScrollMessenger mockMessenger = new MockScrollMessenger(); - gateway = _deployGateway(address(mockMessenger)); - gateway.initialize(address(counterpartGateway), address(router), address(mockMessenger)); - - // only messenger can call, revert - hevm.expectRevert(ErrorCallerIsNotMessenger.selector); - gateway.onDropMessage(new bytes(0)); - - // only called in drop context, revert - hevm.expectRevert(ErrorNotInDropMessageContext.selector); - mockMessenger.callTarget( - address(gateway), - abi.encodeWithSelector(gateway.onDropMessage.selector, new bytes(0)) - ); - - mockMessenger.setXDomainMessageSender(ScrollConstants.DROP_XDOMAIN_MESSAGE_SENDER); - - // invalid selector, revert - hevm.expectRevert("invalid selector"); - mockMessenger.callTarget( - address(gateway), - abi.encodeWithSelector(gateway.onDropMessage.selector, new bytes(4)) - ); - - bytes memory message = abi.encodeWithSelector( - IL2ERC20Gateway.finalizeDepositERC20.selector, - address(l1Token), - address(l2Token), - address(this), - address(this), - 100, - new bytes(0) - ); - - // nonzero msg.value, revert - hevm.expectRevert("nonzero msg.value"); - mockMessenger.callTarget{value: 1}( - address(gateway), - abi.encodeWithSelector(gateway.onDropMessage.selector, message) - ); - } - - function testDropMessage( - uint256 amount, - address recipient, - bytes memory dataToCall - ) public { - gateway.updateTokenMapping(address(l1Token), address(l2Token)); - - amount = bound(amount, 1, l1Token.balanceOf(address(this))); - bytes memory message = abi.encodeWithSelector( - IL2ERC20Gateway.finalizeDepositERC20.selector, - address(l1Token), - address(l2Token), - address(this), - recipient, - amount, - dataToCall - ); - gateway.depositERC20AndCall(address(l1Token), recipient, amount, dataToCall, defaultGasLimit); - - // skip message 0 - hevm.startPrank(address(rollup)); - messageQueue.popCrossDomainMessage(0, 1, 0x1); - assertEq(messageQueue.pendingQueueIndex(), 1); - hevm.stopPrank(); - - // drop message 0 - hevm.expectEmit(true, true, false, true); - emit RefundERC20(address(l1Token), address(this), amount); - - uint256 balance = l1Token.balanceOf(address(this)); - l1Messenger.dropMessage(address(gateway), address(counterpartGateway), 0, 0, message); - assertEq(balance + amount, l1Token.balanceOf(address(this))); - } - - function testFinalizeWithdrawERC20FailedMocking( - address sender, - address recipient, - uint256 amount, - bytes memory dataToCall - ) public { - amount = bound(amount, 1, 100000); - - // revert when caller is not messenger - hevm.expectRevert(ErrorCallerIsNotMessenger.selector); - gateway.finalizeWithdrawERC20(address(l1Token), address(l2Token), sender, recipient, amount, dataToCall); - - MockScrollMessenger mockMessenger = new MockScrollMessenger(); - gateway = _deployGateway(address(mockMessenger)); - gateway.initialize(address(counterpartGateway), address(router), address(mockMessenger)); - - // only call by counterpart - hevm.expectRevert(ErrorCallerIsNotCounterpartGateway.selector); - mockMessenger.callTarget( - address(gateway), - abi.encodeWithSelector( - gateway.finalizeWithdrawERC20.selector, - address(l1Token), - address(l2Token), - sender, - recipient, - amount, - dataToCall - ) - ); - - mockMessenger.setXDomainMessageSender(address(counterpartGateway)); - - // msg.value mismatch - hevm.expectRevert("nonzero msg.value"); - mockMessenger.callTarget{value: 1}( - address(gateway), - abi.encodeWithSelector( - gateway.finalizeWithdrawERC20.selector, - address(l1Token), - address(l2Token), - sender, - recipient, - amount, - dataToCall - ) - ); - - // msg.value mismatch - hevm.expectRevert("l2 token mismatch"); - mockMessenger.callTarget( - address(gateway), - abi.encodeWithSelector( - gateway.finalizeWithdrawERC20.selector, - address(l1Token), - address(l2Token), - sender, - recipient, - amount, - dataToCall - ) - ); - } - - function testFinalizeWithdrawERC20Failed( - address sender, - address recipient, - uint256 amount, - bytes memory dataToCall - ) public { - // blacklist some addresses - hevm.assume(recipient != address(0)); - hevm.assume(recipient != address(gateway)); - - gateway.updateTokenMapping(address(l1Token), address(l2Token)); - - amount = bound(amount, 1, l1Token.balanceOf(address(this))); - - // deposit some token to L1StandardERC20Gateway - gateway.depositERC20(address(l1Token), amount, defaultGasLimit); - - // do finalize withdraw token - bytes memory message = abi.encodeWithSelector( - IL1ERC20Gateway.finalizeWithdrawERC20.selector, - address(l1Token), - address(l2Token), - sender, - recipient, - amount, - dataToCall - ); - bytes memory xDomainCalldata = abi.encodeWithSignature( - "relayMessage(address,address,uint256,uint256,bytes)", - address(uint160(address(counterpartGateway)) + 1), - address(gateway), - 0, - 0, - message - ); - - prepareL2MessageRoot(keccak256(xDomainCalldata)); - - IL1ScrollMessenger.L2MessageProof memory proof; - proof.batchIndex = rollup.lastFinalizedBatchIndex(); - - // counterpart is not L2WETHGateway - // emit FailedRelayedMessage from L1ScrollMessenger - hevm.expectEmit(true, false, false, true); - emit FailedRelayedMessage(keccak256(xDomainCalldata)); - - uint256 gatewayBalance = l1Token.balanceOf(address(gateway)); - uint256 recipientBalance = l1Token.balanceOf(recipient); - assertBoolEq(false, l1Messenger.isL2MessageExecuted(keccak256(xDomainCalldata))); - l1Messenger.relayMessageWithProof( - address(uint160(address(counterpartGateway)) + 1), - address(gateway), - 0, - 0, - message, - proof - ); - assertEq(gatewayBalance, l1Token.balanceOf(address(gateway))); - assertEq(recipientBalance, l1Token.balanceOf(recipient)); - assertBoolEq(false, l1Messenger.isL2MessageExecuted(keccak256(xDomainCalldata))); - } - - function testFinalizeWithdrawERC20( - address sender, - uint256 amount, - bytes memory dataToCall - ) public { - MockGatewayRecipient recipient = new MockGatewayRecipient(); - - gateway.updateTokenMapping(address(l1Token), address(l2Token)); - - amount = bound(amount, 1, l1Token.balanceOf(address(this))); - - // deposit some token to L1StandardERC20Gateway - gateway.depositERC20(address(l1Token), amount, defaultGasLimit); - - // do finalize withdraw token - bytes memory message = abi.encodeWithSelector( - IL1ERC20Gateway.finalizeWithdrawERC20.selector, - address(l1Token), - address(l2Token), - sender, - address(recipient), - amount, - dataToCall - ); - bytes memory xDomainCalldata = abi.encodeWithSignature( - "relayMessage(address,address,uint256,uint256,bytes)", - address(counterpartGateway), - address(gateway), - 0, - 0, - message - ); - - prepareL2MessageRoot(keccak256(xDomainCalldata)); - - IL1ScrollMessenger.L2MessageProof memory proof; - proof.batchIndex = rollup.lastFinalizedBatchIndex(); - - // emit FinalizeWithdrawERC20 from L1StandardERC20Gateway - { - hevm.expectEmit(true, true, true, true); - emit FinalizeWithdrawERC20( - address(l1Token), - address(l2Token), - sender, - address(recipient), - amount, - dataToCall - ); - } - - // emit RelayedMessage from L1ScrollMessenger - { - hevm.expectEmit(true, false, false, true); - emit RelayedMessage(keccak256(xDomainCalldata)); - } - - uint256 gatewayBalance = l1Token.balanceOf(address(gateway)); - uint256 recipientBalance = l1Token.balanceOf(address(recipient)); - assertBoolEq(false, l1Messenger.isL2MessageExecuted(keccak256(xDomainCalldata))); - l1Messenger.relayMessageWithProof(address(counterpartGateway), address(gateway), 0, 0, message, proof); - assertEq(gatewayBalance - amount, l1Token.balanceOf(address(gateway))); - assertEq(recipientBalance + amount, l1Token.balanceOf(address(recipient))); - assertBoolEq(true, l1Messenger.isL2MessageExecuted(keccak256(xDomainCalldata))); - } - - function _depositERC20( - bool useRouter, - uint256 amount, - uint256 gasLimit, - uint256 feePerGas - ) private { - amount = bound(amount, 0, l1Token.balanceOf(address(this))); - gasLimit = bound(gasLimit, defaultGasLimit / 2, defaultGasLimit); - feePerGas = bound(feePerGas, 0, 1000); - - messageQueue.setL2BaseFee(feePerGas); - - uint256 feeToPay = feePerGas * gasLimit; - bytes memory message = abi.encodeWithSelector( - IL2ERC20Gateway.finalizeDepositERC20.selector, - address(l1Token), - address(l2Token), - address(this), - address(this), - amount, - new bytes(0) - ); - bytes memory xDomainCalldata = abi.encodeWithSignature( - "relayMessage(address,address,uint256,uint256,bytes)", - address(gateway), - address(counterpartGateway), - 0, - 0, - message - ); - - hevm.expectRevert("no corresponding l2 token"); - if (useRouter) { - router.depositERC20{value: feeToPay + extraValue}(address(l1Token), amount, gasLimit); - } else { - gateway.depositERC20{value: feeToPay + extraValue}(address(l1Token), amount, gasLimit); - } - - gateway.updateTokenMapping(address(l1Token), address(l2Token)); - if (amount == 0) { - hevm.expectRevert("deposit zero amount"); - if (useRouter) { - router.depositERC20{value: feeToPay + extraValue}(address(l1Token), amount, gasLimit); - } else { - gateway.depositERC20{value: feeToPay + extraValue}(address(l1Token), amount, gasLimit); - } - } else { - // emit QueueTransaction from L1MessageQueue - { - hevm.expectEmit(true, true, false, true); - address sender = AddressAliasHelper.applyL1ToL2Alias(address(l1Messenger)); - emit QueueTransaction(sender, address(l2Messenger), 0, 0, gasLimit, xDomainCalldata); - } - - // emit SentMessage from L1ScrollMessenger - { - hevm.expectEmit(true, true, false, true); - emit SentMessage(address(gateway), address(counterpartGateway), 0, 0, gasLimit, message); - } - - // emit DepositERC20 from L1CustomERC20Gateway - hevm.expectEmit(true, true, true, true); - emit DepositERC20(address(l1Token), address(l2Token), address(this), address(this), amount, new bytes(0)); - - uint256 gatewayBalance = l1Token.balanceOf(address(gateway)); - uint256 feeVaultBalance = address(feeVault).balance; - assertEq(l1Messenger.messageSendTimestamp(keccak256(xDomainCalldata)), 0); - if (useRouter) { - router.depositERC20{value: feeToPay + extraValue}(address(l1Token), amount, gasLimit); - } else { - gateway.depositERC20{value: feeToPay + extraValue}(address(l1Token), amount, gasLimit); - } - assertEq(amount + gatewayBalance, l1Token.balanceOf(address(gateway))); - assertEq(feeToPay + feeVaultBalance, address(feeVault).balance); - assertGt(l1Messenger.messageSendTimestamp(keccak256(xDomainCalldata)), 0); - } - } - - function _depositERC20WithRecipient( - bool useRouter, - uint256 amount, - address recipient, - uint256 gasLimit, - uint256 feePerGas - ) private { - amount = bound(amount, 0, l1Token.balanceOf(address(this))); - gasLimit = bound(gasLimit, defaultGasLimit / 2, defaultGasLimit); - feePerGas = bound(feePerGas, 0, 1000); - - messageQueue.setL2BaseFee(feePerGas); - - uint256 feeToPay = feePerGas * gasLimit; - bytes memory message = abi.encodeWithSelector( - IL2ERC20Gateway.finalizeDepositERC20.selector, - address(l1Token), - address(l2Token), - address(this), - recipient, - amount, - new bytes(0) - ); - bytes memory xDomainCalldata = abi.encodeWithSignature( - "relayMessage(address,address,uint256,uint256,bytes)", - address(gateway), - address(counterpartGateway), - 0, - 0, - message - ); - - hevm.expectRevert("no corresponding l2 token"); - if (useRouter) { - router.depositERC20{value: feeToPay + extraValue}(address(l1Token), amount, gasLimit); - } else { - gateway.depositERC20{value: feeToPay + extraValue}(address(l1Token), amount, gasLimit); - } - - gateway.updateTokenMapping(address(l1Token), address(l2Token)); - if (amount == 0) { - hevm.expectRevert("deposit zero amount"); - if (useRouter) { - router.depositERC20{value: feeToPay + extraValue}(address(l1Token), recipient, amount, gasLimit); - } else { - gateway.depositERC20{value: feeToPay + extraValue}(address(l1Token), recipient, amount, gasLimit); - } - } else { - // emit QueueTransaction from L1MessageQueue - { - hevm.expectEmit(true, true, false, true); - address sender = AddressAliasHelper.applyL1ToL2Alias(address(l1Messenger)); - emit QueueTransaction(sender, address(l2Messenger), 0, 0, gasLimit, xDomainCalldata); - } - - // emit SentMessage from L1ScrollMessenger - { - hevm.expectEmit(true, true, false, true); - emit SentMessage(address(gateway), address(counterpartGateway), 0, 0, gasLimit, message); - } - - // emit DepositERC20 from L1CustomERC20Gateway - hevm.expectEmit(true, true, true, true); - emit DepositERC20(address(l1Token), address(l2Token), address(this), recipient, amount, new bytes(0)); - - uint256 gatewayBalance = l1Token.balanceOf(address(gateway)); - uint256 feeVaultBalance = address(feeVault).balance; - assertEq(l1Messenger.messageSendTimestamp(keccak256(xDomainCalldata)), 0); - if (useRouter) { - router.depositERC20{value: feeToPay + extraValue}(address(l1Token), recipient, amount, gasLimit); - } else { - gateway.depositERC20{value: feeToPay + extraValue}(address(l1Token), recipient, amount, gasLimit); - } - assertEq(amount + gatewayBalance, l1Token.balanceOf(address(gateway))); - assertEq(feeToPay + feeVaultBalance, address(feeVault).balance); - assertGt(l1Messenger.messageSendTimestamp(keccak256(xDomainCalldata)), 0); - } - } - - function _depositERC20WithRecipientAndCalldata( - bool useRouter, - uint256 amount, - address recipient, - bytes memory dataToCall, - uint256 gasLimit, - uint256 feePerGas - ) private { - amount = bound(amount, 0, l1Token.balanceOf(address(this))); - gasLimit = bound(gasLimit, defaultGasLimit / 2, defaultGasLimit); - feePerGas = bound(feePerGas, 0, 1000); - - messageQueue.setL2BaseFee(feePerGas); - - uint256 feeToPay = feePerGas * gasLimit; - bytes memory message = abi.encodeWithSelector( - IL2ERC20Gateway.finalizeDepositERC20.selector, - address(l1Token), - address(l2Token), - address(this), - recipient, - amount, - dataToCall - ); - bytes memory xDomainCalldata = abi.encodeWithSignature( - "relayMessage(address,address,uint256,uint256,bytes)", - address(gateway), - address(counterpartGateway), - 0, - 0, - message - ); - - hevm.expectRevert("no corresponding l2 token"); - if (useRouter) { - router.depositERC20{value: feeToPay + extraValue}(address(l1Token), amount, gasLimit); - } else { - gateway.depositERC20{value: feeToPay + extraValue}(address(l1Token), amount, gasLimit); - } - - gateway.updateTokenMapping(address(l1Token), address(l2Token)); - if (amount == 0) { - hevm.expectRevert("deposit zero amount"); - if (useRouter) { - router.depositERC20AndCall{value: feeToPay + extraValue}( - address(l1Token), - recipient, - amount, - dataToCall, - gasLimit - ); - } else { - gateway.depositERC20AndCall{value: feeToPay + extraValue}( - address(l1Token), - recipient, - amount, - dataToCall, - gasLimit - ); - } - } else { - // emit QueueTransaction from L1MessageQueue - { - hevm.expectEmit(true, true, false, true); - address sender = AddressAliasHelper.applyL1ToL2Alias(address(l1Messenger)); - emit QueueTransaction(sender, address(l2Messenger), 0, 0, gasLimit, xDomainCalldata); - } - - // emit SentMessage from L1ScrollMessenger - { - hevm.expectEmit(true, true, false, true); - emit SentMessage(address(gateway), address(counterpartGateway), 0, 0, gasLimit, message); - } - - // emit DepositERC20 from L1CustomERC20Gateway - hevm.expectEmit(true, true, true, true); - emit DepositERC20(address(l1Token), address(l2Token), address(this), recipient, amount, dataToCall); - - uint256 gatewayBalance = l1Token.balanceOf(address(gateway)); - uint256 feeVaultBalance = address(feeVault).balance; - assertEq(l1Messenger.messageSendTimestamp(keccak256(xDomainCalldata)), 0); - if (useRouter) { - router.depositERC20AndCall{value: feeToPay + extraValue}( - address(l1Token), - recipient, - amount, - dataToCall, - gasLimit - ); - } else { - gateway.depositERC20AndCall{value: feeToPay + extraValue}( - address(l1Token), - recipient, - amount, - dataToCall, - gasLimit - ); - } - assertEq(amount + gatewayBalance, l1Token.balanceOf(address(gateway))); - assertEq(feeToPay + feeVaultBalance, address(feeVault).balance); - assertGt(l1Messenger.messageSendTimestamp(keccak256(xDomainCalldata)), 0); - } - } - - function _deployGateway(address messenger) internal returns (L1CustomERC20Gateway _gateway) { - _gateway = L1CustomERC20Gateway(_deployProxy(address(0))); - - admin.upgrade( - ITransparentUpgradeableProxy(address(_gateway)), - address(new L1CustomERC20Gateway(address(counterpartGateway), address(router), messenger)) - ); - } -} diff --git a/contracts/src/test/L1ERC1155Gateway.t.sol b/contracts/src/test/L1ERC1155Gateway.t.sol deleted file mode 100644 index c9c7836c1..000000000 --- a/contracts/src/test/L1ERC1155Gateway.t.sol +++ /dev/null @@ -1,1064 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {DSTestPlus} from "solmate/test/utils/DSTestPlus.sol"; -import {MockERC1155} from "solmate/test/utils/mocks/MockERC1155.sol"; -import {ERC1155TokenReceiver} from "solmate/tokens/ERC1155.sol"; - -import {ITransparentUpgradeableProxy} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; - -import {IL1ERC1155Gateway, L1ERC1155Gateway} from "../L1/gateways/L1ERC1155Gateway.sol"; -import {IL1ScrollMessenger} from "../L1/IL1ScrollMessenger.sol"; -import {IL2ERC1155Gateway, L2ERC1155Gateway} from "../L2/gateways/L2ERC1155Gateway.sol"; -import {AddressAliasHelper} from "../libraries/common/AddressAliasHelper.sol"; -import {ScrollConstants} from "../libraries/constants/ScrollConstants.sol"; - -import {L1GatewayTestBase} from "./L1GatewayTestBase.t.sol"; -import {MockScrollMessenger} from "./mocks/MockScrollMessenger.sol"; -import {MockERC1155Recipient} from "./mocks/MockERC1155Recipient.sol"; - -contract L1ERC1155GatewayTest is L1GatewayTestBase, ERC1155TokenReceiver { - // from L1ERC1155Gateway - event FinalizeWithdrawERC1155( - address indexed _l1Token, - address indexed _l2Token, - address indexed _from, - address _to, - uint256 _tokenId, - uint256 _amount - ); - event FinalizeBatchWithdrawERC1155( - address indexed _l1Token, - address indexed _l2Token, - address indexed _from, - address _to, - uint256[] _tokenIds, - uint256[] _amounts - ); - event DepositERC1155( - address indexed _l1Token, - address indexed _l2Token, - address indexed _from, - address _to, - uint256 _tokenId, - uint256 _amount - ); - event BatchDepositERC1155( - address indexed _l1Token, - address indexed _l2Token, - address indexed _from, - address _to, - uint256[] _tokenIds, - uint256[] _amounts - ); - event RefundERC1155(address indexed token, address indexed recipient, uint256 tokenId, uint256 amount); - event BatchRefundERC1155(address indexed token, address indexed recipient, uint256[] tokenIds, uint256[] amounts); - - uint256 private constant TOKEN_COUNT = 100; - uint256 private constant MAX_TOKEN_BALANCE = 1000000000; - - L1ERC1155Gateway private gateway; - - L2ERC1155Gateway private counterpartGateway; - - MockERC1155 private l1Token; - MockERC1155 private l2Token; - MockERC1155Recipient private mockRecipient; - - function setUp() public { - __L1GatewayTestBase_setUp(); - - // Deploy tokens - l1Token = new MockERC1155(); - l2Token = new MockERC1155(); - - // Deploy L2 contracts - counterpartGateway = new L2ERC1155Gateway(address(1), address(1)); - - // Deploy L1 contracts - gateway = _deployGateway(address(l1Messenger)); - - // Initialize L1 contracts - gateway.initialize(address(counterpartGateway), address(l1Messenger)); - - // Prepare token balances - for (uint256 i = 0; i < TOKEN_COUNT; i++) { - l1Token.mint(address(this), i, MAX_TOKEN_BALANCE, ""); - } - l1Token.setApprovalForAll(address(gateway), true); - - mockRecipient = new MockERC1155Recipient(); - } - - function testInitialized() public { - assertEq(address(counterpartGateway), gateway.counterpart()); - assertEq(address(0), gateway.router()); - assertEq(address(l1Messenger), gateway.messenger()); - - assertEq(address(0), gateway.tokenMapping(address(l1Token))); - - hevm.expectRevert("Initializable: contract is already initialized"); - gateway.initialize(address(1), address(l1Messenger)); - } - - function testUpdateTokenMappingFailed(address token1) public { - // call by non-owner, should revert - hevm.startPrank(address(1)); - hevm.expectRevert("Ownable: caller is not the owner"); - gateway.updateTokenMapping(token1, token1); - hevm.stopPrank(); - - // l2 token is zero, should revert - hevm.expectRevert("token address cannot be 0"); - gateway.updateTokenMapping(token1, address(0)); - } - - function testUpdateTokenMappingSuccess(address token1, address token2) public { - hevm.assume(token2 != address(0)); - - assertEq(gateway.tokenMapping(token1), address(0)); - gateway.updateTokenMapping(token1, token2); - assertEq(gateway.tokenMapping(token1), token2); - } - - function testDepositERC1155( - uint256 tokenId, - uint256 amount, - uint256 gasLimit, - uint256 feePerGas - ) public { - _testDepositERC1155(tokenId, amount, gasLimit, feePerGas); - } - - function testDepositERC1155WithRecipient( - uint256 tokenId, - uint256 amount, - address recipient, - uint256 gasLimit, - uint256 feePerGas - ) public { - _testDepositERC1155WithRecipient(tokenId, amount, recipient, gasLimit, feePerGas); - } - - function testBatchDepositERC1155( - uint256 tokenCount, - uint256 amount, - uint256 gasLimit, - uint256 feePerGas - ) public { - _testBatchDepositERC1155(tokenCount, amount, gasLimit, feePerGas); - } - - function testBatchDepositERC1155WithRecipient( - uint256 tokenCount, - uint256 amount, - address recipient, - uint256 gasLimit, - uint256 feePerGas - ) public { - _testBatchDepositERC1155WithRecipient(tokenCount, amount, recipient, gasLimit, feePerGas); - } - - function testDropMessageMocking() public { - MockScrollMessenger mockMessenger = new MockScrollMessenger(); - gateway = _deployGateway(address(mockMessenger)); - gateway.initialize(address(counterpartGateway), address(mockMessenger)); - - // only messenger can call, revert - hevm.expectRevert(ErrorCallerIsNotMessenger.selector); - gateway.onDropMessage(new bytes(0)); - - // only called in drop context, revert - hevm.expectRevert(ErrorNotInDropMessageContext.selector); - mockMessenger.callTarget( - address(gateway), - abi.encodeWithSelector(gateway.onDropMessage.selector, new bytes(0)) - ); - - mockMessenger.setXDomainMessageSender(ScrollConstants.DROP_XDOMAIN_MESSAGE_SENDER); - - // invalid selector, revert - hevm.expectRevert("invalid selector"); - mockMessenger.callTarget( - address(gateway), - abi.encodeWithSelector(gateway.onDropMessage.selector, new bytes(4)) - ); - - bytes memory message = abi.encodeWithSelector( - IL2ERC1155Gateway.finalizeDepositERC1155.selector, - address(l1Token), - address(l2Token), - address(this), - address(this), - 0, - 0 - ); - - // nonzero msg.value, revert - hevm.expectRevert("nonzero msg.value"); - mockMessenger.callTarget{value: 1}( - address(gateway), - abi.encodeWithSelector(gateway.onDropMessage.selector, message) - ); - } - - function testDropMessage(uint256 tokenId, uint256 amount) public { - gateway.updateTokenMapping(address(l1Token), address(l2Token)); - - tokenId = bound(tokenId, 0, TOKEN_COUNT - 1); - amount = bound(amount, 1, MAX_TOKEN_BALANCE); - bytes memory message = abi.encodeWithSelector( - IL2ERC1155Gateway.finalizeDepositERC1155.selector, - address(l1Token), - address(l2Token), - address(this), - address(this), - tokenId, - amount - ); - gateway.depositERC1155(address(l1Token), tokenId, amount, defaultGasLimit); - - // skip message 0 - hevm.startPrank(address(rollup)); - messageQueue.popCrossDomainMessage(0, 1, 0x1); - assertEq(messageQueue.pendingQueueIndex(), 1); - hevm.stopPrank(); - - // drop message 0 - hevm.expectEmit(true, true, false, true); - emit RefundERC1155(address(l1Token), address(this), tokenId, amount); - - uint256 balance = l1Token.balanceOf(address(this), tokenId); - l1Messenger.dropMessage(address(gateway), address(counterpartGateway), 0, 0, message); - assertEq(balance + amount, l1Token.balanceOf(address(this), tokenId)); - } - - function testDropMessageBatch(uint256 tokenCount, uint256 amount) public { - tokenCount = bound(tokenCount, 1, TOKEN_COUNT); - amount = bound(amount, 1, MAX_TOKEN_BALANCE); - gateway.updateTokenMapping(address(l1Token), address(l2Token)); - - uint256[] memory _tokenIds = new uint256[](tokenCount); - uint256[] memory _amounts = new uint256[](tokenCount); - for (uint256 i = 0; i < tokenCount; i++) { - _tokenIds[i] = i; - _amounts[i] = amount; - } - - bytes memory message = abi.encodeWithSelector( - IL2ERC1155Gateway.finalizeBatchDepositERC1155.selector, - address(l1Token), - address(l2Token), - address(this), - address(this), - _tokenIds, - _amounts - ); - gateway.batchDepositERC1155(address(l1Token), _tokenIds, _amounts, defaultGasLimit); - - // skip message 0 - hevm.startPrank(address(rollup)); - messageQueue.popCrossDomainMessage(0, 1, 0x1); - assertEq(messageQueue.pendingQueueIndex(), 1); - hevm.stopPrank(); - - // drop message 0 - hevm.expectEmit(true, true, false, true); - emit BatchRefundERC1155(address(l1Token), address(this), _tokenIds, _amounts); - - uint256[] memory balances = new uint256[](tokenCount); - for (uint256 i = 0; i < tokenCount; i++) { - balances[i] = l1Token.balanceOf(address(this), _tokenIds[i]); - } - l1Messenger.dropMessage(address(gateway), address(counterpartGateway), 0, 0, message); - for (uint256 i = 0; i < tokenCount; i++) { - assertEq(balances[i] + _amounts[i], l1Token.balanceOf(address(this), _tokenIds[i])); - } - } - - function testFinalizeWithdrawERC1155FailedMocking( - address sender, - address recipient, - uint256 tokenId, - uint256 amount - ) public { - tokenId = bound(tokenId, 0, TOKEN_COUNT - 1); - amount = bound(amount, 1, MAX_TOKEN_BALANCE); - - // revert when caller is not messenger - hevm.expectRevert(ErrorCallerIsNotMessenger.selector); - gateway.finalizeWithdrawERC1155(address(l1Token), address(l2Token), sender, recipient, tokenId, amount); - - MockScrollMessenger mockMessenger = new MockScrollMessenger(); - gateway = _deployGateway(address(mockMessenger)); - gateway.initialize(address(counterpartGateway), address(mockMessenger)); - - // only call by counterpart - hevm.expectRevert(ErrorCallerIsNotCounterpartGateway.selector); - mockMessenger.callTarget( - address(gateway), - abi.encodeWithSelector( - gateway.finalizeWithdrawERC1155.selector, - address(l1Token), - address(l2Token), - sender, - recipient, - tokenId, - amount - ) - ); - - mockMessenger.setXDomainMessageSender(address(counterpartGateway)); - - // msg.value mismatch - hevm.expectRevert("l2 token mismatch"); - mockMessenger.callTarget( - address(gateway), - abi.encodeWithSelector( - gateway.finalizeWithdrawERC1155.selector, - address(l1Token), - address(l2Token), - sender, - recipient, - tokenId, - amount - ) - ); - } - - function testFinalizeWithdrawERC1155Failed( - address sender, - address recipient, - uint256 tokenId, - uint256 amount - ) public { - hevm.assume(recipient != address(0)); - tokenId = bound(tokenId, 0, TOKEN_COUNT - 1); - amount = bound(amount, 1, MAX_TOKEN_BALANCE); - - gateway.updateTokenMapping(address(l1Token), address(l2Token)); - gateway.depositERC1155(address(l1Token), tokenId, amount, defaultGasLimit); - - // do finalize withdraw token - bytes memory message = abi.encodeWithSelector( - IL1ERC1155Gateway.finalizeWithdrawERC1155.selector, - address(l1Token), - address(l2Token), - sender, - recipient, - tokenId, - amount - ); - bytes memory xDomainCalldata = abi.encodeWithSignature( - "relayMessage(address,address,uint256,uint256,bytes)", - address(uint160(address(counterpartGateway)) + 1), - address(gateway), - 0, - 0, - message - ); - - prepareL2MessageRoot(keccak256(xDomainCalldata)); - - IL1ScrollMessenger.L2MessageProof memory proof; - proof.batchIndex = rollup.lastFinalizedBatchIndex(); - - // counterpart is not L2WETHGateway - // emit FailedRelayedMessage from L1ScrollMessenger - hevm.expectEmit(true, false, false, true); - emit FailedRelayedMessage(keccak256(xDomainCalldata)); - - uint256 gatewayBalance = l1Token.balanceOf(address(gateway), tokenId); - uint256 recipientBalance = l1Token.balanceOf(recipient, tokenId); - assertBoolEq(false, l1Messenger.isL2MessageExecuted(keccak256(xDomainCalldata))); - l1Messenger.relayMessageWithProof( - address(uint160(address(counterpartGateway)) + 1), - address(gateway), - 0, - 0, - message, - proof - ); - assertEq(gatewayBalance, l1Token.balanceOf(address(gateway), tokenId)); - assertEq(recipientBalance, l1Token.balanceOf(recipient, tokenId)); - assertBoolEq(false, l1Messenger.isL2MessageExecuted(keccak256(xDomainCalldata))); - } - - function testFinalizeWithdrawERC1155( - address sender, - address recipient, - uint256 tokenId, - uint256 amount - ) public { - uint256 size; - assembly { - size := extcodesize(recipient) - } - hevm.assume(size == 0); - hevm.assume(recipient != address(0)); - - tokenId = bound(tokenId, 0, TOKEN_COUNT - 1); - amount = bound(amount, 1, MAX_TOKEN_BALANCE); - - gateway.updateTokenMapping(address(l1Token), address(l2Token)); - gateway.depositERC1155(address(l1Token), tokenId, amount, defaultGasLimit); - - // do finalize withdraw token - bytes memory message = abi.encodeWithSelector( - IL1ERC1155Gateway.finalizeWithdrawERC1155.selector, - address(l1Token), - address(l2Token), - sender, - recipient, - tokenId, - amount - ); - bytes memory xDomainCalldata = abi.encodeWithSignature( - "relayMessage(address,address,uint256,uint256,bytes)", - address(counterpartGateway), - address(gateway), - 0, - 0, - message - ); - - prepareL2MessageRoot(keccak256(xDomainCalldata)); - - IL1ScrollMessenger.L2MessageProof memory proof; - proof.batchIndex = rollup.lastFinalizedBatchIndex(); - - // emit FinalizeWithdrawERC1155 from L1ERC1155Gateway - { - hevm.expectEmit(true, true, true, true); - emit FinalizeWithdrawERC1155(address(l1Token), address(l2Token), sender, recipient, tokenId, amount); - } - - // emit RelayedMessage from L1ScrollMessenger - { - hevm.expectEmit(true, false, false, true); - emit RelayedMessage(keccak256(xDomainCalldata)); - } - - uint256 gatewayBalance = l1Token.balanceOf(address(gateway), tokenId); - uint256 recipientBalance = l1Token.balanceOf(recipient, tokenId); - assertBoolEq(false, l1Messenger.isL2MessageExecuted(keccak256(xDomainCalldata))); - l1Messenger.relayMessageWithProof(address(counterpartGateway), address(gateway), 0, 0, message, proof); - assertEq(gatewayBalance - amount, l1Token.balanceOf(address(gateway), tokenId)); - assertEq(recipientBalance + amount, l1Token.balanceOf(recipient, tokenId)); - assertBoolEq(true, l1Messenger.isL2MessageExecuted(keccak256(xDomainCalldata))); - } - - function testFinalizeBatchWithdrawERC1155FailedMocking( - address sender, - address recipient, - uint256 tokenCount, - uint256 amount - ) public { - tokenCount = bound(tokenCount, 1, TOKEN_COUNT); - amount = bound(amount, 1, MAX_TOKEN_BALANCE); - uint256[] memory _tokenIds = new uint256[](tokenCount); - uint256[] memory _amounts = new uint256[](tokenCount); - for (uint256 i = 0; i < tokenCount; i++) { - _tokenIds[i] = i; - _amounts[i] = amount; - } - - // revert when caller is not messenger - hevm.expectRevert(ErrorCallerIsNotMessenger.selector); - gateway.finalizeBatchWithdrawERC1155( - address(l1Token), - address(l2Token), - sender, - recipient, - _tokenIds, - _amounts - ); - - MockScrollMessenger mockMessenger = new MockScrollMessenger(); - gateway = _deployGateway(address(mockMessenger)); - gateway.initialize(address(counterpartGateway), address(mockMessenger)); - - // only call by counterpart - hevm.expectRevert(ErrorCallerIsNotCounterpartGateway.selector); - mockMessenger.callTarget( - address(gateway), - abi.encodeWithSelector( - gateway.finalizeBatchWithdrawERC1155.selector, - address(l1Token), - address(l2Token), - sender, - recipient, - _tokenIds, - _amounts - ) - ); - - mockMessenger.setXDomainMessageSender(address(counterpartGateway)); - - // msg.value mismatch - hevm.expectRevert("l2 token mismatch"); - mockMessenger.callTarget( - address(gateway), - abi.encodeWithSelector( - gateway.finalizeBatchWithdrawERC1155.selector, - address(l1Token), - address(l2Token), - sender, - recipient, - _tokenIds, - _amounts - ) - ); - } - - function testFinalizeBatchWithdrawERC1155Failed( - address sender, - address recipient, - uint256 tokenCount, - uint256 amount - ) public { - hevm.assume(recipient != address(0)); - tokenCount = bound(tokenCount, 1, TOKEN_COUNT); - amount = bound(amount, 1, MAX_TOKEN_BALANCE); - uint256[] memory _tokenIds = new uint256[](tokenCount); - uint256[] memory _amounts = new uint256[](tokenCount); - for (uint256 i = 0; i < tokenCount; i++) { - _tokenIds[i] = i; - _amounts[i] = amount; - } - - gateway.updateTokenMapping(address(l1Token), address(l2Token)); - gateway.batchDepositERC1155(address(l1Token), _tokenIds, _amounts, defaultGasLimit); - - // do finalize withdraw token - bytes memory message = abi.encodeWithSelector( - IL1ERC1155Gateway.finalizeBatchWithdrawERC1155.selector, - address(l1Token), - address(l2Token), - sender, - recipient, - _tokenIds, - _amounts - ); - bytes memory xDomainCalldata = abi.encodeWithSignature( - "relayMessage(address,address,uint256,uint256,bytes)", - address(uint160(address(counterpartGateway)) + 1), - address(gateway), - 0, - 0, - message - ); - - prepareL2MessageRoot(keccak256(xDomainCalldata)); - - IL1ScrollMessenger.L2MessageProof memory proof; - proof.batchIndex = rollup.lastFinalizedBatchIndex(); - - // counterpart is not L2WETHGateway - // emit FailedRelayedMessage from L1ScrollMessenger - hevm.expectEmit(true, false, false, true); - emit FailedRelayedMessage(keccak256(xDomainCalldata)); - - uint256[] memory gatewayBalances = new uint256[](tokenCount); - uint256[] memory recipientBalances = new uint256[](tokenCount); - for (uint256 i = 0; i < tokenCount; i++) { - gatewayBalances[i] = l1Token.balanceOf(address(gateway), i); - recipientBalances[i] = l1Token.balanceOf(recipient, i); - } - assertBoolEq(false, l1Messenger.isL2MessageExecuted(keccak256(xDomainCalldata))); - l1Messenger.relayMessageWithProof( - address(uint160(address(counterpartGateway)) + 1), - address(gateway), - 0, - 0, - message, - proof - ); - for (uint256 i = 0; i < tokenCount; i++) { - assertEq(gatewayBalances[i], l1Token.balanceOf(address(gateway), i)); - assertEq(recipientBalances[i], l1Token.balanceOf(recipient, i)); - } - assertBoolEq(false, l1Messenger.isL2MessageExecuted(keccak256(xDomainCalldata))); - } - - function testFinalizeBatchWithdrawERC1155( - address sender, - address recipient, - uint256 tokenCount, - uint256 amount - ) public { - uint256 size; - assembly { - size := extcodesize(recipient) - } - hevm.assume(size == 0); - hevm.assume(recipient != address(0)); - - tokenCount = bound(tokenCount, 1, TOKEN_COUNT); - amount = bound(amount, 1, MAX_TOKEN_BALANCE); - uint256[] memory _tokenIds = new uint256[](tokenCount); - uint256[] memory _amounts = new uint256[](tokenCount); - for (uint256 i = 0; i < tokenCount; i++) { - _tokenIds[i] = i; - _amounts[i] = amount; - } - - gateway.updateTokenMapping(address(l1Token), address(l2Token)); - gateway.batchDepositERC1155(address(l1Token), _tokenIds, _amounts, defaultGasLimit); - - // do finalize withdraw token - bytes memory message = abi.encodeWithSelector( - IL1ERC1155Gateway.finalizeBatchWithdrawERC1155.selector, - address(l1Token), - address(l2Token), - sender, - recipient, - _tokenIds, - _amounts - ); - bytes memory xDomainCalldata = abi.encodeWithSignature( - "relayMessage(address,address,uint256,uint256,bytes)", - address(counterpartGateway), - address(gateway), - 0, - 0, - message - ); - - prepareL2MessageRoot(keccak256(xDomainCalldata)); - - IL1ScrollMessenger.L2MessageProof memory proof; - proof.batchIndex = rollup.lastFinalizedBatchIndex(); - - // emit FinalizeBatchWithdrawERC1155 from L1ERC1155Gateway - { - hevm.expectEmit(true, true, true, true); - emit FinalizeBatchWithdrawERC1155( - address(l1Token), - address(l2Token), - sender, - recipient, - _tokenIds, - _amounts - ); - } - - // emit RelayedMessage from L1ScrollMessenger - { - hevm.expectEmit(true, false, false, true); - emit RelayedMessage(keccak256(xDomainCalldata)); - } - - uint256[] memory gatewayBalances = new uint256[](tokenCount); - uint256[] memory recipientBalances = new uint256[](tokenCount); - for (uint256 i = 0; i < tokenCount; i++) { - gatewayBalances[i] = l1Token.balanceOf(address(gateway), i); - recipientBalances[i] = l1Token.balanceOf(recipient, i); - } - assertBoolEq(false, l1Messenger.isL2MessageExecuted(keccak256(xDomainCalldata))); - l1Messenger.relayMessageWithProof(address(counterpartGateway), address(gateway), 0, 0, message, proof); - - for (uint256 i = 0; i < tokenCount; i++) { - assertEq(gatewayBalances[i] - _amounts[i], l1Token.balanceOf(address(gateway), i)); - assertEq(recipientBalances[i] + _amounts[i], l1Token.balanceOf(recipient, i)); - } - assertBoolEq(true, l1Messenger.isL2MessageExecuted(keccak256(xDomainCalldata))); - } - - function testReentranceWhenFinalizeWithdraw( - address from, - uint256 tokenId, - uint256 amount - ) public { - MockScrollMessenger mockMessenger = new MockScrollMessenger(); - gateway = _deployGateway(address(mockMessenger)); - gateway.initialize(address(counterpartGateway), address(mockMessenger)); - l1Token.setApprovalForAll(address(gateway), true); - - // deposit first - gateway.updateTokenMapping(address(l1Token), address(l2Token)); - tokenId = bound(tokenId, 0, TOKEN_COUNT - 1); - amount = bound(amount, 1, MAX_TOKEN_BALANCE); - gateway.depositERC1155(address(l1Token), tokenId, amount, defaultGasLimit); - - mockRecipient.setCall( - address(gateway), - 0, - abi.encodeWithSignature( - "depositERC1155(address,uint256,uint256,uint256)", - address(l1Token), - tokenId, - amount, - 0 - ) - ); - - // finalize withdraw - mockMessenger.setXDomainMessageSender(address(counterpartGateway)); - hevm.expectRevert("ReentrancyGuard: reentrant call"); - mockMessenger.callTarget( - address(gateway), - abi.encodeWithSelector( - IL1ERC1155Gateway.finalizeWithdrawERC1155.selector, - address(l1Token), - address(l2Token), - from, - address(mockRecipient), - tokenId, - amount - ) - ); - - // finalize batch withdraw - mockMessenger.setXDomainMessageSender(address(counterpartGateway)); - hevm.expectRevert("ReentrancyGuard: reentrant call"); - uint256[] memory tokenIds = new uint256[](1); - uint256[] memory amounts = new uint256[](1); - tokenIds[0] = tokenId; - amounts[0] = amount; - mockMessenger.callTarget( - address(gateway), - abi.encodeWithSelector( - IL1ERC1155Gateway.finalizeBatchWithdrawERC1155.selector, - address(l1Token), - address(l2Token), - from, - address(mockRecipient), - tokenIds, - amounts - ) - ); - } - - function _testDepositERC1155( - uint256 tokenId, - uint256 amount, - uint256 gasLimit, - uint256 feePerGas - ) internal { - tokenId = bound(tokenId, 0, TOKEN_COUNT - 1); - amount = bound(amount, 0, MAX_TOKEN_BALANCE); - gasLimit = bound(gasLimit, defaultGasLimit / 2, defaultGasLimit); - feePerGas = bound(feePerGas, 0, 1000); - - messageQueue.setL2BaseFee(feePerGas); - uint256 feeToPay = feePerGas * gasLimit; - - bytes memory message = abi.encodeWithSelector( - IL2ERC1155Gateway.finalizeDepositERC1155.selector, - address(l1Token), - address(l2Token), - address(this), - address(this), - tokenId, - amount - ); - bytes memory xDomainCalldata = abi.encodeWithSignature( - "relayMessage(address,address,uint256,uint256,bytes)", - address(gateway), - address(counterpartGateway), - 0, - 0, - message - ); - - if (amount == 0) { - hevm.expectRevert("deposit zero amount"); - gateway.depositERC1155{value: feeToPay + extraValue}(address(l1Token), tokenId, amount, gasLimit); - } else { - hevm.expectRevert("no corresponding l2 token"); - gateway.depositERC1155(address(l1Token), tokenId, amount, gasLimit); - - gateway.updateTokenMapping(address(l1Token), address(l2Token)); - // emit QueueTransaction from L1MessageQueue - { - hevm.expectEmit(true, true, false, true); - address sender = AddressAliasHelper.applyL1ToL2Alias(address(l1Messenger)); - emit QueueTransaction(sender, address(l2Messenger), 0, 0, gasLimit, xDomainCalldata); - } - - // emit SentMessage from L1ScrollMessenger - { - hevm.expectEmit(true, true, false, true); - emit SentMessage(address(gateway), address(counterpartGateway), 0, 0, gasLimit, message); - } - - // emit FinalizeWithdrawERC1155 from L1ERC1155Gateway - hevm.expectEmit(true, true, true, true); - emit DepositERC1155(address(l1Token), address(l2Token), address(this), address(this), tokenId, amount); - - uint256 gatewayBalance = l1Token.balanceOf(address(gateway), tokenId); - uint256 feeVaultBalance = address(feeVault).balance; - assertEq(l1Messenger.messageSendTimestamp(keccak256(xDomainCalldata)), 0); - gateway.depositERC1155{value: feeToPay + extraValue}(address(l1Token), tokenId, amount, gasLimit); - assertEq(amount + gatewayBalance, l1Token.balanceOf(address(gateway), tokenId)); - assertEq(feeToPay + feeVaultBalance, address(feeVault).balance); - assertGt(l1Messenger.messageSendTimestamp(keccak256(xDomainCalldata)), 0); - } - } - - function _testDepositERC1155WithRecipient( - uint256 tokenId, - uint256 amount, - address recipient, - uint256 gasLimit, - uint256 feePerGas - ) internal { - tokenId = bound(tokenId, 0, TOKEN_COUNT - 1); - amount = bound(amount, 0, MAX_TOKEN_BALANCE); - gasLimit = bound(gasLimit, defaultGasLimit / 2, defaultGasLimit); - feePerGas = bound(feePerGas, 0, 1000); - - messageQueue.setL2BaseFee(feePerGas); - uint256 feeToPay = feePerGas * gasLimit; - - bytes memory message = abi.encodeWithSelector( - IL2ERC1155Gateway.finalizeDepositERC1155.selector, - address(l1Token), - address(l2Token), - address(this), - recipient, - tokenId, - amount - ); - bytes memory xDomainCalldata = abi.encodeWithSignature( - "relayMessage(address,address,uint256,uint256,bytes)", - address(gateway), - address(counterpartGateway), - 0, - 0, - message - ); - - if (amount == 0) { - hevm.expectRevert("deposit zero amount"); - gateway.depositERC1155{value: feeToPay + extraValue}( - address(l1Token), - recipient, - tokenId, - amount, - gasLimit - ); - } else { - hevm.expectRevert("no corresponding l2 token"); - gateway.depositERC1155(address(l1Token), tokenId, amount, gasLimit); - - gateway.updateTokenMapping(address(l1Token), address(l2Token)); - // emit QueueTransaction from L1MessageQueue - { - hevm.expectEmit(true, true, false, true); - address sender = AddressAliasHelper.applyL1ToL2Alias(address(l1Messenger)); - emit QueueTransaction(sender, address(l2Messenger), 0, 0, gasLimit, xDomainCalldata); - } - - // emit SentMessage from L1ScrollMessenger - { - hevm.expectEmit(true, true, false, true); - emit SentMessage(address(gateway), address(counterpartGateway), 0, 0, gasLimit, message); - } - - // emit FinalizeWithdrawERC1155 from L1ERC1155Gateway - hevm.expectEmit(true, true, true, true); - emit DepositERC1155(address(l1Token), address(l2Token), address(this), recipient, tokenId, amount); - - uint256 gatewayBalance = l1Token.balanceOf(address(gateway), tokenId); - uint256 feeVaultBalance = address(feeVault).balance; - assertEq(l1Messenger.messageSendTimestamp(keccak256(xDomainCalldata)), 0); - gateway.depositERC1155{value: feeToPay + extraValue}( - address(l1Token), - recipient, - tokenId, - amount, - gasLimit - ); - assertEq(amount + gatewayBalance, l1Token.balanceOf(address(gateway), tokenId)); - assertEq(feeToPay + feeVaultBalance, address(feeVault).balance); - assertGt(l1Messenger.messageSendTimestamp(keccak256(xDomainCalldata)), 0); - } - } - - function _testBatchDepositERC1155( - uint256 tokenCount, - uint256 amount, - uint256 gasLimit, - uint256 feePerGas - ) internal { - tokenCount = bound(tokenCount, 1, TOKEN_COUNT); - amount = bound(amount, 1, MAX_TOKEN_BALANCE); - gasLimit = bound(gasLimit, defaultGasLimit / 2, defaultGasLimit); - feePerGas = bound(feePerGas, 0, 1000); - - messageQueue.setL2BaseFee(feePerGas); - uint256 feeToPay = feePerGas * gasLimit; - - uint256[] memory _tokenIds = new uint256[](tokenCount); - uint256[] memory _amounts = new uint256[](tokenCount); - for (uint256 i = 0; i < tokenCount; i++) { - _tokenIds[i] = i; - _amounts[i] = amount; - } - - hevm.expectRevert("no token to deposit"); - gateway.batchDepositERC1155(address(l1Token), new uint256[](0), new uint256[](0), gasLimit); - - hevm.expectRevert("length mismatch"); - gateway.batchDepositERC1155(address(l1Token), new uint256[](1), new uint256[](0), gasLimit); - - hevm.expectRevert("deposit zero amount"); - gateway.batchDepositERC1155(address(l1Token), _tokenIds, new uint256[](tokenCount), gasLimit); - - hevm.expectRevert("no corresponding l2 token"); - gateway.batchDepositERC1155(address(l1Token), _tokenIds, _amounts, gasLimit); - - bytes memory message = abi.encodeWithSelector( - IL2ERC1155Gateway.finalizeBatchDepositERC1155.selector, - address(l1Token), - address(l2Token), - address(this), - address(this), - _tokenIds, - _amounts - ); - bytes memory xDomainCalldata = abi.encodeWithSignature( - "relayMessage(address,address,uint256,uint256,bytes)", - address(gateway), - address(counterpartGateway), - 0, - 0, - message - ); - - gateway.updateTokenMapping(address(l1Token), address(l2Token)); - - // emit QueueTransaction from L1MessageQueue - { - hevm.expectEmit(true, true, false, true); - address sender = AddressAliasHelper.applyL1ToL2Alias(address(l1Messenger)); - emit QueueTransaction(sender, address(l2Messenger), 0, 0, gasLimit, xDomainCalldata); - } - - // emit SentMessage from L1ScrollMessenger - { - hevm.expectEmit(true, true, false, true); - emit SentMessage(address(gateway), address(counterpartGateway), 0, 0, gasLimit, message); - } - - // emit FinalizeWithdrawERC1155 from L1ERC1155Gateway - hevm.expectEmit(true, true, true, true); - emit BatchDepositERC1155(address(l1Token), address(l2Token), address(this), address(this), _tokenIds, _amounts); - - uint256[] memory gatewayBalances = new uint256[](tokenCount); - for (uint256 i = 0; i < tokenCount; i++) { - gatewayBalances[i] = l1Token.balanceOf(address(gateway), i); - } - uint256 feeVaultBalance = address(feeVault).balance; - assertEq(l1Messenger.messageSendTimestamp(keccak256(xDomainCalldata)), 0); - gateway.batchDepositERC1155{value: feeToPay + extraValue}(address(l1Token), _tokenIds, _amounts, gasLimit); - for (uint256 i = 0; i < tokenCount; i++) { - assertEq(gatewayBalances[i] + amount, l1Token.balanceOf(address(gateway), i)); - } - assertEq(feeToPay + feeVaultBalance, address(feeVault).balance); - assertGt(l1Messenger.messageSendTimestamp(keccak256(xDomainCalldata)), 0); - } - - function _testBatchDepositERC1155WithRecipient( - uint256 tokenCount, - uint256 amount, - address recipient, - uint256 gasLimit, - uint256 feePerGas - ) internal { - tokenCount = bound(tokenCount, 1, TOKEN_COUNT); - amount = bound(amount, 1, MAX_TOKEN_BALANCE); - gasLimit = bound(gasLimit, defaultGasLimit / 2, defaultGasLimit); - feePerGas = bound(feePerGas, 0, 1000); - - messageQueue.setL2BaseFee(feePerGas); - uint256 feeToPay = feePerGas * gasLimit; - - uint256[] memory _tokenIds = new uint256[](tokenCount); - uint256[] memory _amounts = new uint256[](tokenCount); - for (uint256 i = 0; i < tokenCount; i++) { - _tokenIds[i] = i; - _amounts[i] = amount; - } - - hevm.expectRevert("no token to deposit"); - gateway.batchDepositERC1155(address(l1Token), recipient, new uint256[](0), new uint256[](0), gasLimit); - - hevm.expectRevert("length mismatch"); - gateway.batchDepositERC1155(address(l1Token), recipient, new uint256[](1), new uint256[](0), gasLimit); - - hevm.expectRevert("deposit zero amount"); - gateway.batchDepositERC1155(address(l1Token), recipient, _tokenIds, new uint256[](tokenCount), gasLimit); - - hevm.expectRevert("no corresponding l2 token"); - gateway.batchDepositERC1155(address(l1Token), recipient, _tokenIds, _amounts, gasLimit); - - bytes memory message = abi.encodeWithSelector( - IL2ERC1155Gateway.finalizeBatchDepositERC1155.selector, - address(l1Token), - address(l2Token), - address(this), - recipient, - _tokenIds, - _amounts - ); - bytes memory xDomainCalldata = abi.encodeWithSignature( - "relayMessage(address,address,uint256,uint256,bytes)", - address(gateway), - address(counterpartGateway), - 0, - 0, - message - ); - - gateway.updateTokenMapping(address(l1Token), address(l2Token)); - - // emit QueueTransaction from L1MessageQueue - { - hevm.expectEmit(true, true, false, true); - address sender = AddressAliasHelper.applyL1ToL2Alias(address(l1Messenger)); - emit QueueTransaction(sender, address(l2Messenger), 0, 0, gasLimit, xDomainCalldata); - } - - // emit SentMessage from L1ScrollMessenger - { - hevm.expectEmit(true, true, false, true); - emit SentMessage(address(gateway), address(counterpartGateway), 0, 0, gasLimit, message); - } - - // emit FinalizeWithdrawERC1155 from L1ERC1155Gateway - hevm.expectEmit(true, true, true, true); - emit BatchDepositERC1155(address(l1Token), address(l2Token), address(this), recipient, _tokenIds, _amounts); - - uint256[] memory gatewayBalances = new uint256[](tokenCount); - for (uint256 i = 0; i < tokenCount; i++) { - gatewayBalances[i] = l1Token.balanceOf(address(gateway), i); - } - uint256 feeVaultBalance = address(feeVault).balance; - assertEq(l1Messenger.messageSendTimestamp(keccak256(xDomainCalldata)), 0); - gateway.batchDepositERC1155{value: feeToPay + extraValue}( - address(l1Token), - recipient, - _tokenIds, - _amounts, - gasLimit - ); - for (uint256 i = 0; i < tokenCount; i++) { - assertEq(gatewayBalances[i] + amount, l1Token.balanceOf(address(gateway), i)); - } - assertEq(feeToPay + feeVaultBalance, address(feeVault).balance); - assertGt(l1Messenger.messageSendTimestamp(keccak256(xDomainCalldata)), 0); - } - - function _deployGateway(address messenger) internal returns (L1ERC1155Gateway _gateway) { - _gateway = L1ERC1155Gateway(_deployProxy(address(0))); - - admin.upgrade( - ITransparentUpgradeableProxy(address(_gateway)), - address(new L1ERC1155Gateway(address(counterpartGateway), address(messenger))) - ); - } -} diff --git a/contracts/src/test/L1ERC721Gateway.t.sol b/contracts/src/test/L1ERC721Gateway.t.sol deleted file mode 100644 index b76163d83..000000000 --- a/contracts/src/test/L1ERC721Gateway.t.sol +++ /dev/null @@ -1,952 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {MockERC721} from "solmate/test/utils/mocks/MockERC721.sol"; -import {ERC721TokenReceiver} from "solmate/tokens/ERC721.sol"; - -import {ITransparentUpgradeableProxy} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; - -import {IL1ERC721Gateway, L1ERC721Gateway} from "../L1/gateways/L1ERC721Gateway.sol"; -import {IL1ScrollMessenger} from "../L1/IL1ScrollMessenger.sol"; -import {IL2ERC721Gateway, L2ERC721Gateway} from "../L2/gateways/L2ERC721Gateway.sol"; -import {AddressAliasHelper} from "../libraries/common/AddressAliasHelper.sol"; -import {ScrollConstants} from "../libraries/constants/ScrollConstants.sol"; - -import {L1GatewayTestBase} from "./L1GatewayTestBase.t.sol"; -import {MockScrollMessenger} from "./mocks/MockScrollMessenger.sol"; -import {MockERC721Recipient} from "./mocks/MockERC721Recipient.sol"; - -contract L1ERC721GatewayTest is L1GatewayTestBase, ERC721TokenReceiver { - // from L1ERC721Gateway - event FinalizeWithdrawERC721( - address indexed _l1Token, - address indexed _l2Token, - address indexed _from, - address _to, - uint256 _tokenId - ); - event FinalizeBatchWithdrawERC721( - address indexed _l1Token, - address indexed _l2Token, - address indexed _from, - address _to, - uint256[] _tokenIds - ); - event DepositERC721( - address indexed _l1Token, - address indexed _l2Token, - address indexed _from, - address _to, - uint256 _tokenId - ); - event BatchDepositERC721( - address indexed _l1Token, - address indexed _l2Token, - address indexed _from, - address _to, - uint256[] _tokenIds - ); - event RefundERC721(address indexed token, address indexed recipient, uint256 tokenId); - event BatchRefundERC721(address indexed token, address indexed recipient, uint256[] tokenIds); - - uint256 private constant TOKEN_COUNT = 100; - - L1ERC721Gateway private gateway; - - L2ERC721Gateway private counterpartGateway; - - MockERC721 private l1Token; - MockERC721 private l2Token; - MockERC721Recipient private mockRecipient; - - function setUp() public { - __L1GatewayTestBase_setUp(); - - // Deploy tokens - l1Token = new MockERC721("Mock L1", "ML1"); - l2Token = new MockERC721("Mock L2", "ML1"); - - // Deploy L2 contracts - counterpartGateway = new L2ERC721Gateway(address(1), address(1)); - - // Deploy L1 contracts - gateway = _deployGateway(address(l1Messenger)); - - // Initialize L1 contracts - gateway.initialize(address(counterpartGateway), address(l1Messenger)); - - // Prepare token balances - for (uint256 i = 0; i < TOKEN_COUNT; i++) { - l1Token.mint(address(this), i); - } - l1Token.setApprovalForAll(address(gateway), true); - - mockRecipient = new MockERC721Recipient(); - } - - function testInitialized() public { - assertEq(address(counterpartGateway), gateway.counterpart()); - assertEq(address(0), gateway.router()); - assertEq(address(l1Messenger), gateway.messenger()); - - assertEq(address(0), gateway.tokenMapping(address(l1Token))); - - hevm.expectRevert("Initializable: contract is already initialized"); - gateway.initialize(address(1), address(l1Messenger)); - } - - function testUpdateTokenMappingFailed(address token1) public { - // call by non-owner, should revert - hevm.startPrank(address(1)); - hevm.expectRevert("Ownable: caller is not the owner"); - gateway.updateTokenMapping(token1, token1); - hevm.stopPrank(); - - // l2 token is zero, should revert - hevm.expectRevert("token address cannot be 0"); - gateway.updateTokenMapping(token1, address(0)); - } - - function testUpdateTokenMappingSuccess(address token1, address token2) public { - hevm.assume(token2 != address(0)); - - assertEq(gateway.tokenMapping(token1), address(0)); - gateway.updateTokenMapping(token1, token2); - assertEq(gateway.tokenMapping(token1), token2); - } - - function testDepositERC721( - uint256 tokenId, - uint256 gasLimit, - uint256 feePerGas - ) public { - _testDepositERC721(tokenId, gasLimit, feePerGas); - } - - function testDepositERC721WithRecipient( - uint256 tokenId, - address to, - uint256 gasLimit, - uint256 feePerGas - ) public { - _testDepositERC721WithRecipient(tokenId, to, gasLimit, feePerGas); - } - - function testBatchDepositERC721WithGatewaySuccess( - uint256 tokenCount, - uint256 gasLimit, - uint256 feePerGas - ) public { - _testBatchDepositERC721(tokenCount, gasLimit, feePerGas); - } - - /// @dev batch deposit erc721 with recipient - function testBatchDepositERC721WithGatewaySuccess( - uint256 tokenCount, - address recipient, - uint256 gasLimit, - uint256 feePerGas - ) public { - _testBatchDepositERC721WithRecipient(tokenCount, recipient, gasLimit, feePerGas); - } - - function testDropMessageMocking() public { - MockScrollMessenger mockMessenger = new MockScrollMessenger(); - gateway = _deployGateway(address(mockMessenger)); - gateway.initialize(address(counterpartGateway), address(mockMessenger)); - - // only messenger can call, revert - hevm.expectRevert(ErrorCallerIsNotMessenger.selector); - gateway.onDropMessage(new bytes(0)); - - // only called in drop context, revert - hevm.expectRevert(ErrorNotInDropMessageContext.selector); - mockMessenger.callTarget( - address(gateway), - abi.encodeWithSelector(gateway.onDropMessage.selector, new bytes(0)) - ); - - mockMessenger.setXDomainMessageSender(ScrollConstants.DROP_XDOMAIN_MESSAGE_SENDER); - - // invalid selector, revert - hevm.expectRevert("invalid selector"); - mockMessenger.callTarget( - address(gateway), - abi.encodeWithSelector(gateway.onDropMessage.selector, new bytes(4)) - ); - - bytes memory message = abi.encodeWithSelector( - IL2ERC721Gateway.finalizeDepositERC721.selector, - address(l1Token), - address(l2Token), - address(this), - address(this), - 0 - ); - - // nonzero msg.value, revert - hevm.expectRevert("nonzero msg.value"); - mockMessenger.callTarget{value: 1}( - address(gateway), - abi.encodeWithSelector(gateway.onDropMessage.selector, message) - ); - } - - function testDropMessage(uint256 tokenId) public { - gateway.updateTokenMapping(address(l1Token), address(l2Token)); - - tokenId = bound(tokenId, 0, TOKEN_COUNT - 1); - bytes memory message = abi.encodeWithSelector( - IL2ERC721Gateway.finalizeDepositERC721.selector, - address(l1Token), - address(l2Token), - address(this), - address(this), - tokenId - ); - gateway.depositERC721(address(l1Token), tokenId, defaultGasLimit); - - // skip message 0 - hevm.startPrank(address(rollup)); - messageQueue.popCrossDomainMessage(0, 1, 0x1); - assertEq(messageQueue.pendingQueueIndex(), 1); - hevm.stopPrank(); - - // drop message 0 - hevm.expectEmit(true, true, false, true); - emit RefundERC721(address(l1Token), address(this), tokenId); - - assertEq(l1Token.ownerOf(tokenId), address(gateway)); - l1Messenger.dropMessage(address(gateway), address(counterpartGateway), 0, 0, message); - assertEq(l1Token.ownerOf(tokenId), address(this)); - } - - function testDropMessageBatch(uint256 tokenCount) public { - tokenCount = bound(tokenCount, 1, TOKEN_COUNT); - gateway.updateTokenMapping(address(l1Token), address(l2Token)); - - uint256[] memory _tokenIds = new uint256[](tokenCount); - for (uint256 i = 0; i < tokenCount; i++) { - _tokenIds[i] = i; - } - - bytes memory message = abi.encodeWithSelector( - IL2ERC721Gateway.finalizeBatchDepositERC721.selector, - address(l1Token), - address(l2Token), - address(this), - address(this), - _tokenIds - ); - gateway.batchDepositERC721(address(l1Token), _tokenIds, defaultGasLimit); - - // skip message 0 - hevm.startPrank(address(rollup)); - messageQueue.popCrossDomainMessage(0, 1, 0x1); - assertEq(messageQueue.pendingQueueIndex(), 1); - hevm.stopPrank(); - - // drop message 0 - hevm.expectEmit(true, true, false, true); - emit BatchRefundERC721(address(l1Token), address(this), _tokenIds); - for (uint256 i = 0; i < tokenCount; i++) { - assertEq(l1Token.ownerOf(_tokenIds[i]), address(gateway)); - } - - l1Messenger.dropMessage(address(gateway), address(counterpartGateway), 0, 0, message); - for (uint256 i = 0; i < tokenCount; i++) { - assertEq(l1Token.ownerOf(_tokenIds[i]), address(this)); - } - } - - function testFinalizeWithdrawERC721FailedMocking( - address sender, - address recipient, - uint256 tokenId - ) public { - tokenId = bound(tokenId, 0, TOKEN_COUNT - 1); - - // revert when caller is not messenger - hevm.expectRevert(ErrorCallerIsNotMessenger.selector); - gateway.finalizeWithdrawERC721(address(l1Token), address(l2Token), sender, recipient, tokenId); - - MockScrollMessenger mockMessenger = new MockScrollMessenger(); - gateway = _deployGateway(address(mockMessenger)); - gateway.initialize(address(counterpartGateway), address(mockMessenger)); - - // only call by counterpart - hevm.expectRevert(ErrorCallerIsNotCounterpartGateway.selector); - mockMessenger.callTarget( - address(gateway), - abi.encodeWithSelector( - gateway.finalizeWithdrawERC721.selector, - address(l1Token), - address(l2Token), - sender, - recipient, - tokenId - ) - ); - - mockMessenger.setXDomainMessageSender(address(counterpartGateway)); - - // msg.value mismatch - hevm.expectRevert("l2 token mismatch"); - mockMessenger.callTarget( - address(gateway), - abi.encodeWithSelector( - gateway.finalizeWithdrawERC721.selector, - address(l1Token), - address(l2Token), - sender, - recipient, - tokenId - ) - ); - } - - function testFinalizeWithdrawERC721Failed( - address sender, - address recipient, - uint256 tokenId - ) public { - hevm.assume(recipient != address(0)); - tokenId = bound(tokenId, 0, TOKEN_COUNT - 1); - - gateway.updateTokenMapping(address(l1Token), address(l2Token)); - gateway.depositERC721(address(l1Token), tokenId, defaultGasLimit); - - // do finalize withdraw token - bytes memory message = abi.encodeWithSelector( - IL1ERC721Gateway.finalizeWithdrawERC721.selector, - address(l1Token), - address(l2Token), - sender, - recipient, - tokenId - ); - bytes memory xDomainCalldata = abi.encodeWithSignature( - "relayMessage(address,address,uint256,uint256,bytes)", - address(uint160(address(counterpartGateway)) + 1), - address(gateway), - 0, - 0, - message - ); - - prepareL2MessageRoot(keccak256(xDomainCalldata)); - - IL1ScrollMessenger.L2MessageProof memory proof; - proof.batchIndex = rollup.lastFinalizedBatchIndex(); - - // counterpart is not L2WETHGateway - // emit FailedRelayedMessage from L1ScrollMessenger - hevm.expectEmit(true, false, false, true); - emit FailedRelayedMessage(keccak256(xDomainCalldata)); - - assertEq(address(gateway), l1Token.ownerOf(tokenId)); - uint256 gatewayBalance = l1Token.balanceOf(address(gateway)); - uint256 recipientBalance = l1Token.balanceOf(recipient); - assertBoolEq(false, l1Messenger.isL2MessageExecuted(keccak256(xDomainCalldata))); - l1Messenger.relayMessageWithProof( - address(uint160(address(counterpartGateway)) + 1), - address(gateway), - 0, - 0, - message, - proof - ); - assertEq(address(gateway), l1Token.ownerOf(tokenId)); - assertEq(gatewayBalance, l1Token.balanceOf(address(gateway))); - assertEq(recipientBalance, l1Token.balanceOf(recipient)); - assertBoolEq(false, l1Messenger.isL2MessageExecuted(keccak256(xDomainCalldata))); - } - - function testFinalizeWithdrawERC721( - address sender, - address recipient, - uint256 tokenId - ) public { - uint256 size; - assembly { - size := extcodesize(recipient) - } - hevm.assume(size == 0); - hevm.assume(recipient != address(0)); - - tokenId = bound(tokenId, 0, TOKEN_COUNT - 1); - - gateway.updateTokenMapping(address(l1Token), address(l2Token)); - gateway.depositERC721(address(l1Token), tokenId, defaultGasLimit); - - // do finalize withdraw token - bytes memory message = abi.encodeWithSelector( - IL1ERC721Gateway.finalizeWithdrawERC721.selector, - address(l1Token), - address(l2Token), - sender, - recipient, - tokenId - ); - bytes memory xDomainCalldata = abi.encodeWithSignature( - "relayMessage(address,address,uint256,uint256,bytes)", - address(counterpartGateway), - address(gateway), - 0, - 0, - message - ); - - prepareL2MessageRoot(keccak256(xDomainCalldata)); - - IL1ScrollMessenger.L2MessageProof memory proof; - proof.batchIndex = rollup.lastFinalizedBatchIndex(); - - // emit FinalizeWithdrawERC721 from L1ERC721Gateway - { - hevm.expectEmit(true, true, true, true); - emit FinalizeWithdrawERC721(address(l1Token), address(l2Token), sender, recipient, tokenId); - } - - // emit RelayedMessage from L1ScrollMessenger - { - hevm.expectEmit(true, false, false, true); - emit RelayedMessage(keccak256(xDomainCalldata)); - } - - assertEq(address(gateway), l1Token.ownerOf(tokenId)); - uint256 gatewayBalance = l1Token.balanceOf(address(gateway)); - uint256 recipientBalance = l1Token.balanceOf(recipient); - assertBoolEq(false, l1Messenger.isL2MessageExecuted(keccak256(xDomainCalldata))); - l1Messenger.relayMessageWithProof(address(counterpartGateway), address(gateway), 0, 0, message, proof); - assertEq(recipient, l1Token.ownerOf(tokenId)); - assertEq(gatewayBalance - 1, l1Token.balanceOf(address(gateway))); - assertEq(recipientBalance + 1, l1Token.balanceOf(recipient)); - assertBoolEq(true, l1Messenger.isL2MessageExecuted(keccak256(xDomainCalldata))); - } - - function testFinalizeBatchWithdrawERC721FailedMocking( - address sender, - address recipient, - uint256 tokenCount - ) public { - tokenCount = bound(tokenCount, 1, TOKEN_COUNT); - uint256[] memory _tokenIds = new uint256[](tokenCount); - for (uint256 i = 0; i < tokenCount; i++) { - _tokenIds[i] = i; - } - - // revert when caller is not messenger - hevm.expectRevert(ErrorCallerIsNotMessenger.selector); - gateway.finalizeBatchWithdrawERC721(address(l1Token), address(l2Token), sender, recipient, _tokenIds); - - MockScrollMessenger mockMessenger = new MockScrollMessenger(); - gateway = _deployGateway(address(mockMessenger)); - gateway.initialize(address(counterpartGateway), address(mockMessenger)); - - // only call by counterpart - hevm.expectRevert(ErrorCallerIsNotCounterpartGateway.selector); - mockMessenger.callTarget( - address(gateway), - abi.encodeWithSelector( - gateway.finalizeBatchWithdrawERC721.selector, - address(l1Token), - address(l2Token), - sender, - recipient, - _tokenIds - ) - ); - - mockMessenger.setXDomainMessageSender(address(counterpartGateway)); - - // msg.value mismatch - hevm.expectRevert("l2 token mismatch"); - mockMessenger.callTarget( - address(gateway), - abi.encodeWithSelector( - gateway.finalizeBatchWithdrawERC721.selector, - address(l1Token), - address(l2Token), - sender, - recipient, - _tokenIds - ) - ); - } - - function testFinalizeBatchWithdrawERC721Failed( - address sender, - address recipient, - uint256 tokenCount - ) public { - hevm.assume(recipient != address(0)); - tokenCount = bound(tokenCount, 1, TOKEN_COUNT); - uint256[] memory _tokenIds = new uint256[](tokenCount); - for (uint256 i = 0; i < tokenCount; i++) { - _tokenIds[i] = i; - } - - gateway.updateTokenMapping(address(l1Token), address(l2Token)); - gateway.batchDepositERC721(address(l1Token), _tokenIds, defaultGasLimit); - - // do finalize withdraw token - bytes memory message = abi.encodeWithSelector( - IL1ERC721Gateway.finalizeBatchWithdrawERC721.selector, - address(l1Token), - address(l2Token), - sender, - recipient, - _tokenIds - ); - bytes memory xDomainCalldata = abi.encodeWithSignature( - "relayMessage(address,address,uint256,uint256,bytes)", - address(uint160(address(counterpartGateway)) + 1), - address(gateway), - 0, - 0, - message - ); - - prepareL2MessageRoot(keccak256(xDomainCalldata)); - - IL1ScrollMessenger.L2MessageProof memory proof; - proof.batchIndex = rollup.lastFinalizedBatchIndex(); - - // counterpart is not L2WETHGateway - // emit FailedRelayedMessage from L1ScrollMessenger - hevm.expectEmit(true, false, false, true); - emit FailedRelayedMessage(keccak256(xDomainCalldata)); - - for (uint256 i = 0; i < tokenCount; i++) { - assertEq(address(gateway), l1Token.ownerOf(_tokenIds[i])); - } - uint256 gatewayBalance = l1Token.balanceOf(address(gateway)); - uint256 recipientBalance = l1Token.balanceOf(recipient); - assertBoolEq(false, l1Messenger.isL2MessageExecuted(keccak256(xDomainCalldata))); - l1Messenger.relayMessageWithProof( - address(uint160(address(counterpartGateway)) + 1), - address(gateway), - 0, - 0, - message, - proof - ); - for (uint256 i = 0; i < tokenCount; i++) { - assertEq(address(gateway), l1Token.ownerOf(_tokenIds[i])); - } - assertEq(gatewayBalance, l1Token.balanceOf(address(gateway))); - assertEq(recipientBalance, l1Token.balanceOf(recipient)); - assertBoolEq(false, l1Messenger.isL2MessageExecuted(keccak256(xDomainCalldata))); - } - - function testFinalizeBatchWithdrawERC721( - address sender, - address recipient, - uint256 tokenCount - ) public { - uint256 size; - assembly { - size := extcodesize(recipient) - } - hevm.assume(size == 0); - hevm.assume(recipient != address(0)); - - tokenCount = bound(tokenCount, 1, TOKEN_COUNT); - uint256[] memory _tokenIds = new uint256[](tokenCount); - for (uint256 i = 0; i < tokenCount; i++) { - _tokenIds[i] = i; - } - - gateway.updateTokenMapping(address(l1Token), address(l2Token)); - gateway.batchDepositERC721(address(l1Token), _tokenIds, defaultGasLimit); - - // do finalize withdraw token - bytes memory message = abi.encodeWithSelector( - IL1ERC721Gateway.finalizeBatchWithdrawERC721.selector, - address(l1Token), - address(l2Token), - sender, - recipient, - _tokenIds - ); - bytes memory xDomainCalldata = abi.encodeWithSignature( - "relayMessage(address,address,uint256,uint256,bytes)", - address(counterpartGateway), - address(gateway), - 0, - 0, - message - ); - - prepareL2MessageRoot(keccak256(xDomainCalldata)); - - IL1ScrollMessenger.L2MessageProof memory proof; - proof.batchIndex = rollup.lastFinalizedBatchIndex(); - - // emit FinalizeBatchWithdrawERC721 from L1ERC721Gateway - { - hevm.expectEmit(true, true, true, true); - emit FinalizeBatchWithdrawERC721(address(l1Token), address(l2Token), sender, recipient, _tokenIds); - } - - // emit RelayedMessage from L1ScrollMessenger - { - hevm.expectEmit(true, false, false, true); - emit RelayedMessage(keccak256(xDomainCalldata)); - } - - for (uint256 i = 0; i < tokenCount; i++) { - assertEq(address(gateway), l1Token.ownerOf(_tokenIds[i])); - } - uint256 gatewayBalance = l1Token.balanceOf(address(gateway)); - uint256 recipientBalance = l1Token.balanceOf(recipient); - assertBoolEq(false, l1Messenger.isL2MessageExecuted(keccak256(xDomainCalldata))); - l1Messenger.relayMessageWithProof(address(counterpartGateway), address(gateway), 0, 0, message, proof); - for (uint256 i = 0; i < tokenCount; i++) { - assertEq(recipient, l1Token.ownerOf(_tokenIds[i])); - } - assertEq(gatewayBalance - tokenCount, l1Token.balanceOf(address(gateway))); - assertEq(recipientBalance + tokenCount, l1Token.balanceOf(recipient)); - assertBoolEq(true, l1Messenger.isL2MessageExecuted(keccak256(xDomainCalldata))); - } - - function testReentranceWhenFinalizeWithdraw(address from, uint256 tokenId) public { - tokenId = bound(tokenId, 0, TOKEN_COUNT - 1); - - MockScrollMessenger mockMessenger = new MockScrollMessenger(); - gateway = _deployGateway(address(mockMessenger)); - gateway.initialize(address(counterpartGateway), address(mockMessenger)); - l1Token.setApprovalForAll(address(gateway), true); - - // deposit first - gateway.updateTokenMapping(address(l1Token), address(l2Token)); - gateway.depositERC721(address(l1Token), tokenId, defaultGasLimit); - - mockRecipient.setCall( - address(gateway), - 0, - abi.encodeWithSignature( - "depositERC721(address,uint256,uint256)", - address(l1Token), - tokenId, - defaultGasLimit - ) - ); - // finalize withdraw - mockMessenger.setXDomainMessageSender(address(counterpartGateway)); - hevm.expectRevert("ReentrancyGuard: reentrant call"); - mockMessenger.callTarget( - address(gateway), - abi.encodeWithSelector( - L1ERC721Gateway.finalizeWithdrawERC721.selector, - address(l1Token), - address(l2Token), - from, - address(mockRecipient), - tokenId - ) - ); - - // finalize batch withdraw - mockMessenger.setXDomainMessageSender(address(counterpartGateway)); - hevm.expectRevert("ReentrancyGuard: reentrant call"); - uint256[] memory tokenIds = new uint256[](1); - tokenIds[0] = tokenId; - mockMessenger.callTarget( - address(gateway), - abi.encodeWithSelector( - L1ERC721Gateway.finalizeBatchWithdrawERC721.selector, - address(l1Token), - address(l2Token), - from, - address(mockRecipient), - tokenIds - ) - ); - } - - function _testDepositERC721( - uint256 tokenId, - uint256 gasLimit, - uint256 feePerGas - ) internal { - tokenId = bound(tokenId, 0, TOKEN_COUNT - 1); - gasLimit = bound(gasLimit, defaultGasLimit / 2, defaultGasLimit); - feePerGas = bound(feePerGas, 0, 1000); - - messageQueue.setL2BaseFee(feePerGas); - uint256 feeToPay = feePerGas * gasLimit; - - hevm.expectRevert("no corresponding l2 token"); - gateway.depositERC721(address(l1Token), tokenId, gasLimit); - - bytes memory message = abi.encodeWithSelector( - IL2ERC721Gateway.finalizeDepositERC721.selector, - address(l1Token), - address(l2Token), - address(this), - address(this), - tokenId - ); - bytes memory xDomainCalldata = abi.encodeWithSignature( - "relayMessage(address,address,uint256,uint256,bytes)", - address(gateway), - address(counterpartGateway), - 0, - 0, - message - ); - - gateway.updateTokenMapping(address(l1Token), address(l2Token)); - - // emit QueueTransaction from L1MessageQueue - { - hevm.expectEmit(true, true, false, true); - address sender = AddressAliasHelper.applyL1ToL2Alias(address(l1Messenger)); - emit QueueTransaction(sender, address(l2Messenger), 0, 0, gasLimit, xDomainCalldata); - } - - // emit SentMessage from L1ScrollMessenger - { - hevm.expectEmit(true, true, false, true); - emit SentMessage(address(gateway), address(counterpartGateway), 0, 0, gasLimit, message); - } - - // emit FinalizeWithdrawERC721 from L1ERC721Gateway - hevm.expectEmit(true, true, true, true); - emit DepositERC721(address(l1Token), address(l2Token), address(this), address(this), tokenId); - - assertEq(l1Token.ownerOf(tokenId), address(this)); - uint256 gatewayBalance = l1Token.balanceOf(address(gateway)); - uint256 feeVaultBalance = address(feeVault).balance; - assertEq(l1Messenger.messageSendTimestamp(keccak256(xDomainCalldata)), 0); - gateway.depositERC721{value: feeToPay + extraValue}(address(l1Token), tokenId, gasLimit); - assertEq(address(gateway), l1Token.ownerOf(tokenId)); - assertEq(1 + gatewayBalance, l1Token.balanceOf(address(gateway))); - assertEq(feeToPay + feeVaultBalance, address(feeVault).balance); - assertGt(l1Messenger.messageSendTimestamp(keccak256(xDomainCalldata)), 0); - } - - function _testDepositERC721WithRecipient( - uint256 tokenId, - address recipient, - uint256 gasLimit, - uint256 feePerGas - ) internal { - tokenId = bound(tokenId, 0, TOKEN_COUNT - 1); - gasLimit = bound(gasLimit, defaultGasLimit / 2, defaultGasLimit); - feePerGas = bound(feePerGas, 0, 1000); - - messageQueue.setL2BaseFee(feePerGas); - uint256 feeToPay = feePerGas * gasLimit; - - hevm.expectRevert("no corresponding l2 token"); - gateway.depositERC721(address(l1Token), tokenId, gasLimit); - - bytes memory message = abi.encodeWithSelector( - IL2ERC721Gateway.finalizeDepositERC721.selector, - address(l1Token), - address(l2Token), - address(this), - recipient, - tokenId - ); - bytes memory xDomainCalldata = abi.encodeWithSignature( - "relayMessage(address,address,uint256,uint256,bytes)", - address(gateway), - address(counterpartGateway), - 0, - 0, - message - ); - - gateway.updateTokenMapping(address(l1Token), address(l2Token)); - - // emit QueueTransaction from L1MessageQueue - { - hevm.expectEmit(true, true, false, true); - address sender = AddressAliasHelper.applyL1ToL2Alias(address(l1Messenger)); - emit QueueTransaction(sender, address(l2Messenger), 0, 0, gasLimit, xDomainCalldata); - } - - // emit SentMessage from L1ScrollMessenger - { - hevm.expectEmit(true, true, false, true); - emit SentMessage(address(gateway), address(counterpartGateway), 0, 0, gasLimit, message); - } - - // emit FinalizeWithdrawERC721 from L1ERC721Gateway - hevm.expectEmit(true, true, true, true); - emit DepositERC721(address(l1Token), address(l2Token), address(this), recipient, tokenId); - - assertEq(l1Token.ownerOf(tokenId), address(this)); - uint256 gatewayBalance = l1Token.balanceOf(address(gateway)); - uint256 feeVaultBalance = address(feeVault).balance; - assertEq(l1Messenger.messageSendTimestamp(keccak256(xDomainCalldata)), 0); - gateway.depositERC721{value: feeToPay + extraValue}(address(l1Token), recipient, tokenId, gasLimit); - assertEq(address(gateway), l1Token.ownerOf(tokenId)); - assertEq(1 + gatewayBalance, l1Token.balanceOf(address(gateway))); - assertEq(feeToPay + feeVaultBalance, address(feeVault).balance); - assertGt(l1Messenger.messageSendTimestamp(keccak256(xDomainCalldata)), 0); - } - - function _testBatchDepositERC721( - uint256 tokenCount, - uint256 gasLimit, - uint256 feePerGas - ) internal { - tokenCount = bound(tokenCount, 1, TOKEN_COUNT); - gasLimit = bound(gasLimit, defaultGasLimit / 2, defaultGasLimit); - feePerGas = bound(feePerGas, 0, 1000); - - messageQueue.setL2BaseFee(feePerGas); - uint256 feeToPay = feePerGas * gasLimit; - - uint256[] memory _tokenIds = new uint256[](tokenCount); - for (uint256 i = 0; i < tokenCount; i++) { - _tokenIds[i] = i; - } - - hevm.expectRevert("no token to deposit"); - gateway.batchDepositERC721(address(l1Token), new uint256[](0), gasLimit); - - hevm.expectRevert("no corresponding l2 token"); - gateway.batchDepositERC721(address(l1Token), _tokenIds, gasLimit); - - bytes memory message = abi.encodeWithSelector( - IL2ERC721Gateway.finalizeBatchDepositERC721.selector, - address(l1Token), - address(l2Token), - address(this), - address(this), - _tokenIds - ); - bytes memory xDomainCalldata = abi.encodeWithSignature( - "relayMessage(address,address,uint256,uint256,bytes)", - address(gateway), - address(counterpartGateway), - 0, - 0, - message - ); - - gateway.updateTokenMapping(address(l1Token), address(l2Token)); - - // emit QueueTransaction from L1MessageQueue - { - hevm.expectEmit(true, true, false, true); - address sender = AddressAliasHelper.applyL1ToL2Alias(address(l1Messenger)); - emit QueueTransaction(sender, address(l2Messenger), 0, 0, gasLimit, xDomainCalldata); - } - - // emit SentMessage from L1ScrollMessenger - { - hevm.expectEmit(true, true, false, true); - emit SentMessage(address(gateway), address(counterpartGateway), 0, 0, gasLimit, message); - } - - // emit FinalizeWithdrawERC721 from L1ERC721Gateway - hevm.expectEmit(true, true, true, true); - emit BatchDepositERC721(address(l1Token), address(l2Token), address(this), address(this), _tokenIds); - - for (uint256 i = 0; i < tokenCount; i++) { - assertEq(l1Token.ownerOf(i), address(this)); - } - uint256 gatewayBalance = l1Token.balanceOf(address(gateway)); - uint256 feeVaultBalance = address(feeVault).balance; - assertEq(l1Messenger.messageSendTimestamp(keccak256(xDomainCalldata)), 0); - gateway.batchDepositERC721{value: feeToPay + extraValue}(address(l1Token), _tokenIds, gasLimit); - for (uint256 i = 0; i < tokenCount; i++) { - assertEq(l1Token.ownerOf(i), address(gateway)); - } - assertEq(tokenCount + gatewayBalance, l1Token.balanceOf(address(gateway))); - assertEq(feeToPay + feeVaultBalance, address(feeVault).balance); - assertGt(l1Messenger.messageSendTimestamp(keccak256(xDomainCalldata)), 0); - } - - function _testBatchDepositERC721WithRecipient( - uint256 tokenCount, - address recipient, - uint256 gasLimit, - uint256 feePerGas - ) internal { - tokenCount = bound(tokenCount, 1, TOKEN_COUNT); - gasLimit = bound(gasLimit, defaultGasLimit / 2, defaultGasLimit); - feePerGas = bound(feePerGas, 0, 1000); - - messageQueue.setL2BaseFee(feePerGas); - uint256 feeToPay = feePerGas * gasLimit; - - uint256[] memory _tokenIds = new uint256[](tokenCount); - for (uint256 i = 0; i < tokenCount; i++) { - _tokenIds[i] = i; - } - - hevm.expectRevert("no token to deposit"); - gateway.batchDepositERC721(address(l1Token), recipient, new uint256[](0), gasLimit); - - hevm.expectRevert("no corresponding l2 token"); - gateway.batchDepositERC721(address(l1Token), recipient, _tokenIds, gasLimit); - - bytes memory message = abi.encodeWithSelector( - IL2ERC721Gateway.finalizeBatchDepositERC721.selector, - address(l1Token), - address(l2Token), - address(this), - recipient, - _tokenIds - ); - bytes memory xDomainCalldata = abi.encodeWithSignature( - "relayMessage(address,address,uint256,uint256,bytes)", - address(gateway), - address(counterpartGateway), - 0, - 0, - message - ); - - gateway.updateTokenMapping(address(l1Token), address(l2Token)); - - // emit QueueTransaction from L1MessageQueue - { - hevm.expectEmit(true, true, false, true); - address sender = AddressAliasHelper.applyL1ToL2Alias(address(l1Messenger)); - emit QueueTransaction(sender, address(l2Messenger), 0, 0, gasLimit, xDomainCalldata); - } - - // emit SentMessage from L1ScrollMessenger - { - hevm.expectEmit(true, true, false, true); - emit SentMessage(address(gateway), address(counterpartGateway), 0, 0, gasLimit, message); - } - - // emit FinalizeWithdrawERC721 from L1ERC721Gateway - hevm.expectEmit(true, true, true, true); - emit BatchDepositERC721(address(l1Token), address(l2Token), address(this), recipient, _tokenIds); - - for (uint256 i = 0; i < tokenCount; i++) { - assertEq(l1Token.ownerOf(i), address(this)); - } - uint256 gatewayBalance = l1Token.balanceOf(address(gateway)); - uint256 feeVaultBalance = address(feeVault).balance; - assertEq(l1Messenger.messageSendTimestamp(keccak256(xDomainCalldata)), 0); - gateway.batchDepositERC721{value: feeToPay + extraValue}(address(l1Token), recipient, _tokenIds, gasLimit); - for (uint256 i = 0; i < tokenCount; i++) { - assertEq(l1Token.ownerOf(i), address(gateway)); - } - assertEq(tokenCount + gatewayBalance, l1Token.balanceOf(address(gateway))); - assertEq(feeToPay + feeVaultBalance, address(feeVault).balance); - assertGt(l1Messenger.messageSendTimestamp(keccak256(xDomainCalldata)), 0); - } - - function _deployGateway(address messenger) internal returns (L1ERC721Gateway _gateway) { - _gateway = L1ERC721Gateway(_deployProxy(address(0))); - - admin.upgrade( - ITransparentUpgradeableProxy(address(_gateway)), - address(new L1ERC721Gateway(address(counterpartGateway), address(messenger))) - ); - } -} diff --git a/contracts/src/test/L1ETHGateway.t.sol b/contracts/src/test/L1ETHGateway.t.sol deleted file mode 100644 index d03dee7ad..000000000 --- a/contracts/src/test/L1ETHGateway.t.sol +++ /dev/null @@ -1,559 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {ITransparentUpgradeableProxy} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; - -import {L1GatewayRouter} from "../L1/gateways/L1GatewayRouter.sol"; -import {IL1ETHGateway, L1ETHGateway} from "../L1/gateways/L1ETHGateway.sol"; -import {IL1ScrollMessenger} from "../L1/IL1ScrollMessenger.sol"; -import {IL2ETHGateway, L2ETHGateway} from "../L2/gateways/L2ETHGateway.sol"; -import {AddressAliasHelper} from "../libraries/common/AddressAliasHelper.sol"; -import {ScrollConstants} from "../libraries/constants/ScrollConstants.sol"; - -import {L1GatewayTestBase} from "./L1GatewayTestBase.t.sol"; -import {MockScrollMessenger} from "./mocks/MockScrollMessenger.sol"; -import {MockGatewayRecipient} from "./mocks/MockGatewayRecipient.sol"; - -contract L1ETHGatewayTest is L1GatewayTestBase { - // from L1ETHGateway - event DepositETH(address indexed from, address indexed to, uint256 amount, bytes data); - event FinalizeWithdrawETH(address indexed from, address indexed to, uint256 amount, bytes data); - event RefundETH(address indexed recipient, uint256 amount); - - L1ETHGateway private gateway; - L1GatewayRouter private router; - - L2ETHGateway private counterpartGateway; - - function setUp() public { - __L1GatewayTestBase_setUp(); - - // Deploy L2 contracts - counterpartGateway = new L2ETHGateway(address(1), address(1), address(1)); - - // Deploy L1 contracts - router = L1GatewayRouter(_deployProxy(address(new L1GatewayRouter()))); - gateway = _deployGateway(address(l1Messenger)); - - // Initialize L1 contracts - gateway.initialize(address(counterpartGateway), address(router), address(l1Messenger)); - router.initialize(address(gateway), address(0)); - } - - function testInitialized() public { - assertEq(address(counterpartGateway), gateway.counterpart()); - assertEq(address(router), gateway.router()); - assertEq(address(l1Messenger), gateway.messenger()); - - hevm.expectRevert("Initializable: contract is already initialized"); - gateway.initialize(address(counterpartGateway), address(router), address(l1Messenger)); - } - - function testDepositETH( - uint256 amount, - uint256 gasLimit, - uint256 feePerGas - ) public { - _depositETH(false, amount, gasLimit, feePerGas); - } - - function testDepositETHWithRecipient( - uint256 amount, - address recipient, - uint256 gasLimit, - uint256 feePerGas - ) public { - _depositETHWithRecipient(false, amount, recipient, gasLimit, feePerGas); - } - - function testDepositETHWithRecipientAndCalldata( - uint256 amount, - address recipient, - bytes memory dataToCall, - uint256 gasLimit, - uint256 feePerGas - ) public { - _depositETHWithRecipientAndCalldata(false, amount, recipient, dataToCall, gasLimit, feePerGas); - } - - function testRouterDepositETH( - uint256 amount, - uint256 gasLimit, - uint256 feePerGas - ) public { - _depositETH(true, amount, gasLimit, feePerGas); - } - - function testRouterDepositETHWithRecipient( - uint256 amount, - address recipient, - uint256 gasLimit, - uint256 feePerGas - ) public { - _depositETHWithRecipient(true, amount, recipient, gasLimit, feePerGas); - } - - function testRouterDepositETHWithRecipientAndCalldata( - uint256 amount, - address recipient, - bytes memory dataToCall, - uint256 gasLimit, - uint256 feePerGas - ) public { - _depositETHWithRecipientAndCalldata(true, amount, recipient, dataToCall, gasLimit, feePerGas); - } - - function testDropMessageMocking() public { - MockScrollMessenger mockMessenger = new MockScrollMessenger(); - gateway = _deployGateway(address(mockMessenger)); - gateway.initialize(address(counterpartGateway), address(router), address(mockMessenger)); - - // only messenger can call, revert - hevm.expectRevert(ErrorCallerIsNotMessenger.selector); - gateway.onDropMessage(new bytes(0)); - - // only called in drop context, revert - hevm.expectRevert(ErrorNotInDropMessageContext.selector); - mockMessenger.callTarget( - address(gateway), - abi.encodeWithSelector(gateway.onDropMessage.selector, new bytes(0)) - ); - - mockMessenger.setXDomainMessageSender(ScrollConstants.DROP_XDOMAIN_MESSAGE_SENDER); - - // invalid selector, revert - hevm.expectRevert("invalid selector"); - mockMessenger.callTarget( - address(gateway), - abi.encodeWithSelector(gateway.onDropMessage.selector, new bytes(4)) - ); - - bytes memory message = abi.encodeWithSelector( - IL2ETHGateway.finalizeDepositETH.selector, - address(this), - address(this), - 100, - new bytes(0) - ); - - // msg.value mismatch, revert - hevm.expectRevert("msg.value mismatch"); - mockMessenger.callTarget{value: 99}( - address(gateway), - abi.encodeWithSelector(gateway.onDropMessage.selector, message) - ); - } - - function testDropMessage( - uint256 amount, - address recipient, - bytes memory dataToCall - ) public { - amount = bound(amount, 1, address(this).balance); - bytes memory message = abi.encodeWithSelector( - IL2ETHGateway.finalizeDepositETH.selector, - address(this), - recipient, - amount, - dataToCall - ); - gateway.depositETHAndCall{value: amount}(recipient, amount, dataToCall, defaultGasLimit); - - // skip message 0 - hevm.startPrank(address(rollup)); - messageQueue.popCrossDomainMessage(0, 1, 0x1); - assertEq(messageQueue.pendingQueueIndex(), 1); - hevm.stopPrank(); - - // ETH transfer failed, revert - revertOnReceive = true; - hevm.expectRevert("ETH transfer failed"); - l1Messenger.dropMessage(address(gateway), address(counterpartGateway), amount, 0, message); - - // drop message 0 - hevm.expectEmit(true, true, false, true); - emit RefundETH(address(this), amount); - - revertOnReceive = false; - uint256 balance = address(this).balance; - l1Messenger.dropMessage(address(gateway), address(counterpartGateway), amount, 0, message); - assertEq(balance + amount, address(this).balance); - } - - function testFinalizeWithdrawETHFailedMocking( - address sender, - address recipient, - uint256 amount, - bytes memory dataToCall - ) public { - amount = bound(amount, 1, address(this).balance / 2); - - // revert when caller is not messenger - hevm.expectRevert(ErrorCallerIsNotMessenger.selector); - gateway.finalizeWithdrawETH(sender, recipient, amount, dataToCall); - - MockScrollMessenger mockMessenger = new MockScrollMessenger(); - gateway = _deployGateway(address(mockMessenger)); - gateway.initialize(address(counterpartGateway), address(router), address(mockMessenger)); - - // only call by counterpart - hevm.expectRevert(ErrorCallerIsNotCounterpartGateway.selector); - mockMessenger.callTarget( - address(gateway), - abi.encodeWithSelector(gateway.finalizeWithdrawETH.selector, sender, recipient, amount, dataToCall) - ); - - mockMessenger.setXDomainMessageSender(address(counterpartGateway)); - - // msg.value mismatch - hevm.expectRevert("msg.value mismatch"); - mockMessenger.callTarget( - address(gateway), - abi.encodeWithSelector(gateway.finalizeWithdrawETH.selector, sender, recipient, amount, dataToCall) - ); - - // ETH transfer failed - revertOnReceive = true; - hevm.expectRevert("ETH transfer failed"); - mockMessenger.callTarget{value: amount}( - address(gateway), - abi.encodeWithSelector(gateway.finalizeWithdrawETH.selector, sender, address(this), amount, dataToCall) - ); - } - - function testFinalizeWithdrawETHFailed( - address sender, - address recipient, - uint256 amount, - bytes memory dataToCall - ) public { - amount = bound(amount, 1, address(this).balance / 2); - - // deposit some ETH to L1ScrollMessenger - gateway.depositETH{value: amount}(amount, defaultGasLimit); - - // do finalize withdraw eth - bytes memory message = abi.encodeWithSelector( - IL1ETHGateway.finalizeWithdrawETH.selector, - sender, - recipient, - amount, - dataToCall - ); - bytes memory xDomainCalldata = abi.encodeWithSignature( - "relayMessage(address,address,uint256,uint256,bytes)", - address(uint160(address(counterpartGateway)) + 1), - address(gateway), - amount, - 0, - message - ); - - prepareL2MessageRoot(keccak256(xDomainCalldata)); - - IL1ScrollMessenger.L2MessageProof memory proof; - proof.batchIndex = rollup.lastFinalizedBatchIndex(); - - // counterpart is not L2ETHGateway - // emit FailedRelayedMessage from L1ScrollMessenger - hevm.expectEmit(true, false, false, true); - emit FailedRelayedMessage(keccak256(xDomainCalldata)); - - uint256 messengerBalance = address(l1Messenger).balance; - uint256 recipientBalance = recipient.balance; - assertBoolEq(false, l1Messenger.isL2MessageExecuted(keccak256(xDomainCalldata))); - l1Messenger.relayMessageWithProof( - address(uint160(address(counterpartGateway)) + 1), - address(gateway), - amount, - 0, - message, - proof - ); - assertEq(messengerBalance, address(l1Messenger).balance); - assertEq(recipientBalance, recipient.balance); - assertBoolEq(false, l1Messenger.isL2MessageExecuted(keccak256(xDomainCalldata))); - } - - function testFinalizeWithdrawETH( - address sender, - uint256 amount, - bytes memory dataToCall - ) public { - MockGatewayRecipient recipient = new MockGatewayRecipient(); - - amount = bound(amount, 1, address(this).balance / 2); - - // deposit some ETH to L1ScrollMessenger - gateway.depositETH{value: amount}(amount, defaultGasLimit); - - // do finalize withdraw eth - bytes memory message = abi.encodeWithSelector( - IL1ETHGateway.finalizeWithdrawETH.selector, - sender, - address(recipient), - amount, - dataToCall - ); - bytes memory xDomainCalldata = abi.encodeWithSignature( - "relayMessage(address,address,uint256,uint256,bytes)", - address(counterpartGateway), - address(gateway), - amount, - 0, - message - ); - - prepareL2MessageRoot(keccak256(xDomainCalldata)); - - IL1ScrollMessenger.L2MessageProof memory proof; - proof.batchIndex = rollup.lastFinalizedBatchIndex(); - - // emit FinalizeWithdrawETH from L1ETHGateway - { - hevm.expectEmit(true, true, false, true); - emit FinalizeWithdrawETH(sender, address(recipient), amount, dataToCall); - } - - // emit RelayedMessage from L1ScrollMessenger - { - hevm.expectEmit(true, false, false, true); - emit RelayedMessage(keccak256(xDomainCalldata)); - } - - uint256 messengerBalance = address(l1Messenger).balance; - uint256 recipientBalance = address(recipient).balance; - assertBoolEq(false, l1Messenger.isL2MessageExecuted(keccak256(xDomainCalldata))); - l1Messenger.relayMessageWithProof(address(counterpartGateway), address(gateway), amount, 0, message, proof); - assertEq(messengerBalance - amount, address(l1Messenger).balance); - assertEq(recipientBalance + amount, address(recipient).balance); - assertBoolEq(true, l1Messenger.isL2MessageExecuted(keccak256(xDomainCalldata))); - } - - function _depositETH( - bool useRouter, - uint256 amount, - uint256 gasLimit, - uint256 feePerGas - ) private { - amount = bound(amount, 0, address(this).balance / 2); - gasLimit = bound(gasLimit, defaultGasLimit / 2, defaultGasLimit); - feePerGas = bound(feePerGas, 0, 1000); - - messageQueue.setL2BaseFee(feePerGas); - - uint256 feeToPay = feePerGas * gasLimit; - bytes memory message = abi.encodeWithSelector( - IL2ETHGateway.finalizeDepositETH.selector, - address(this), - address(this), - amount, - new bytes(0) - ); - bytes memory xDomainCalldata = abi.encodeWithSignature( - "relayMessage(address,address,uint256,uint256,bytes)", - address(gateway), - address(counterpartGateway), - amount, - 0, - message - ); - - if (amount == 0) { - hevm.expectRevert("deposit zero eth"); - if (useRouter) { - router.depositETH{value: amount}(amount, gasLimit); - } else { - gateway.depositETH{value: amount}(amount, gasLimit); - } - } else { - // emit QueueTransaction from L1MessageQueue - { - hevm.expectEmit(true, true, false, true); - address sender = AddressAliasHelper.applyL1ToL2Alias(address(l1Messenger)); - emit QueueTransaction(sender, address(l2Messenger), 0, 0, gasLimit, xDomainCalldata); - } - - // emit SentMessage from L1ScrollMessenger - { - hevm.expectEmit(true, true, false, true); - emit SentMessage(address(gateway), address(counterpartGateway), amount, 0, gasLimit, message); - } - - // emit DepositETH from L1ETHGateway - hevm.expectEmit(true, true, false, true); - emit DepositETH(address(this), address(this), amount, new bytes(0)); - - uint256 messengerBalance = address(l1Messenger).balance; - uint256 feeVaultBalance = address(feeVault).balance; - assertEq(l1Messenger.messageSendTimestamp(keccak256(xDomainCalldata)), 0); - if (useRouter) { - router.depositETH{value: amount + feeToPay + extraValue}(amount, gasLimit); - } else { - gateway.depositETH{value: amount + feeToPay + extraValue}(amount, gasLimit); - } - assertEq(amount + messengerBalance, address(l1Messenger).balance); - assertEq(feeToPay + feeVaultBalance, address(feeVault).balance); - assertGt(l1Messenger.messageSendTimestamp(keccak256(xDomainCalldata)), 0); - } - } - - function _depositETHWithRecipient( - bool useRouter, - uint256 amount, - address recipient, - uint256 gasLimit, - uint256 feePerGas - ) private { - amount = bound(amount, 0, address(this).balance / 2); - gasLimit = bound(gasLimit, defaultGasLimit / 2, defaultGasLimit); - feePerGas = bound(feePerGas, 0, 1000); - - messageQueue.setL2BaseFee(feePerGas); - - uint256 feeToPay = feePerGas * gasLimit; - bytes memory message = abi.encodeWithSelector( - IL2ETHGateway.finalizeDepositETH.selector, - address(this), - recipient, - amount, - new bytes(0) - ); - bytes memory xDomainCalldata = abi.encodeWithSignature( - "relayMessage(address,address,uint256,uint256,bytes)", - address(gateway), - address(counterpartGateway), - amount, - 0, - message - ); - - if (amount == 0) { - hevm.expectRevert("deposit zero eth"); - if (useRouter) { - router.depositETH{value: amount}(recipient, amount, gasLimit); - } else { - gateway.depositETH{value: amount}(recipient, amount, gasLimit); - } - } else { - // emit QueueTransaction from L1MessageQueue - { - hevm.expectEmit(true, true, false, true); - address sender = AddressAliasHelper.applyL1ToL2Alias(address(l1Messenger)); - emit QueueTransaction(sender, address(l2Messenger), 0, 0, gasLimit, xDomainCalldata); - } - - // emit SentMessage from L1ScrollMessenger - { - hevm.expectEmit(true, true, false, true); - emit SentMessage(address(gateway), address(counterpartGateway), amount, 0, gasLimit, message); - } - - // emit DepositETH from L1ETHGateway - hevm.expectEmit(true, true, false, true); - emit DepositETH(address(this), recipient, amount, new bytes(0)); - - uint256 messengerBalance = address(l1Messenger).balance; - uint256 feeVaultBalance = address(feeVault).balance; - assertEq(l1Messenger.messageSendTimestamp(keccak256(xDomainCalldata)), 0); - if (useRouter) { - router.depositETH{value: amount + feeToPay + extraValue}(recipient, amount, gasLimit); - } else { - gateway.depositETH{value: amount + feeToPay + extraValue}(recipient, amount, gasLimit); - } - assertEq(amount + messengerBalance, address(l1Messenger).balance); - assertEq(feeToPay + feeVaultBalance, address(feeVault).balance); - assertGt(l1Messenger.messageSendTimestamp(keccak256(xDomainCalldata)), 0); - } - } - - function _depositETHWithRecipientAndCalldata( - bool useRouter, - uint256 amount, - address recipient, - bytes memory dataToCall, - uint256 gasLimit, - uint256 feePerGas - ) private { - amount = bound(amount, 0, address(this).balance / 2); - gasLimit = bound(gasLimit, defaultGasLimit / 2, defaultGasLimit); - feePerGas = bound(feePerGas, 0, 1000); - - messageQueue.setL2BaseFee(feePerGas); - - uint256 feeToPay = feePerGas * gasLimit; - bytes memory message = abi.encodeWithSelector( - IL2ETHGateway.finalizeDepositETH.selector, - address(this), - recipient, - amount, - dataToCall - ); - bytes memory xDomainCalldata = abi.encodeWithSignature( - "relayMessage(address,address,uint256,uint256,bytes)", - address(gateway), - address(counterpartGateway), - amount, - 0, - message - ); - - if (amount == 0) { - hevm.expectRevert("deposit zero eth"); - if (useRouter) { - router.depositETHAndCall{value: amount}(recipient, amount, dataToCall, gasLimit); - } else { - gateway.depositETHAndCall{value: amount}(recipient, amount, dataToCall, gasLimit); - } - } else { - // emit QueueTransaction from L1MessageQueue - { - hevm.expectEmit(true, true, false, true); - address sender = AddressAliasHelper.applyL1ToL2Alias(address(l1Messenger)); - emit QueueTransaction(sender, address(l2Messenger), 0, 0, gasLimit, xDomainCalldata); - } - - // emit SentMessage from L1ScrollMessenger - { - hevm.expectEmit(true, true, false, true); - emit SentMessage(address(gateway), address(counterpartGateway), amount, 0, gasLimit, message); - } - - // emit DepositETH from L1ETHGateway - hevm.expectEmit(true, true, false, true); - emit DepositETH(address(this), recipient, amount, dataToCall); - - uint256 messengerBalance = address(l1Messenger).balance; - uint256 feeVaultBalance = address(feeVault).balance; - assertEq(l1Messenger.messageSendTimestamp(keccak256(xDomainCalldata)), 0); - if (useRouter) { - router.depositETHAndCall{value: amount + feeToPay + extraValue}( - recipient, - amount, - dataToCall, - gasLimit - ); - } else { - gateway.depositETHAndCall{value: amount + feeToPay + extraValue}( - recipient, - amount, - dataToCall, - gasLimit - ); - } - assertEq(amount + messengerBalance, address(l1Messenger).balance); - assertEq(feeToPay + feeVaultBalance, address(feeVault).balance); - assertGt(l1Messenger.messageSendTimestamp(keccak256(xDomainCalldata)), 0); - } - } - - function _deployGateway(address messenger) internal returns (L1ETHGateway _gateway) { - _gateway = L1ETHGateway(_deployProxy(address(0))); - - admin.upgrade( - ITransparentUpgradeableProxy(address(_gateway)), - address(new L1ETHGateway(address(counterpartGateway), address(router), address(messenger))) - ); - } -} diff --git a/contracts/src/test/L1GasPriceOracle.t.sol b/contracts/src/test/L1GasPriceOracle.t.sol deleted file mode 100644 index d6b4c834b..000000000 --- a/contracts/src/test/L1GasPriceOracle.t.sol +++ /dev/null @@ -1,235 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {DSTestPlus} from "solmate/test/utils/DSTestPlus.sol"; - -import {L1GasPriceOracle} from "../L2/predeploys/L1GasPriceOracle.sol"; -import {Whitelist} from "../L2/predeploys/Whitelist.sol"; - -contract L1GasPriceOracleTest is DSTestPlus { - uint256 private constant PRECISION = 1e9; - uint256 private constant MAX_OVERHEAD = 30000000 / 16; - uint256 private constant MAX_SCALAR = 1000 * PRECISION; - uint256 private constant MAX_COMMIT_SCALAR = 10 ** 9 * PRECISION; - uint256 private constant MAX_BLOB_SCALAR = 10 ** 9 * PRECISION; - - L1GasPriceOracle private oracle; - Whitelist private whitelist; - - function setUp() public { - whitelist = new Whitelist(address(this)); - oracle = new L1GasPriceOracle(address(this)); - oracle.updateWhitelist(address(whitelist)); - - address[] memory _accounts = new address[](1); - _accounts[0] = address(this); - whitelist.updateWhitelistStatus(_accounts, true); - } - - function testSetOverhead(uint256 _overhead) external { - _overhead = bound(_overhead, 0, MAX_OVERHEAD); - - // call by non-owner, should revert - hevm.startPrank(address(1)); - hevm.expectRevert("caller is not the owner"); - oracle.setOverhead(_overhead); - hevm.stopPrank(); - - // overhead is too large - hevm.expectRevert(L1GasPriceOracle.ErrExceedMaxOverhead.selector); - oracle.setOverhead(MAX_OVERHEAD + 1); - - // call by owner, should succeed - assertEq(oracle.overhead(), 0); - oracle.setOverhead(_overhead); - assertEq(oracle.overhead(), _overhead); - } - - function testSetScalar(uint256 _scalar) external { - _scalar = bound(_scalar, 0, MAX_SCALAR); - - // call by non-owner, should revert - hevm.startPrank(address(1)); - hevm.expectRevert("caller is not the owner"); - oracle.setScalar(_scalar); - hevm.stopPrank(); - - // scale is too large - hevm.expectRevert(L1GasPriceOracle.ErrExceedMaxScalar.selector); - oracle.setScalar(MAX_SCALAR + 1); - - // call by owner, should succeed - assertEq(oracle.scalar(), 0); - oracle.setScalar(_scalar); - assertEq(oracle.scalar(), _scalar); - } - - function testSetCommitScalar(uint256 _scalar) external { - _scalar = bound(_scalar, 0, MAX_COMMIT_SCALAR); - - // call by non-owner, should revert - hevm.startPrank(address(1)); - hevm.expectRevert("caller is not the owner"); - oracle.setCommitScalar(_scalar); - hevm.stopPrank(); - - // scale is too large - hevm.expectRevert(L1GasPriceOracle.ErrExceedMaxCommitScalar.selector); - oracle.setCommitScalar(MAX_COMMIT_SCALAR + 1); - - // call by owner, should succeed - assertEq(oracle.commitScalar(), 0); - oracle.setCommitScalar(_scalar); - assertEq(oracle.commitScalar(), _scalar); - } - - function testSetBlobScalar(uint256 _scalar) external { - _scalar = bound(_scalar, 0, MAX_BLOB_SCALAR); - - // call by non-owner, should revert - hevm.startPrank(address(1)); - hevm.expectRevert("caller is not the owner"); - oracle.setBlobScalar(_scalar); - hevm.stopPrank(); - - // scale is too large - hevm.expectRevert(L1GasPriceOracle.ErrExceedMaxBlobScalar.selector); - oracle.setBlobScalar(MAX_COMMIT_SCALAR + 1); - - // call by owner, should succeed - assertEq(oracle.blobScalar(), 0); - oracle.setBlobScalar(_scalar); - assertEq(oracle.blobScalar(), _scalar); - } - - function testUpdateWhitelist(address _newWhitelist) external { - hevm.assume(_newWhitelist != address(whitelist)); - - // call by non-owner, should revert - hevm.startPrank(address(1)); - hevm.expectRevert("caller is not the owner"); - oracle.updateWhitelist(_newWhitelist); - hevm.stopPrank(); - - // call by owner, should succeed - assertEq(address(oracle.whitelist()), address(whitelist)); - oracle.updateWhitelist(_newWhitelist); - assertEq(address(oracle.whitelist()), _newWhitelist); - } - - function testEnableCurie() external { - // call by non-owner, should revert - hevm.startPrank(address(1)); - hevm.expectRevert("caller is not the owner"); - oracle.enableCurie(); - hevm.stopPrank(); - - // call by owner, should succeed - assertBoolEq(oracle.isCurie(), false); - oracle.enableCurie(); - assertBoolEq(oracle.isCurie(), true); - - // enable twice, should revert - hevm.expectRevert(L1GasPriceOracle.ErrAlreadyInCurieFork.selector); - oracle.enableCurie(); - } - - function testSetL1BaseFee(uint256 _baseFee) external { - _baseFee = bound(_baseFee, 0, 1e9 * 20000); // max 20k gwei - - // call by non-owner, should revert - hevm.startPrank(address(1)); - hevm.expectRevert(L1GasPriceOracle.ErrCallerNotWhitelisted.selector); - oracle.setL1BaseFee(_baseFee); - hevm.stopPrank(); - - // call by owner, should succeed - assertEq(oracle.l1BaseFee(), 0); - oracle.setL1BaseFee(_baseFee); - assertEq(oracle.l1BaseFee(), _baseFee); - } - - function testSetL1BaseFeeAndBlobBaseFee(uint256 _baseFee, uint256 _blobBaseFee) external { - _baseFee = bound(_baseFee, 0, 1e9 * 20000); // max 20k gwei - _blobBaseFee = bound(_blobBaseFee, 0, 1e9 * 20000); // max 20k gwei - - // call by non-owner, should revert - hevm.startPrank(address(1)); - hevm.expectRevert(L1GasPriceOracle.ErrCallerNotWhitelisted.selector); - oracle.setL1BaseFeeAndBlobBaseFee(_baseFee, _blobBaseFee); - hevm.stopPrank(); - - // call by owner, should succeed - assertEq(oracle.l1BaseFee(), 0); - assertEq(oracle.l1BlobBaseFee(), 0); - oracle.setL1BaseFeeAndBlobBaseFee(_baseFee, _blobBaseFee); - assertEq(oracle.l1BaseFee(), _baseFee); - assertEq(oracle.l1BlobBaseFee(), _blobBaseFee); - } - - function testGetL1GasUsedBeforeCurie(uint256 _overhead, bytes memory _data) external { - _overhead = bound(_overhead, 0, MAX_OVERHEAD); - - oracle.setOverhead(_overhead); - - uint256 _gasUsed = _overhead + 4 * 16; - for (uint256 i = 0; i < _data.length; i++) { - if (_data[i] == 0) _gasUsed += 4; - else _gasUsed += 16; - } - - assertEq(oracle.getL1GasUsed(_data), _gasUsed); - } - - function testGetL1FeeBeforeCurie( - uint256 _baseFee, - uint256 _overhead, - uint256 _scalar, - bytes memory _data - ) external { - _overhead = bound(_overhead, 0, MAX_OVERHEAD); - _scalar = bound(_scalar, 0, MAX_SCALAR); - _baseFee = bound(_baseFee, 0, 1e9 * 20000); // max 20k gwei - - oracle.setOverhead(_overhead); - oracle.setScalar(_scalar); - oracle.setL1BaseFee(_baseFee); - - uint256 _gasUsed = _overhead + 4 * 16; - for (uint256 i = 0; i < _data.length; i++) { - if (_data[i] == 0) _gasUsed += 4; - else _gasUsed += 16; - } - - assertEq(oracle.getL1Fee(_data), (_gasUsed * _baseFee * _scalar) / PRECISION); - } - - function testGetL1GasUsedCurie(bytes memory _data) external { - oracle.enableCurie(); - assertEq(oracle.getL1GasUsed(_data), 0); - } - - function testGetL1FeeCurie( - uint256 _baseFee, - uint256 _blobBaseFee, - uint256 _commitScalar, - uint256 _blobScalar, - bytes memory _data - ) external { - _baseFee = bound(_baseFee, 0, 1e9 * 20000); // max 20k gwei - _blobBaseFee = bound(_blobBaseFee, 0, 1e9 * 20000); // max 20k gwei - _commitScalar = bound(_commitScalar, 0, MAX_COMMIT_SCALAR); - _blobScalar = bound(_blobScalar, 0, MAX_BLOB_SCALAR); - - oracle.enableCurie(); - oracle.setCommitScalar(_commitScalar); - oracle.setBlobScalar(_blobScalar); - oracle.setL1BaseFeeAndBlobBaseFee(_baseFee, _blobBaseFee); - - assertEq( - oracle.getL1Fee(_data), - (_commitScalar * _baseFee + _blobScalar * _blobBaseFee * _data.length) / PRECISION - ); - } -} diff --git a/contracts/src/test/L1GatewayRouter.t.sol b/contracts/src/test/L1GatewayRouter.t.sol deleted file mode 100644 index cb2460ade..000000000 --- a/contracts/src/test/L1GatewayRouter.t.sol +++ /dev/null @@ -1,201 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {MockERC20} from "solmate/test/utils/mocks/MockERC20.sol"; - -import {ITransparentUpgradeableProxy} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; - -import {L1ETHGateway} from "../L1/gateways/L1ETHGateway.sol"; -import {L1GatewayRouter} from "../L1/gateways/L1GatewayRouter.sol"; -import {L1StandardERC20Gateway} from "../L1/gateways/L1StandardERC20Gateway.sol"; -import {L2ETHGateway} from "../L2/gateways/L2ETHGateway.sol"; -import {L2StandardERC20Gateway} from "../L2/gateways/L2StandardERC20Gateway.sol"; -import {ScrollStandardERC20} from "../libraries/token/ScrollStandardERC20.sol"; -import {ScrollStandardERC20Factory} from "../libraries/token/ScrollStandardERC20Factory.sol"; - -import {L1GatewayTestBase} from "./L1GatewayTestBase.t.sol"; - -import {TransferReentrantToken} from "./mocks/tokens/TransferReentrantToken.sol"; - -contract L1GatewayRouterTest is L1GatewayTestBase { - // from L1GatewayRouter - event SetETHGateway(address indexed oldETHGateway, address indexed newEthGateway); - event SetDefaultERC20Gateway(address indexed oldDefaultERC20Gateway, address indexed newDefaultERC20Gateway); - event SetERC20Gateway(address indexed token, address indexed oldGateway, address indexed newGateway); - - ScrollStandardERC20 private template; - ScrollStandardERC20Factory private factory; - - L1StandardERC20Gateway private l1StandardERC20Gateway; - L2StandardERC20Gateway private l2StandardERC20Gateway; - - L1ETHGateway private l1ETHGateway; - L2ETHGateway private l2ETHGateway; - - L1GatewayRouter private router; - MockERC20 private l1Token; - - function setUp() public { - __L1GatewayTestBase_setUp(); - - // Deploy tokens - l1Token = new MockERC20("Mock", "M", 18); - - // Deploy L2 contracts - template = new ScrollStandardERC20(); - factory = new ScrollStandardERC20Factory(address(template)); - l2StandardERC20Gateway = new L2StandardERC20Gateway(address(1), address(1), address(1), address(factory)); - l2ETHGateway = new L2ETHGateway(address(1), address(1), address(1)); - - // Deploy L1 contracts - l1StandardERC20Gateway = L1StandardERC20Gateway(_deployProxy(address(0))); - l1ETHGateway = L1ETHGateway(_deployProxy(address(0))); - router = L1GatewayRouter(_deployProxy(address(new L1GatewayRouter()))); - admin.upgrade( - ITransparentUpgradeableProxy(address(l1StandardERC20Gateway)), - address( - new L1StandardERC20Gateway( - address(l2StandardERC20Gateway), - address(router), - address(l1Messenger), - address(template), - address(factory) - ) - ) - ); - admin.upgrade( - ITransparentUpgradeableProxy(address(l1ETHGateway)), - address(new L1ETHGateway(address(l2ETHGateway), address(router), address(l1Messenger))) - ); - - // Initialize L1 contracts - l1StandardERC20Gateway.initialize( - address(l2StandardERC20Gateway), - address(router), - address(l1Messenger), - address(template), - address(factory) - ); - l1ETHGateway.initialize(address(l2ETHGateway), address(router), address(l1Messenger)); - router.initialize(address(l1ETHGateway), address(l1StandardERC20Gateway)); - } - - function testOwnership() public { - assertEq(address(this), router.owner()); - } - - function testInitialized() public { - assertEq(address(l1StandardERC20Gateway), router.defaultERC20Gateway()); - assertEq( - factory.computeL2TokenAddress(address(l2StandardERC20Gateway), address(l1Token)), - router.getL2ERC20Address(address(l1Token)) - ); - assertEq(address(l1StandardERC20Gateway), router.getERC20Gateway(address(l1Token))); - - hevm.expectRevert("Initializable: contract is already initialized"); - router.initialize(address(l1ETHGateway), address(l1StandardERC20Gateway)); - } - - function testSetDefaultERC20Gateway() public { - router.setDefaultERC20Gateway(address(0)); - - // set by non-owner, should revert - hevm.startPrank(address(1)); - hevm.expectRevert("Ownable: caller is not the owner"); - router.setDefaultERC20Gateway(address(l1StandardERC20Gateway)); - hevm.stopPrank(); - - // set by owner, should succeed - hevm.expectEmit(true, true, false, true); - emit SetDefaultERC20Gateway(address(0), address(l1StandardERC20Gateway)); - - assertEq(address(0), router.getERC20Gateway(address(l1Token))); - assertEq(address(0), router.defaultERC20Gateway()); - router.setDefaultERC20Gateway(address(l1StandardERC20Gateway)); - assertEq(address(l1StandardERC20Gateway), router.getERC20Gateway(address(l1Token))); - assertEq(address(l1StandardERC20Gateway), router.defaultERC20Gateway()); - } - - function testSetERC20Gateway() public { - router.setDefaultERC20Gateway(address(0)); - - // length mismatch, should revert - address[] memory empty = new address[](0); - address[] memory single = new address[](1); - hevm.expectRevert("length mismatch"); - router.setERC20Gateway(empty, single); - hevm.expectRevert("length mismatch"); - router.setERC20Gateway(single, empty); - - // set by owner, should succeed - address[] memory _tokens = new address[](1); - address[] memory _gateways = new address[](1); - _tokens[0] = address(l1Token); - _gateways[0] = address(l1StandardERC20Gateway); - - hevm.expectEmit(true, true, true, true); - emit SetERC20Gateway(address(l1Token), address(0), address(l1StandardERC20Gateway)); - - assertEq(address(0), router.getERC20Gateway(address(l1Token))); - router.setERC20Gateway(_tokens, _gateways); - assertEq(address(l1StandardERC20Gateway), router.getERC20Gateway(address(l1Token))); - } - - function testFinalizeWithdrawERC20() public { - hevm.expectRevert("should never be called"); - router.finalizeWithdrawERC20(address(0), address(0), address(0), address(0), 0, ""); - } - - function testFinalizeWithdrawETH() public { - hevm.expectRevert("should never be called"); - router.finalizeWithdrawETH(address(0), address(0), 0, ""); - } - - function testRequestERC20( - address _sender, - address _token, - uint256 _amount - ) public { - hevm.expectRevert("Only in deposit context"); - router.requestERC20(_sender, _token, _amount); - } - - function testReentrant() public { - TransferReentrantToken reentrantToken = new TransferReentrantToken("Reentrant", "R", 18); - reentrantToken.mint(address(this), type(uint128).max); - reentrantToken.approve(address(router), type(uint256).max); - - reentrantToken.setReentrantCall( - address(router), - 0, - abi.encodeWithSelector( - router.depositERC20AndCall.selector, - address(reentrantToken), - address(this), - 0, - new bytes(0), - 0 - ), - true - ); - hevm.expectRevert("Only not in context"); - router.depositERC20(address(reentrantToken), 1, 0); - - reentrantToken.setReentrantCall( - address(router), - 0, - abi.encodeWithSelector( - router.depositERC20AndCall.selector, - address(reentrantToken), - address(this), - 0, - new bytes(0), - 0 - ), - false - ); - hevm.expectRevert("Only not in context"); - router.depositERC20(address(reentrantToken), 1, 0); - } -} diff --git a/contracts/src/test/L1GatewayTestBase.t.sol b/contracts/src/test/L1GatewayTestBase.t.sol deleted file mode 100644 index a47b59459..000000000 --- a/contracts/src/test/L1GatewayTestBase.t.sol +++ /dev/null @@ -1,181 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {DSTestPlus} from "solmate/test/utils/DSTestPlus.sol"; - -import {ITransparentUpgradeableProxy} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; - -import {EnforcedTxGateway} from "../L1/gateways/EnforcedTxGateway.sol"; -import {L1MessageQueueWithGasPriceOracle} from "../L1/rollup/L1MessageQueueWithGasPriceOracle.sol"; -import {L2GasPriceOracle} from "../L1/rollup/L2GasPriceOracle.sol"; -import {ScrollChain, IScrollChain} from "../L1/rollup/ScrollChain.sol"; -import {Whitelist} from "../L2/predeploys/Whitelist.sol"; -import {L1ScrollMessenger} from "../L1/L1ScrollMessenger.sol"; -import {L2ScrollMessenger} from "../L2/L2ScrollMessenger.sol"; -import {EmptyContract} from "../misc/EmptyContract.sol"; - -import {MockRollupVerifier} from "./mocks/MockRollupVerifier.sol"; -import {ScrollTestBase} from "./ScrollTestBase.t.sol"; - -// solhint-disable no-inline-assembly - -abstract contract L1GatewayTestBase is ScrollTestBase { - // from L1MessageQueue - event QueueTransaction( - address indexed sender, - address indexed target, - uint256 value, - uint64 queueIndex, - uint256 gasLimit, - bytes data - ); - - // from L1ScrollMessenger - event SentMessage( - address indexed sender, - address indexed target, - uint256 value, - uint256 messageNonce, - uint256 gasLimit, - bytes message - ); - event RelayedMessage(bytes32 indexed messageHash); - event FailedRelayedMessage(bytes32 indexed messageHash); - - /********** - * Errors * - **********/ - - // from IScrollGateway - error ErrorZeroAddress(); - error ErrorCallerIsNotMessenger(); - error ErrorCallerIsNotCounterpartGateway(); - error ErrorNotInDropMessageContext(); - - // pay 0.1 extra ETH to test refund - uint256 internal constant extraValue = 1e17; - - uint32 internal constant defaultGasLimit = 1000000; - - L1ScrollMessenger internal l1Messenger; - L1MessageQueueWithGasPriceOracle internal messageQueue; - L2GasPriceOracle internal gasOracle; - EnforcedTxGateway internal enforcedTxGateway; - ScrollChain internal rollup; - - MockRollupVerifier internal verifier; - - address internal feeVault; - Whitelist private whitelist; - - L2ScrollMessenger internal l2Messenger; - - bool internal revertOnReceive; - - receive() external payable { - if (revertOnReceive) { - revert("RevertOnReceive"); - } - } - - function __L1GatewayTestBase_setUp() internal { - __ScrollTestBase_setUp(); - - feeVault = address(uint160(address(this)) - 1); - - // deploy proxy and contracts in L1 - l1Messenger = L1ScrollMessenger(payable(_deployProxy(address(0)))); - messageQueue = L1MessageQueueWithGasPriceOracle(_deployProxy(address(0))); - rollup = ScrollChain(_deployProxy(address(0))); - enforcedTxGateway = EnforcedTxGateway(_deployProxy(address(new EnforcedTxGateway()))); - gasOracle = L2GasPriceOracle(_deployProxy(address(new L2GasPriceOracle()))); - whitelist = new Whitelist(address(this)); - verifier = new MockRollupVerifier(); - - // deploy proxy and contracts in L2 - l2Messenger = L2ScrollMessenger(payable(_deployProxy(address(0)))); - - // Upgrade the L1ScrollMessenger implementation and initialize - admin.upgrade( - ITransparentUpgradeableProxy(address(l1Messenger)), - address(new L1ScrollMessenger(address(l2Messenger), address(rollup), address(messageQueue))) - ); - l1Messenger.initialize(address(l2Messenger), feeVault, address(rollup), address(messageQueue)); - - // initialize L2GasPriceOracle - gasOracle.initialize(1, 2, 1, 1); - gasOracle.updateWhitelist(address(whitelist)); - - // Upgrade the L1MessageQueueWithGasPriceOracle implementation and initialize - admin.upgrade( - ITransparentUpgradeableProxy(address(messageQueue)), - address(new L1MessageQueueWithGasPriceOracle(address(l1Messenger), address(rollup), address(1))) - ); - messageQueue.initialize( - address(l1Messenger), - address(rollup), - address(enforcedTxGateway), - address(gasOracle), - 10000000 - ); - messageQueue.initializeV2(); - - // Upgrade the ScrollChain implementation and initialize - admin.upgrade( - ITransparentUpgradeableProxy(address(rollup)), - address(new ScrollChain(1233, address(messageQueue), address(verifier))) - ); - rollup.initialize(address(messageQueue), address(0), 44); - - // Setup whitelist - address[] memory _accounts = new address[](1); - _accounts[0] = address(this); - whitelist.updateWhitelistStatus(_accounts, true); - - // Make nonzero block.timestamp - hevm.warp(1); - } - - function prepareL2MessageRoot(bytes32 messageHash) internal { - rollup.addSequencer(address(0)); - rollup.addProver(address(0)); - - // import genesis batch - bytes memory batchHeader0 = new bytes(89); - assembly { - mstore(add(batchHeader0, add(0x20, 25)), 1) - } - rollup.importGenesisBatch(batchHeader0, bytes32(uint256(1))); - bytes32 batchHash0 = rollup.committedBatches(0); - - // commit one batch - bytes[] memory chunks = new bytes[](1); - bytes memory chunk0 = new bytes(1 + 60); - chunk0[0] = bytes1(uint8(1)); // one block in this chunk - chunks[0] = chunk0; - hevm.startPrank(address(0)); - rollup.commitBatch(0, batchHeader0, chunks, new bytes(0)); - hevm.stopPrank(); - - bytes memory batchHeader1 = new bytes(89); - assembly { - mstore(add(batchHeader1, 0x20), 0) // version - mstore(add(batchHeader1, add(0x20, 1)), shl(192, 1)) // batchIndex - mstore(add(batchHeader1, add(0x20, 9)), 0) // l1MessagePopped - mstore(add(batchHeader1, add(0x20, 17)), 0) // totalL1MessagePopped - mstore(add(batchHeader1, add(0x20, 25)), 0x246394445f4fe64ed5598554d55d1682d6fb3fe04bf58eb54ef81d1189fafb51) // dataHash - mstore(add(batchHeader1, add(0x20, 57)), batchHash0) // parentBatchHash - } - - hevm.startPrank(address(0)); - rollup.finalizeBatchWithProof( - batchHeader1, - bytes32(uint256(1)), - bytes32(uint256(2)), - messageHash, - new bytes(0) - ); - hevm.stopPrank(); - } -} diff --git a/contracts/src/test/L1MessageQueueWithGasPriceOracle.t.sol b/contracts/src/test/L1MessageQueueWithGasPriceOracle.t.sol deleted file mode 100644 index 536d85ea9..000000000 --- a/contracts/src/test/L1MessageQueueWithGasPriceOracle.t.sol +++ /dev/null @@ -1,100 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {DSTestPlus} from "solmate/test/utils/DSTestPlus.sol"; - -import {ITransparentUpgradeableProxy} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; - -import {IL1MessageQueueWithGasPriceOracle} from "../L1/rollup/IL1MessageQueueWithGasPriceOracle.sol"; -import {L1MessageQueueWithGasPriceOracle} from "../L1/rollup/L1MessageQueueWithGasPriceOracle.sol"; -import {L2GasPriceOracle} from "../L1/rollup/L2GasPriceOracle.sol"; -import {Whitelist} from "../L2/predeploys/Whitelist.sol"; - -import {ScrollTestBase} from "./ScrollTestBase.t.sol"; - -contract L1MessageQueueWithGasPriceOracleTest is ScrollTestBase { - // events - event UpdateWhitelistChecker(address indexed _oldWhitelistChecker, address indexed _newWhitelistChecker); - event UpdateL2BaseFee(uint256 oldL2BaseFee, uint256 newL2BaseFee); - - L1MessageQueueWithGasPriceOracle private queue; - L2GasPriceOracle internal gasOracle; - Whitelist private whitelist; - - function setUp() public { - __ScrollTestBase_setUp(); - - queue = L1MessageQueueWithGasPriceOracle(_deployProxy(address(0))); - gasOracle = L2GasPriceOracle(_deployProxy(address(new L2GasPriceOracle()))); - whitelist = new Whitelist(address(this)); - - // initialize L2GasPriceOracle - gasOracle.initialize(1, 2, 1, 1); - gasOracle.updateWhitelist(address(whitelist)); - - // Setup whitelist - address[] memory _accounts = new address[](1); - _accounts[0] = address(this); - whitelist.updateWhitelistStatus(_accounts, true); - - // Upgrade the L1MessageQueueWithGasPriceOracle implementation and initialize - admin.upgrade( - ITransparentUpgradeableProxy(address(queue)), - address(new L1MessageQueueWithGasPriceOracle(address(1), address(1), address(1))) - ); - queue.initialize(address(1), address(1), address(1), address(gasOracle), 10000000); - queue.initializeV2(); - } - - function testUpdateWhitelistChecker(address _newWhitelistChecker) external { - hevm.assume(_newWhitelistChecker != address(whitelist)); - - // call by non-owner, should revert - hevm.startPrank(address(1)); - hevm.expectRevert("Ownable: caller is not the owner"); - queue.updateWhitelistChecker(_newWhitelistChecker); - hevm.stopPrank(); - - // call by owner, should succeed - assertEq(address(queue.whitelistChecker()), address(whitelist)); - hevm.expectEmit(true, true, false, true); - emit UpdateWhitelistChecker(address(whitelist), _newWhitelistChecker); - queue.updateWhitelistChecker(_newWhitelistChecker); - assertEq(address(queue.whitelistChecker()), _newWhitelistChecker); - } - - function testSetL2BaseFee(uint256 _baseFee1, uint256 _baseFee2) external { - // call by non-whitelister, should revert - hevm.startPrank(address(1)); - hevm.expectRevert(IL1MessageQueueWithGasPriceOracle.ErrorNotWhitelistedSender.selector); - queue.setL2BaseFee(_baseFee1); - hevm.stopPrank(); - - // call by owner, should succeed - assertEq(queue.l2BaseFee(), 0); - hevm.expectEmit(false, false, false, true); - emit UpdateL2BaseFee(0, _baseFee1); - queue.setL2BaseFee(_baseFee1); - assertEq(queue.l2BaseFee(), _baseFee1); - - hevm.expectEmit(false, false, false, true); - emit UpdateL2BaseFee(_baseFee1, _baseFee2); - queue.setL2BaseFee(_baseFee2); - assertEq(queue.l2BaseFee(), _baseFee2); - } - - function testEstimateCrossDomainMessageFee(uint256 baseFee, uint256 gasLimit) external { - gasLimit = bound(gasLimit, 0, 3000000); - baseFee = bound(baseFee, 0, 1000000000); - - assertEq(queue.estimateCrossDomainMessageFee(gasLimit), 0); - - queue.setL2BaseFee(baseFee); - assertEq(queue.estimateCrossDomainMessageFee(gasLimit), baseFee * gasLimit); - } - - function testCalculateIntrinsicGasFee(bytes memory data) external { - assertEq(queue.calculateIntrinsicGasFee(data), 21000 + data.length * 16); - } -} diff --git a/contracts/src/test/L1ScrollMessengerTest.t.sol b/contracts/src/test/L1ScrollMessengerTest.t.sol deleted file mode 100644 index bd804e21f..000000000 --- a/contracts/src/test/L1ScrollMessengerTest.t.sol +++ /dev/null @@ -1,335 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {DSTestPlus} from "solmate/test/utils/DSTestPlus.sol"; - -import {EnforcedTxGateway} from "../L1/gateways/EnforcedTxGateway.sol"; -import {L1MessageQueue} from "../L1/rollup/L1MessageQueue.sol"; -import {L2GasPriceOracle} from "../L1/rollup/L2GasPriceOracle.sol"; -import {IScrollChain, ScrollChain} from "../L1/rollup/ScrollChain.sol"; -import {Whitelist} from "../L2/predeploys/Whitelist.sol"; -import {IL1ScrollMessenger, L1ScrollMessenger} from "../L1/L1ScrollMessenger.sol"; -import {L2ScrollMessenger} from "../L2/L2ScrollMessenger.sol"; - -import {L1GatewayTestBase} from "./L1GatewayTestBase.t.sol"; - -contract L1ScrollMessengerTest is L1GatewayTestBase { - event OnDropMessageCalled(bytes); - event UpdateMaxReplayTimes(uint256 oldMaxReplayTimes, uint256 newMaxReplayTimes); - - function setUp() public { - __L1GatewayTestBase_setUp(); - } - - function testForbidCallMessageQueueFromL2() external { - bytes32 _xDomainCalldataHash = keccak256( - abi.encodeWithSignature( - "relayMessage(address,address,uint256,uint256,bytes)", - address(this), - address(messageQueue), - 0, - 0, - new bytes(0) - ) - ); - prepareL2MessageRoot(_xDomainCalldataHash); - - IL1ScrollMessenger.L2MessageProof memory proof; - proof.batchIndex = rollup.lastFinalizedBatchIndex(); - - hevm.expectRevert("Forbid to call message queue"); - l1Messenger.relayMessageWithProof(address(this), address(messageQueue), 0, 0, new bytes(0), proof); - } - - function testForbidCallSelfFromL2() external { - bytes32 _xDomainCalldataHash = keccak256( - abi.encodeWithSignature( - "relayMessage(address,address,uint256,uint256,bytes)", - address(this), - address(l1Messenger), - 0, - 0, - new bytes(0) - ) - ); - prepareL2MessageRoot(_xDomainCalldataHash); - IL1ScrollMessenger.L2MessageProof memory proof; - proof.batchIndex = rollup.lastFinalizedBatchIndex(); - - hevm.expectRevert("Forbid to call self"); - l1Messenger.relayMessageWithProof(address(this), address(l1Messenger), 0, 0, new bytes(0), proof); - } - - function testSendMessage(uint256 exceedValue, address refundAddress) external { - hevm.assume(refundAddress.code.length == 0); - hevm.assume(uint256(uint160(refundAddress)) > 100); // ignore some precompile contracts - hevm.assume(refundAddress != address(0x000000000000000000636F6e736F6c652e6c6f67)); // ignore console/console2 - - exceedValue = bound(exceedValue, 1, address(this).balance / 2); - - // Insufficient msg.value - hevm.expectRevert("Insufficient msg.value"); - l1Messenger.sendMessage(address(0), 1, new bytes(0), defaultGasLimit, refundAddress); - - // refund exceed fee - uint256 balanceBefore = refundAddress.balance; - l1Messenger.sendMessage{value: 1 + exceedValue}(address(0), 1, new bytes(0), defaultGasLimit, refundAddress); - assertEq(balanceBefore + exceedValue, refundAddress.balance); - } - - function testReplayMessage(uint256 exceedValue, address refundAddress) external { - hevm.assume(refundAddress.code.length == 0); - hevm.assume(uint256(uint160(refundAddress)) > uint256(100)); // ignore some precompile contracts - hevm.assume(refundAddress != feeVault); - hevm.assume(refundAddress != address(0x000000000000000000636F6e736F6c652e6c6f67)); // ignore console/console2 - - exceedValue = bound(exceedValue, 1, address(this).balance / 2); - - l1Messenger.updateMaxReplayTimes(0); - - // append a message - l1Messenger.sendMessage{value: 100}(address(0), 100, new bytes(0), defaultGasLimit, refundAddress); - - // Provided message has not been enqueued - hevm.expectRevert("Provided message has not been enqueued"); - l1Messenger.replayMessage(address(this), address(0), 101, 0, new bytes(0), defaultGasLimit, refundAddress); - - messageQueue.setL2BaseFee(1); - // Insufficient msg.value - hevm.expectRevert("Insufficient msg.value for fee"); - l1Messenger.replayMessage(address(this), address(0), 100, 0, new bytes(0), defaultGasLimit, refundAddress); - - uint256 _fee = messageQueue.l2BaseFee() * defaultGasLimit; - - // Exceed maximum replay times - hevm.expectRevert("Exceed maximum replay times"); - l1Messenger.replayMessage{value: _fee}( - address(this), - address(0), - 100, - 0, - new bytes(0), - defaultGasLimit, - refundAddress - ); - - l1Messenger.updateMaxReplayTimes(1); - - // refund exceed fee - uint256 balanceBefore = refundAddress.balance; - uint256 feeVaultBefore = feeVault.balance; - l1Messenger.replayMessage{value: _fee + exceedValue}( - address(this), - address(0), - 100, - 0, - new bytes(0), - defaultGasLimit, - refundAddress - ); - assertEq(balanceBefore + exceedValue, refundAddress.balance); - assertEq(feeVaultBefore + _fee, feeVault.balance); - - // test replay list - // 1. send a message with nonce 2 - // 2. replay 3 times - messageQueue.setL2BaseFee(0); - l1Messenger.updateMaxReplayTimes(100); - l1Messenger.sendMessage{value: 100}(address(0), 100, new bytes(0), defaultGasLimit, refundAddress); - bytes32 hash = keccak256( - abi.encodeWithSignature( - "relayMessage(address,address,uint256,uint256,bytes)", - address(this), - address(0), - 100, - 2, - new bytes(0) - ) - ); - (uint256 _replayTimes, uint256 _lastIndex) = l1Messenger.replayStates(hash); - assertEq(_replayTimes, 0); - assertEq(_lastIndex, 0); - for (uint256 i = 0; i < 3; i++) { - l1Messenger.replayMessage(address(this), address(0), 100, 2, new bytes(0), defaultGasLimit, refundAddress); - (_replayTimes, _lastIndex) = l1Messenger.replayStates(hash); - assertEq(_replayTimes, i + 1); - assertEq(_lastIndex, i + 3); - assertEq(l1Messenger.prevReplayIndex(i + 3), i + 2 + 1); - for (uint256 j = 0; j <= i; j++) { - assertEq(l1Messenger.prevReplayIndex(i + 3 - j), i + 2 - j + 1); - } - } - } - - function testUpdateMaxReplayTimes(uint256 _maxReplayTimes) external { - // not owner, revert - hevm.startPrank(address(1)); - hevm.expectRevert("Ownable: caller is not the owner"); - l1Messenger.updateMaxReplayTimes(_maxReplayTimes); - hevm.stopPrank(); - - hevm.expectEmit(false, false, false, true); - emit UpdateMaxReplayTimes(3, _maxReplayTimes); - - assertEq(l1Messenger.maxReplayTimes(), 3); - l1Messenger.updateMaxReplayTimes(_maxReplayTimes); - assertEq(l1Messenger.maxReplayTimes(), _maxReplayTimes); - } - - function testSetPause() external { - // not owner, revert - hevm.startPrank(address(1)); - hevm.expectRevert("Ownable: caller is not the owner"); - l1Messenger.setPause(false); - hevm.stopPrank(); - - // pause - l1Messenger.setPause(true); - assertBoolEq(true, l1Messenger.paused()); - - hevm.expectRevert("Pausable: paused"); - l1Messenger.sendMessage(address(0), 0, new bytes(0), defaultGasLimit); - hevm.expectRevert("Pausable: paused"); - l1Messenger.sendMessage(address(0), 0, new bytes(0), defaultGasLimit, address(0)); - hevm.expectRevert("Pausable: paused"); - IL1ScrollMessenger.L2MessageProof memory _proof; - l1Messenger.relayMessageWithProof(address(0), address(0), 0, 0, new bytes(0), _proof); - hevm.expectRevert("Pausable: paused"); - l1Messenger.replayMessage(address(0), address(0), 0, 0, new bytes(0), 0, address(0)); - hevm.expectRevert("Pausable: paused"); - l1Messenger.dropMessage(address(0), address(0), 0, 0, new bytes(0)); - - // unpause - l1Messenger.setPause(false); - assertBoolEq(false, l1Messenger.paused()); - } - - function testIntrinsicGasLimit() external { - uint256 _fee = messageQueue.l2BaseFee() * 24000; - uint256 value = 1; - - // _xDomainCalldata contains - // 4B function identifier - // 20B sender addr (encoded as 32B) - // 20B target addr (encoded as 32B) - // 32B value - // 32B nonce - // message byte array (32B offset + 32B length + bytes (padding to multiple of 32)) - // So the intrinsic gas must be greater than 21000 + 16 * 228 = 24648 - l1Messenger.sendMessage{value: _fee + value}(address(0), value, hex"0011220033", 24648); - - // insufficient intrinsic gas - hevm.expectRevert("Insufficient gas limit, must be above intrinsic gas"); - l1Messenger.sendMessage{value: _fee + value}(address(0), 1, hex"0011220033", 24647); - - // gas limit exceeds the max value - uint256 gasLimit = 100000000; - _fee = messageQueue.l2BaseFee() * gasLimit; - hevm.expectRevert("Gas limit must not exceed maxGasLimit"); - l1Messenger.sendMessage{value: _fee + value}(address(0), value, hex"0011220033", gasLimit); - - // update max gas limit - messageQueue.updateMaxGasLimit(gasLimit); - l1Messenger.sendMessage{value: _fee + value}(address(0), value, hex"0011220033", gasLimit); - } - - function testDropMessage() external { - // Provided message has not been enqueued, revert - hevm.expectRevert("Provided message has not been enqueued"); - l1Messenger.dropMessage(address(0), address(0), 0, 0, new bytes(0)); - - // send one message with nonce 0 - l1Messenger.sendMessage(address(0), 0, new bytes(0), defaultGasLimit); - assertEq(messageQueue.nextCrossDomainMessageIndex(), 1); - - // drop pending message, revert - hevm.expectRevert("cannot drop pending message"); - l1Messenger.dropMessage(address(this), address(0), 0, 0, new bytes(0)); - - l1Messenger.updateMaxReplayTimes(10); - - // replay 1 time - l1Messenger.replayMessage(address(this), address(0), 0, 0, new bytes(0), defaultGasLimit, address(0)); - assertEq(messageQueue.nextCrossDomainMessageIndex(), 2); - - // skip all 2 messages - hevm.startPrank(address(rollup)); - messageQueue.popCrossDomainMessage(0, 2, 0x3); - assertEq(messageQueue.pendingQueueIndex(), 2); - hevm.stopPrank(); - for (uint256 i = 0; i < 2; ++i) { - assertBoolEq(messageQueue.isMessageSkipped(i), true); - assertBoolEq(messageQueue.isMessageDropped(i), false); - } - hevm.expectEmit(false, false, false, true); - emit OnDropMessageCalled(new bytes(0)); - l1Messenger.dropMessage(address(this), address(0), 0, 0, new bytes(0)); - for (uint256 i = 0; i < 2; ++i) { - assertBoolEq(messageQueue.isMessageSkipped(i), true); - assertBoolEq(messageQueue.isMessageDropped(i), true); - } - - // send one message with nonce 2 and replay 3 times - l1Messenger.sendMessage(address(0), 0, new bytes(0), defaultGasLimit); - assertEq(messageQueue.nextCrossDomainMessageIndex(), 3); - for (uint256 i = 0; i < 3; i++) { - l1Messenger.replayMessage(address(this), address(0), 0, 2, new bytes(0), defaultGasLimit, address(0)); - } - assertEq(messageQueue.nextCrossDomainMessageIndex(), 6); - - // only first 3 are skipped - hevm.startPrank(address(rollup)); - messageQueue.popCrossDomainMessage(2, 4, 0x7); - assertEq(messageQueue.pendingQueueIndex(), 6); - hevm.stopPrank(); - for (uint256 i = 2; i < 6; i++) { - assertBoolEq(messageQueue.isMessageSkipped(i), i < 5); - assertBoolEq(messageQueue.isMessageDropped(i), false); - } - - // drop non-skipped message, revert - hevm.expectRevert("drop non-skipped message"); - l1Messenger.dropMessage(address(this), address(0), 0, 2, new bytes(0)); - - // send one message with nonce 6 and replay 4 times - l1Messenger.sendMessage(address(0), 0, new bytes(0), defaultGasLimit); - for (uint256 i = 0; i < 4; i++) { - l1Messenger.replayMessage(address(this), address(0), 0, 6, new bytes(0), defaultGasLimit, address(0)); - } - assertEq(messageQueue.nextCrossDomainMessageIndex(), 11); - - // skip all 5 messages - hevm.startPrank(address(rollup)); - messageQueue.popCrossDomainMessage(6, 5, 0x1f); - assertEq(messageQueue.pendingQueueIndex(), 11); - hevm.stopPrank(); - for (uint256 i = 6; i < 11; ++i) { - assertBoolEq(messageQueue.isMessageSkipped(i), true); - assertBoolEq(messageQueue.isMessageDropped(i), false); - } - hevm.expectEmit(false, false, false, true); - emit OnDropMessageCalled(new bytes(0)); - l1Messenger.dropMessage(address(this), address(0), 0, 6, new bytes(0)); - for (uint256 i = 6; i < 11; ++i) { - assertBoolEq(messageQueue.isMessageSkipped(i), true); - assertBoolEq(messageQueue.isMessageDropped(i), true); - } - - // Message already dropped, revert - hevm.expectRevert("Message already dropped"); - l1Messenger.dropMessage(address(this), address(0), 0, 0, new bytes(0)); - hevm.expectRevert("Message already dropped"); - l1Messenger.dropMessage(address(this), address(0), 0, 6, new bytes(0)); - - // replay dropped message, revert - hevm.expectRevert("Message already dropped"); - l1Messenger.replayMessage(address(this), address(0), 0, 0, new bytes(0), defaultGasLimit, address(0)); - hevm.expectRevert("Message already dropped"); - l1Messenger.replayMessage(address(this), address(0), 0, 6, new bytes(0), defaultGasLimit, address(0)); - } - - function onDropMessage(bytes memory message) external payable { - emit OnDropMessageCalled(message); - } -} diff --git a/contracts/src/test/L1StandardERC20Gateway.t.sol b/contracts/src/test/L1StandardERC20Gateway.t.sol deleted file mode 100644 index 576c557d8..000000000 --- a/contracts/src/test/L1StandardERC20Gateway.t.sol +++ /dev/null @@ -1,734 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {MockERC20} from "solmate/test/utils/mocks/MockERC20.sol"; - -import {ITransparentUpgradeableProxy} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; - -import {L1GatewayRouter} from "../L1/gateways/L1GatewayRouter.sol"; -import {IL1ERC20Gateway, L1StandardERC20Gateway} from "../L1/gateways/L1StandardERC20Gateway.sol"; -import {IL1ScrollMessenger} from "../L1/IL1ScrollMessenger.sol"; -import {IL2ERC20Gateway, L2StandardERC20Gateway} from "../L2/gateways/L2StandardERC20Gateway.sol"; -import {ScrollStandardERC20} from "../libraries/token/ScrollStandardERC20.sol"; -import {ScrollStandardERC20Factory} from "../libraries/token/ScrollStandardERC20Factory.sol"; -import {AddressAliasHelper} from "../libraries/common/AddressAliasHelper.sol"; -import {ScrollConstants} from "../libraries/constants/ScrollConstants.sol"; - -import {L1GatewayTestBase} from "./L1GatewayTestBase.t.sol"; -import {MockScrollMessenger} from "./mocks/MockScrollMessenger.sol"; -import {TransferReentrantToken} from "./mocks/tokens/TransferReentrantToken.sol"; -import {FeeOnTransferToken} from "./mocks/tokens/FeeOnTransferToken.sol"; -import {MockGatewayRecipient} from "./mocks/MockGatewayRecipient.sol"; - -contract L1StandardERC20GatewayTest is L1GatewayTestBase { - // from L1StandardERC20Gateway - event FinalizeWithdrawERC20( - address indexed _l1Token, - address indexed _l2Token, - address indexed _from, - address _to, - uint256 _amount, - bytes _data - ); - event DepositERC20( - address indexed _l1Token, - address indexed _l2Token, - address indexed _from, - address _to, - uint256 _amount, - bytes _data - ); - event RefundERC20(address indexed token, address indexed recipient, uint256 amount); - - ScrollStandardERC20 private template; - ScrollStandardERC20Factory private factory; - - L1StandardERC20Gateway private gateway; - L1GatewayRouter private router; - - L2StandardERC20Gateway private counterpartGateway; - - MockERC20 private l1Token; - MockERC20 private l2Token; - TransferReentrantToken private reentrantToken; - FeeOnTransferToken private feeToken; - - function setUp() public { - __L1GatewayTestBase_setUp(); - - // Deploy tokens - l1Token = new MockERC20("Mock", "M", 18); - reentrantToken = new TransferReentrantToken("Reentrant", "R", 18); - feeToken = new FeeOnTransferToken("Fee", "F", 18); - - // Deploy L2 contracts - template = new ScrollStandardERC20(); - factory = new ScrollStandardERC20Factory(address(template)); - counterpartGateway = new L2StandardERC20Gateway(address(1), address(1), address(1), address(factory)); - - // Deploy L1 contracts - router = L1GatewayRouter(_deployProxy(address(new L1GatewayRouter()))); - gateway = _deployGateway(address(l1Messenger)); - - // Initialize L1 contracts - gateway.initialize( - address(counterpartGateway), - address(router), - address(l1Messenger), - address(template), - address(factory) - ); - router.initialize(address(0), address(gateway)); - - // Prepare token balances - l2Token = MockERC20(gateway.getL2ERC20Address(address(l1Token))); - l1Token.mint(address(this), type(uint128).max); - l1Token.approve(address(gateway), type(uint256).max); - l1Token.approve(address(router), type(uint256).max); - - reentrantToken.mint(address(this), type(uint128).max); - reentrantToken.approve(address(gateway), type(uint256).max); - reentrantToken.approve(address(router), type(uint256).max); - - feeToken.mint(address(this), type(uint128).max); - feeToken.approve(address(gateway), type(uint256).max); - feeToken.approve(address(router), type(uint256).max); - } - - function testInitialized() public { - assertEq(address(counterpartGateway), gateway.counterpart()); - assertEq(address(router), gateway.router()); - assertEq(address(l1Messenger), gateway.messenger()); - assertEq(address(template), gateway.l2TokenImplementation()); - assertEq(address(factory), gateway.l2TokenFactory()); - - hevm.expectRevert("Initializable: contract is already initialized"); - gateway.initialize( - address(counterpartGateway), - address(router), - address(l1Messenger), - address(template), - address(factory) - ); - } - - function testGetL2ERC20Address(address l1Address) public { - assertEq( - gateway.getL2ERC20Address(l1Address), - factory.computeL2TokenAddress(address(counterpartGateway), l1Address) - ); - } - - function testDepositERC20( - uint256 amount, - uint256 gasLimit, - uint256 feePerGas - ) public { - _depositERC20(false, amount, gasLimit, feePerGas); - } - - function testDepositERC20WithRecipient( - uint256 amount, - address recipient, - uint256 gasLimit, - uint256 feePerGas - ) public { - _depositERC20WithRecipient(false, amount, recipient, gasLimit, feePerGas); - } - - function testDepositERC20WithRecipientAndCalldata( - uint256 amount, - address recipient, - bytes memory dataToCall, - uint256 gasLimit, - uint256 feePerGas - ) public { - _depositERC20WithRecipientAndCalldata(false, amount, recipient, dataToCall, gasLimit, feePerGas); - } - - function testRouterDepositERC20( - uint256 amount, - uint256 gasLimit, - uint256 feePerGas - ) public { - _depositERC20(true, amount, gasLimit, feePerGas); - } - - function testRouterDepositERC20WithRecipient( - uint256 amount, - address recipient, - uint256 gasLimit, - uint256 feePerGas - ) public { - _depositERC20WithRecipient(true, amount, recipient, gasLimit, feePerGas); - } - - function testRouterDepositERC20WithRecipientAndCalldata( - uint256 amount, - address recipient, - bytes memory dataToCall, - uint256 gasLimit, - uint256 feePerGas - ) public { - _depositERC20WithRecipientAndCalldata(true, amount, recipient, dataToCall, gasLimit, feePerGas); - } - - function testDepositReentrantToken(uint256 amount) public { - // should revert, reentrant before transfer - reentrantToken.setReentrantCall( - address(gateway), - 0, - abi.encodeWithSignature("depositERC20(address,uint256,uint256)", address(0), 1, 0), - true - ); - amount = bound(amount, 1, reentrantToken.balanceOf(address(this))); - hevm.expectRevert("ReentrancyGuard: reentrant call"); - gateway.depositERC20(address(reentrantToken), amount, defaultGasLimit); - - // should revert, reentrant after transfer - reentrantToken.setReentrantCall( - address(gateway), - 0, - abi.encodeWithSignature("depositERC20(address,uint256,uint256)", address(0), 1, 0), - false - ); - amount = bound(amount, 1, reentrantToken.balanceOf(address(this))); - hevm.expectRevert("ReentrancyGuard: reentrant call"); - gateway.depositERC20(address(reentrantToken), amount, defaultGasLimit); - } - - function testFeeOnTransferTokenFailed(uint256 amount) public { - feeToken.setFeeRate(1e9); - amount = bound(amount, 1, feeToken.balanceOf(address(this))); - hevm.expectRevert("deposit zero amount"); - gateway.depositERC20(address(feeToken), amount, defaultGasLimit); - } - - function testFeeOnTransferTokenSucceed(uint256 amount, uint256 feeRate) public { - feeRate = bound(feeRate, 0, 1e9 - 1); - amount = bound(amount, 1e9, feeToken.balanceOf(address(this))); - feeToken.setFeeRate(feeRate); - - // should succeed, for valid amount - uint256 balanceBefore = feeToken.balanceOf(address(gateway)); - uint256 fee = (amount * feeRate) / 1e9; - gateway.depositERC20(address(feeToken), amount, defaultGasLimit); - uint256 balanceAfter = feeToken.balanceOf(address(gateway)); - assertEq(balanceBefore + amount - fee, balanceAfter); - } - - function testDropMessageMocking() public { - MockScrollMessenger mockMessenger = new MockScrollMessenger(); - gateway = _deployGateway(address(mockMessenger)); - gateway.initialize( - address(counterpartGateway), - address(router), - address(mockMessenger), - address(template), - address(factory) - ); - - // only messenger can call, revert - hevm.expectRevert(ErrorCallerIsNotMessenger.selector); - gateway.onDropMessage(new bytes(0)); - - // only called in drop context, revert - hevm.expectRevert(ErrorNotInDropMessageContext.selector); - mockMessenger.callTarget( - address(gateway), - abi.encodeWithSelector(gateway.onDropMessage.selector, new bytes(0)) - ); - - mockMessenger.setXDomainMessageSender(ScrollConstants.DROP_XDOMAIN_MESSAGE_SENDER); - - // invalid selector, revert - hevm.expectRevert("invalid selector"); - mockMessenger.callTarget( - address(gateway), - abi.encodeWithSelector(gateway.onDropMessage.selector, new bytes(4)) - ); - - bytes memory message = abi.encodeWithSelector( - IL2ERC20Gateway.finalizeDepositERC20.selector, - address(l1Token), - address(l2Token), - address(this), - address(this), - 100, - new bytes(0) - ); - - // nonzero msg.value, revert - hevm.expectRevert("nonzero msg.value"); - mockMessenger.callTarget{value: 1}( - address(gateway), - abi.encodeWithSelector(gateway.onDropMessage.selector, message) - ); - } - - function testDropMessage( - uint256 amount, - address recipient, - bytes memory dataToCall - ) public { - amount = bound(amount, 1, l1Token.balanceOf(address(this)) / 2); - bytes memory message = abi.encodeWithSelector( - IL2ERC20Gateway.finalizeDepositERC20.selector, - address(l1Token), - address(l2Token), - address(this), - recipient, - amount, - abi.encode(true, abi.encode(dataToCall, abi.encode(l1Token.symbol(), l1Token.name(), l1Token.decimals()))) - ); - gateway.depositERC20AndCall(address(l1Token), recipient, amount, dataToCall, defaultGasLimit); - gateway.depositERC20AndCall(address(l1Token), recipient, amount, dataToCall, defaultGasLimit); - - // skip message 0 and 1 - hevm.startPrank(address(rollup)); - messageQueue.popCrossDomainMessage(0, 2, 0x3); - assertEq(messageQueue.pendingQueueIndex(), 2); - hevm.stopPrank(); - - // drop message 1 - hevm.expectEmit(true, true, false, true); - emit RefundERC20(address(l1Token), address(this), amount); - - uint256 balance = l1Token.balanceOf(address(this)); - l1Messenger.dropMessage(address(gateway), address(counterpartGateway), 0, 1, message); - assertEq(balance + amount, l1Token.balanceOf(address(this))); - } - - function testFinalizeWithdrawERC20FailedMocking( - address sender, - address recipient, - uint256 amount, - bytes memory dataToCall - ) public { - amount = bound(amount, 1, 100000); - - // revert when caller is not messenger - hevm.expectRevert(ErrorCallerIsNotMessenger.selector); - gateway.finalizeWithdrawERC20(address(l1Token), address(l2Token), sender, recipient, amount, dataToCall); - - MockScrollMessenger mockMessenger = new MockScrollMessenger(); - gateway = _deployGateway(address(mockMessenger)); - gateway.initialize( - address(counterpartGateway), - address(router), - address(mockMessenger), - address(template), - address(factory) - ); - - // only call by counterpart - hevm.expectRevert(ErrorCallerIsNotCounterpartGateway.selector); - mockMessenger.callTarget( - address(gateway), - abi.encodeWithSelector( - gateway.finalizeWithdrawERC20.selector, - address(l1Token), - address(l2Token), - sender, - recipient, - amount, - dataToCall - ) - ); - - mockMessenger.setXDomainMessageSender(address(counterpartGateway)); - - // msg.value mismatch - hevm.expectRevert("nonzero msg.value"); - mockMessenger.callTarget{value: 1}( - address(gateway), - abi.encodeWithSelector( - gateway.finalizeWithdrawERC20.selector, - address(l1Token), - address(l2Token), - sender, - recipient, - amount, - dataToCall - ) - ); - } - - function testFinalizeWithdrawERC20Failed( - address sender, - address recipient, - uint256 amount, - bytes memory dataToCall - ) public { - // blacklist some addresses - hevm.assume(recipient != address(0)); - - amount = bound(amount, 1, l1Token.balanceOf(address(this))); - - // deposit some token to L1StandardERC20Gateway - gateway.depositERC20(address(l1Token), amount, defaultGasLimit); - - // do finalize withdraw token - bytes memory message = abi.encodeWithSelector( - IL1ERC20Gateway.finalizeWithdrawERC20.selector, - address(l1Token), - address(l2Token), - sender, - recipient, - amount, - dataToCall - ); - bytes memory xDomainCalldata = abi.encodeWithSignature( - "relayMessage(address,address,uint256,uint256,bytes)", - address(uint160(address(counterpartGateway)) + 1), - address(gateway), - 0, - 0, - message - ); - - prepareL2MessageRoot(keccak256(xDomainCalldata)); - - IL1ScrollMessenger.L2MessageProof memory proof; - proof.batchIndex = rollup.lastFinalizedBatchIndex(); - - // counterpart is not L2WETHGateway - // emit FailedRelayedMessage from L1ScrollMessenger - hevm.expectEmit(true, false, false, true); - emit FailedRelayedMessage(keccak256(xDomainCalldata)); - - uint256 gatewayBalance = l1Token.balanceOf(address(gateway)); - uint256 recipientBalance = l1Token.balanceOf(recipient); - assertBoolEq(false, l1Messenger.isL2MessageExecuted(keccak256(xDomainCalldata))); - l1Messenger.relayMessageWithProof( - address(uint160(address(counterpartGateway)) + 1), - address(gateway), - 0, - 0, - message, - proof - ); - assertEq(gatewayBalance, l1Token.balanceOf(address(gateway))); - assertEq(recipientBalance, l1Token.balanceOf(recipient)); - assertBoolEq(false, l1Messenger.isL2MessageExecuted(keccak256(xDomainCalldata))); - } - - function testFinalizeWithdrawERC20( - address sender, - uint256 amount, - bytes memory dataToCall - ) public { - MockGatewayRecipient recipient = new MockGatewayRecipient(); - - amount = bound(amount, 1, l1Token.balanceOf(address(this))); - - // deposit some token to L1StandardERC20Gateway - gateway.depositERC20(address(l1Token), amount, defaultGasLimit); - - // do finalize withdraw token - bytes memory message = abi.encodeWithSelector( - IL1ERC20Gateway.finalizeWithdrawERC20.selector, - address(l1Token), - address(l2Token), - sender, - address(recipient), - amount, - dataToCall - ); - bytes memory xDomainCalldata = abi.encodeWithSignature( - "relayMessage(address,address,uint256,uint256,bytes)", - address(counterpartGateway), - address(gateway), - 0, - 0, - message - ); - - prepareL2MessageRoot(keccak256(xDomainCalldata)); - - IL1ScrollMessenger.L2MessageProof memory proof; - proof.batchIndex = rollup.lastFinalizedBatchIndex(); - - // emit FinalizeWithdrawERC20 from L1StandardERC20Gateway - { - hevm.expectEmit(true, true, true, true); - emit FinalizeWithdrawERC20( - address(l1Token), - address(l2Token), - sender, - address(recipient), - amount, - dataToCall - ); - } - - // emit RelayedMessage from L1ScrollMessenger - { - hevm.expectEmit(true, false, false, true); - emit RelayedMessage(keccak256(xDomainCalldata)); - } - - uint256 gatewayBalance = l1Token.balanceOf(address(gateway)); - uint256 recipientBalance = l1Token.balanceOf(address(recipient)); - assertBoolEq(false, l1Messenger.isL2MessageExecuted(keccak256(xDomainCalldata))); - l1Messenger.relayMessageWithProof(address(counterpartGateway), address(gateway), 0, 0, message, proof); - assertEq(gatewayBalance - amount, l1Token.balanceOf(address(gateway))); - assertEq(recipientBalance + amount, l1Token.balanceOf(address(recipient))); - assertBoolEq(true, l1Messenger.isL2MessageExecuted(keccak256(xDomainCalldata))); - } - - function _depositERC20( - bool useRouter, - uint256 amount, - uint256 gasLimit, - uint256 feePerGas - ) private { - amount = bound(amount, 0, l1Token.balanceOf(address(this))); - gasLimit = bound(gasLimit, defaultGasLimit / 2, defaultGasLimit); - feePerGas = bound(feePerGas, 0, 1000); - - messageQueue.setL2BaseFee(feePerGas); - - uint256 feeToPay = feePerGas * gasLimit; - bytes memory message = abi.encodeWithSelector( - IL2ERC20Gateway.finalizeDepositERC20.selector, - address(l1Token), - address(l2Token), - address(this), - address(this), - amount, - abi.encode(true, abi.encode(new bytes(0), abi.encode(l1Token.symbol(), l1Token.name(), l1Token.decimals()))) - ); - bytes memory xDomainCalldata = abi.encodeWithSignature( - "relayMessage(address,address,uint256,uint256,bytes)", - address(gateway), - address(counterpartGateway), - 0, - 0, - message - ); - - if (amount == 0) { - hevm.expectRevert("deposit zero amount"); - if (useRouter) { - router.depositERC20{value: feeToPay + extraValue}(address(l1Token), amount, gasLimit); - } else { - gateway.depositERC20{value: feeToPay + extraValue}(address(l1Token), amount, gasLimit); - } - } else { - // emit QueueTransaction from L1MessageQueue - { - hevm.expectEmit(true, true, false, true); - address sender = AddressAliasHelper.applyL1ToL2Alias(address(l1Messenger)); - emit QueueTransaction(sender, address(l2Messenger), 0, 0, gasLimit, xDomainCalldata); - } - - // emit SentMessage from L1ScrollMessenger - { - hevm.expectEmit(true, true, false, true); - emit SentMessage(address(gateway), address(counterpartGateway), 0, 0, gasLimit, message); - } - - // emit DepositERC20 from L1StandardERC20Gateway - hevm.expectEmit(true, true, true, true); - emit DepositERC20(address(l1Token), address(l2Token), address(this), address(this), amount, new bytes(0)); - - uint256 gatewayBalance = l1Token.balanceOf(address(gateway)); - uint256 feeVaultBalance = address(feeVault).balance; - assertEq(l1Messenger.messageSendTimestamp(keccak256(xDomainCalldata)), 0); - if (useRouter) { - router.depositERC20{value: feeToPay + extraValue}(address(l1Token), amount, gasLimit); - } else { - gateway.depositERC20{value: feeToPay + extraValue}(address(l1Token), amount, gasLimit); - } - assertEq(amount + gatewayBalance, l1Token.balanceOf(address(gateway))); - assertEq(feeToPay + feeVaultBalance, address(feeVault).balance); - assertGt(l1Messenger.messageSendTimestamp(keccak256(xDomainCalldata)), 0); - } - } - - function _depositERC20WithRecipient( - bool useRouter, - uint256 amount, - address recipient, - uint256 gasLimit, - uint256 feePerGas - ) private { - amount = bound(amount, 0, l1Token.balanceOf(address(this))); - gasLimit = bound(gasLimit, defaultGasLimit / 2, defaultGasLimit); - feePerGas = bound(feePerGas, 0, 1000); - - messageQueue.setL2BaseFee(feePerGas); - - uint256 feeToPay = feePerGas * gasLimit; - bytes memory message = abi.encodeWithSelector( - IL2ERC20Gateway.finalizeDepositERC20.selector, - address(l1Token), - address(l2Token), - address(this), - recipient, - amount, - abi.encode(true, abi.encode(new bytes(0), abi.encode(l1Token.symbol(), l1Token.name(), l1Token.decimals()))) - ); - bytes memory xDomainCalldata = abi.encodeWithSignature( - "relayMessage(address,address,uint256,uint256,bytes)", - address(gateway), - address(counterpartGateway), - 0, - 0, - message - ); - - if (amount == 0) { - hevm.expectRevert("deposit zero amount"); - if (useRouter) { - router.depositERC20{value: feeToPay + extraValue}(address(l1Token), recipient, amount, gasLimit); - } else { - gateway.depositERC20{value: feeToPay + extraValue}(address(l1Token), recipient, amount, gasLimit); - } - } else { - // emit QueueTransaction from L1MessageQueue - { - hevm.expectEmit(true, true, false, true); - address sender = AddressAliasHelper.applyL1ToL2Alias(address(l1Messenger)); - emit QueueTransaction(sender, address(l2Messenger), 0, 0, gasLimit, xDomainCalldata); - } - - // emit SentMessage from L1ScrollMessenger - { - hevm.expectEmit(true, true, false, true); - emit SentMessage(address(gateway), address(counterpartGateway), 0, 0, gasLimit, message); - } - - // emit DepositERC20 from L1StandardERC20Gateway - hevm.expectEmit(true, true, true, true); - emit DepositERC20(address(l1Token), address(l2Token), address(this), recipient, amount, new bytes(0)); - - uint256 gatewayBalance = l1Token.balanceOf(address(gateway)); - uint256 feeVaultBalance = address(feeVault).balance; - assertEq(l1Messenger.messageSendTimestamp(keccak256(xDomainCalldata)), 0); - if (useRouter) { - router.depositERC20{value: feeToPay + extraValue}(address(l1Token), recipient, amount, gasLimit); - } else { - gateway.depositERC20{value: feeToPay + extraValue}(address(l1Token), recipient, amount, gasLimit); - } - assertEq(amount + gatewayBalance, l1Token.balanceOf(address(gateway))); - assertEq(feeToPay + feeVaultBalance, address(feeVault).balance); - assertGt(l1Messenger.messageSendTimestamp(keccak256(xDomainCalldata)), 0); - } - } - - function _depositERC20WithRecipientAndCalldata( - bool useRouter, - uint256 amount, - address recipient, - bytes memory dataToCall, - uint256 gasLimit, - uint256 feePerGas - ) private { - amount = bound(amount, 0, l1Token.balanceOf(address(this))); - gasLimit = bound(gasLimit, defaultGasLimit / 2, defaultGasLimit); - feePerGas = bound(feePerGas, 0, 1000); - - messageQueue.setL2BaseFee(feePerGas); - - uint256 feeToPay = feePerGas * gasLimit; - bytes memory message = abi.encodeWithSelector( - IL2ERC20Gateway.finalizeDepositERC20.selector, - address(l1Token), - address(l2Token), - address(this), - recipient, - amount, - abi.encode(true, abi.encode(dataToCall, abi.encode(l1Token.symbol(), l1Token.name(), l1Token.decimals()))) - ); - bytes memory xDomainCalldata = abi.encodeWithSignature( - "relayMessage(address,address,uint256,uint256,bytes)", - address(gateway), - address(counterpartGateway), - 0, - 0, - message - ); - - if (amount == 0) { - hevm.expectRevert("deposit zero amount"); - if (useRouter) { - router.depositERC20AndCall{value: feeToPay + extraValue}( - address(l1Token), - recipient, - amount, - dataToCall, - gasLimit - ); - } else { - gateway.depositERC20AndCall{value: feeToPay + extraValue}( - address(l1Token), - recipient, - amount, - dataToCall, - gasLimit - ); - } - } else { - // emit QueueTransaction from L1MessageQueue - { - hevm.expectEmit(true, true, false, true); - address sender = AddressAliasHelper.applyL1ToL2Alias(address(l1Messenger)); - emit QueueTransaction(sender, address(l2Messenger), 0, 0, gasLimit, xDomainCalldata); - } - - // emit SentMessage from L1ScrollMessenger - { - hevm.expectEmit(true, true, false, true); - emit SentMessage(address(gateway), address(counterpartGateway), 0, 0, gasLimit, message); - } - - // emit DepositERC20 from L1StandardERC20Gateway - hevm.expectEmit(true, true, true, true); - emit DepositERC20(address(l1Token), address(l2Token), address(this), recipient, amount, dataToCall); - - uint256 gatewayBalance = l1Token.balanceOf(address(gateway)); - uint256 feeVaultBalance = address(feeVault).balance; - assertEq(l1Messenger.messageSendTimestamp(keccak256(xDomainCalldata)), 0); - if (useRouter) { - router.depositERC20AndCall{value: feeToPay + extraValue}( - address(l1Token), - recipient, - amount, - dataToCall, - gasLimit - ); - } else { - gateway.depositERC20AndCall{value: feeToPay + extraValue}( - address(l1Token), - recipient, - amount, - dataToCall, - gasLimit - ); - } - assertEq(amount + gatewayBalance, l1Token.balanceOf(address(gateway))); - assertEq(feeToPay + feeVaultBalance, address(feeVault).balance); - assertGt(l1Messenger.messageSendTimestamp(keccak256(xDomainCalldata)), 0); - } - } - - function _deployGateway(address messenger) internal returns (L1StandardERC20Gateway _gateway) { - _gateway = L1StandardERC20Gateway(_deployProxy(address(0))); - - admin.upgrade( - ITransparentUpgradeableProxy(address(_gateway)), - address( - new L1StandardERC20Gateway( - address(counterpartGateway), - address(router), - address(messenger), - address(template), - address(factory) - ) - ) - ); - } -} diff --git a/contracts/src/test/L1USDCGateway.t.sol b/contracts/src/test/L1USDCGateway.t.sol deleted file mode 100644 index 585a6b3e1..000000000 --- a/contracts/src/test/L1USDCGateway.t.sol +++ /dev/null @@ -1,538 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import {MockERC20} from "solmate/test/utils/mocks/MockERC20.sol"; - -import {ITransparentUpgradeableProxy} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; - -import {L1GatewayRouter} from "../L1/gateways/L1GatewayRouter.sol"; -import {IL1ERC20Gateway, L1USDCGateway} from "../L1/gateways/usdc/L1USDCGateway.sol"; -import {IL1ScrollMessenger} from "../L1/IL1ScrollMessenger.sol"; -import {IL2ERC20Gateway, L2USDCGateway} from "../L2/gateways/usdc/L2USDCGateway.sol"; -import {AddressAliasHelper} from "../libraries/common/AddressAliasHelper.sol"; - -import {L1GatewayTestBase} from "./L1GatewayTestBase.t.sol"; -import {MockScrollMessenger} from "./mocks/MockScrollMessenger.sol"; -import {MockGatewayRecipient} from "./mocks/MockGatewayRecipient.sol"; - -contract L1USDCGatewayTest is L1GatewayTestBase { - // from L1USDCGateway - event FinalizeWithdrawERC20( - address indexed _l1Token, - address indexed _l2Token, - address indexed _from, - address _to, - uint256 _amount, - bytes _data - ); - event DepositERC20( - address indexed _l1Token, - address indexed _l2Token, - address indexed _from, - address _to, - uint256 _amount, - bytes _data - ); - - MockERC20 private l1USDC; - MockERC20 private l2USDC; - - L1USDCGateway private gateway; - L1GatewayRouter private router; - - L2USDCGateway private counterpartGateway; - - function setUp() public { - __L1GatewayTestBase_setUp(); - - // Deploy tokens - l1USDC = new MockERC20("USDC", "USDC", 6); - l2USDC = new MockERC20("USDC", "USDC", 6); - - // Deploy L2 contracts - counterpartGateway = new L2USDCGateway(address(l1USDC), address(l2USDC), address(1), address(1), address(1)); - - // Deploy L1 contracts - router = L1GatewayRouter(_deployProxy(address(new L1GatewayRouter()))); - gateway = _deployGateway(address(l1Messenger)); - - // Initialize L1 contracts - gateway.initialize(address(counterpartGateway), address(router), address(l1Messenger)); - router.initialize(address(0), address(gateway)); - - // Prepare token balances - l1USDC.mint(address(this), type(uint128).max); - l1USDC.approve(address(gateway), type(uint256).max); - l1USDC.approve(address(router), type(uint256).max); - } - - function testInitialized() public { - assertEq(address(counterpartGateway), gateway.counterpart()); - assertEq(address(router), gateway.router()); - assertEq(address(l1Messenger), gateway.messenger()); - assertEq(address(l1USDC), gateway.l1USDC()); - assertEq(address(l2USDC), gateway.l2USDC()); - assertEq(address(l2USDC), gateway.getL2ERC20Address(address(l1USDC))); - assertEq(0, gateway.totalBridgedUSDC()); - - hevm.expectRevert("Initializable: contract is already initialized"); - gateway.initialize(address(counterpartGateway), address(router), address(l1Messenger)); - } - - function testDepositPaused() public { - // non-owner call pause, should revert - hevm.startPrank(address(1)); - hevm.expectRevert("Ownable: caller is not the owner"); - gateway.pauseDeposit(false); - hevm.expectRevert("Ownable: caller is not the owner"); - gateway.pauseDeposit(true); - hevm.stopPrank(); - - // pause deposit - gateway.pauseDeposit(true); - - // deposit paused, should revert - hevm.expectRevert("deposit paused"); - gateway.depositERC20(address(l1USDC), 1, defaultGasLimit); - hevm.expectRevert("deposit paused"); - gateway.depositERC20(address(l1USDC), address(this), 1, defaultGasLimit); - hevm.expectRevert("deposit paused"); - gateway.depositERC20AndCall(address(l1USDC), address(this), 1, new bytes(0), defaultGasLimit); - } - - function testPauseWithdraw() public { - // non-owner call pause, should revert - hevm.startPrank(address(1)); - hevm.expectRevert("Ownable: caller is not the owner"); - gateway.pauseWithdraw(false); - hevm.expectRevert("Ownable: caller is not the owner"); - gateway.pauseWithdraw(true); - hevm.stopPrank(); - } - - function testDepositERC20( - uint256 amount, - uint256 gasLimit, - uint256 feePerGas - ) public { - _depositERC20(false, amount, gasLimit, feePerGas); - } - - function testDepositERC20WithRecipient( - uint256 amount, - address recipient, - uint256 gasLimit, - uint256 feePerGas - ) public { - _depositERC20WithRecipient(false, amount, recipient, gasLimit, feePerGas); - } - - function testRouterDepositERC20( - uint256 amount, - uint256 gasLimit, - uint256 feePerGas - ) public { - _depositERC20(true, amount, gasLimit, feePerGas); - } - - function testRouterDepositERC20WithRecipient( - uint256 amount, - address recipient, - uint256 gasLimit, - uint256 feePerGas - ) public { - _depositERC20WithRecipient(true, amount, recipient, gasLimit, feePerGas); - } - - function testFinalizeWithdrawERC20FailedMocking( - address sender, - address recipient, - uint256 amount, - bytes memory dataToCall - ) public { - amount = bound(amount, 1, 100000); - - // revert when caller is not messenger - hevm.expectRevert(ErrorCallerIsNotMessenger.selector); - gateway.finalizeWithdrawERC20(address(l1USDC), address(l2USDC), sender, recipient, amount, dataToCall); - - MockScrollMessenger mockMessenger = new MockScrollMessenger(); - gateway = _deployGateway(address(mockMessenger)); - gateway.initialize(address(counterpartGateway), address(router), address(mockMessenger)); - - // only call by conterpart - hevm.expectRevert(ErrorCallerIsNotCounterpartGateway.selector); - mockMessenger.callTarget( - address(gateway), - abi.encodeWithSelector( - gateway.finalizeWithdrawERC20.selector, - address(l1USDC), - address(l2USDC), - sender, - recipient, - amount, - dataToCall - ) - ); - - mockMessenger.setXDomainMessageSender(address(counterpartGateway)); - - // nonzero msg.value - hevm.expectRevert("nonzero msg.value"); - mockMessenger.callTarget{value: 1}( - address(gateway), - abi.encodeWithSelector( - gateway.finalizeWithdrawERC20.selector, - address(l1USDC), - address(l2USDC), - sender, - recipient, - amount, - dataToCall - ) - ); - - // l1 token not USDC - hevm.expectRevert("l1 token not USDC"); - mockMessenger.callTarget( - address(gateway), - abi.encodeWithSelector( - gateway.finalizeWithdrawERC20.selector, - address(l2USDC), - address(l2USDC), - sender, - recipient, - amount, - dataToCall - ) - ); - - // l2 token not USDC - hevm.expectRevert("l2 token not USDC"); - mockMessenger.callTarget( - address(gateway), - abi.encodeWithSelector( - gateway.finalizeWithdrawERC20.selector, - address(l1USDC), - address(l1USDC), - sender, - recipient, - amount, - dataToCall - ) - ); - - // withdraw paused - gateway.pauseWithdraw(true); - hevm.expectRevert("withdraw paused"); - mockMessenger.callTarget( - address(gateway), - abi.encodeWithSelector( - gateway.finalizeWithdrawERC20.selector, - address(l1USDC), - address(l2USDC), - sender, - recipient, - amount, - dataToCall - ) - ); - } - - function testFinalizeWithdrawERC20Failed( - address sender, - address recipient, - uint256 amount, - bytes memory dataToCall - ) public { - // blacklist some addresses - hevm.assume(recipient != address(0)); - hevm.assume(recipient != address(gateway)); - - amount = bound(amount, 1, l1USDC.balanceOf(address(this))); - - // deposit some USDC to L1ScrollMessenger - gateway.depositERC20(address(l1USDC), amount, defaultGasLimit); - - // do finalize withdraw usdc - bytes memory message = abi.encodeWithSelector( - IL1ERC20Gateway.finalizeWithdrawERC20.selector, - address(l1USDC), - address(l2USDC), - sender, - recipient, - amount, - dataToCall - ); - bytes memory xDomainCalldata = abi.encodeWithSignature( - "relayMessage(address,address,uint256,uint256,bytes)", - address(uint160(address(counterpartGateway)) + 1), - address(gateway), - 0, - 0, - message - ); - - prepareL2MessageRoot(keccak256(xDomainCalldata)); - - IL1ScrollMessenger.L2MessageProof memory proof; - proof.batchIndex = rollup.lastFinalizedBatchIndex(); - - // conterpart is not L2USDCGateway - // emit FailedRelayedMessage from L1ScrollMessenger - hevm.expectEmit(true, false, false, true); - emit FailedRelayedMessage(keccak256(xDomainCalldata)); - - uint256 gatewayBalance = l1USDC.balanceOf(address(gateway)); - uint256 recipientBalance = l1USDC.balanceOf(recipient); - assertBoolEq(false, l1Messenger.isL2MessageExecuted(keccak256(xDomainCalldata))); - l1Messenger.relayMessageWithProof( - address(uint160(address(counterpartGateway)) + 1), - address(gateway), - 0, - 0, - message, - proof - ); - assertEq(gatewayBalance, l1USDC.balanceOf(address(gateway))); - assertEq(recipientBalance, l1USDC.balanceOf(recipient)); - assertBoolEq(false, l1Messenger.isL2MessageExecuted(keccak256(xDomainCalldata))); - } - - function testFinalizeWithdrawERC20( - address sender, - uint256 amount, - bytes memory dataToCall - ) public { - MockGatewayRecipient recipient = new MockGatewayRecipient(); - - amount = bound(amount, 1, l1USDC.balanceOf(address(this))); - - // deposit some USDC to gateway - gateway.depositERC20(address(l1USDC), amount, defaultGasLimit); - - // do finalize withdraw usdc - bytes memory message = abi.encodeWithSelector( - IL1ERC20Gateway.finalizeWithdrawERC20.selector, - address(l1USDC), - address(l2USDC), - sender, - address(recipient), - amount, - dataToCall - ); - bytes memory xDomainCalldata = abi.encodeWithSignature( - "relayMessage(address,address,uint256,uint256,bytes)", - address(counterpartGateway), - address(gateway), - 0, - 0, - message - ); - - prepareL2MessageRoot(keccak256(xDomainCalldata)); - - IL1ScrollMessenger.L2MessageProof memory proof; - proof.batchIndex = rollup.lastFinalizedBatchIndex(); - - // emit FinalizeWithdrawERC20 from L1USDCGateway - { - hevm.expectEmit(true, true, true, true); - emit FinalizeWithdrawERC20( - address(l1USDC), - address(l2USDC), - sender, - address(recipient), - amount, - dataToCall - ); - } - - // emit RelayedMessage from L1ScrollMessenger - { - hevm.expectEmit(true, false, false, true); - emit RelayedMessage(keccak256(xDomainCalldata)); - } - - uint256 gatewayBalance = l1USDC.balanceOf(address(gateway)); - uint256 totalBridgedUSDCBefore = gateway.totalBridgedUSDC(); - uint256 recipientBalance = l1USDC.balanceOf(address(recipient)); - assertBoolEq(false, l1Messenger.isL2MessageExecuted(keccak256(xDomainCalldata))); - l1Messenger.relayMessageWithProof(address(counterpartGateway), address(gateway), 0, 0, message, proof); - assertEq(gatewayBalance - amount, l1USDC.balanceOf(address(gateway))); - assertEq(totalBridgedUSDCBefore - amount, gateway.totalBridgedUSDC()); - assertEq(recipientBalance + amount, l1USDC.balanceOf(address(recipient))); - assertBoolEq(true, l1Messenger.isL2MessageExecuted(keccak256(xDomainCalldata))); - } - - function _depositERC20( - bool useRouter, - uint256 amount, - uint256 gasLimit, - uint256 feePerGas - ) private { - amount = bound(amount, 0, l1USDC.balanceOf(address(this))); - gasLimit = bound(gasLimit, defaultGasLimit / 2, defaultGasLimit); - feePerGas = bound(feePerGas, 0, 1000); - - messageQueue.setL2BaseFee(feePerGas); - - uint256 feeToPay = feePerGas * gasLimit; - bytes memory message = abi.encodeWithSelector( - IL2ERC20Gateway.finalizeDepositERC20.selector, - address(l1USDC), - address(l2USDC), - address(this), - address(this), - amount, - new bytes(0) - ); - bytes memory xDomainCalldata = abi.encodeWithSignature( - "relayMessage(address,address,uint256,uint256,bytes)", - address(gateway), - address(counterpartGateway), - 0, - 0, - message - ); - - if (amount == 0) { - hevm.expectRevert("deposit zero amount"); - if (useRouter) { - router.depositERC20{value: feeToPay + extraValue}(address(l1USDC), amount, gasLimit); - } else { - gateway.depositERC20{value: feeToPay + extraValue}(address(l1USDC), amount, gasLimit); - } - } else { - // token is not l1USDC - hevm.expectRevert("only USDC is allowed"); - gateway.depositERC20(address(l2USDC), amount, gasLimit); - - // emit QueueTransaction from L1MessageQueue - { - hevm.expectEmit(true, true, false, true); - address sender = AddressAliasHelper.applyL1ToL2Alias(address(l1Messenger)); - emit QueueTransaction(sender, address(l2Messenger), 0, 0, gasLimit, xDomainCalldata); - } - - // emit SentMessage from L1ScrollMessenger - { - hevm.expectEmit(true, true, false, true); - emit SentMessage(address(gateway), address(counterpartGateway), 0, 0, gasLimit, message); - } - - // emit DepositERC20 from L1USDCGateway - hevm.expectEmit(true, true, true, true); - emit DepositERC20(address(l1USDC), address(l2USDC), address(this), address(this), amount, new bytes(0)); - - uint256 gatewayBalance = l1USDC.balanceOf(address(gateway)); - uint256 totalBridgedUSDCBefore = gateway.totalBridgedUSDC(); - uint256 feeVaultBalance = address(feeVault).balance; - assertEq(0, l1Messenger.messageSendTimestamp(keccak256(xDomainCalldata))); - if (useRouter) { - router.depositERC20{value: feeToPay + extraValue}(address(l1USDC), amount, gasLimit); - } else { - gateway.depositERC20{value: feeToPay + extraValue}(address(l1USDC), amount, gasLimit); - } - assertEq(amount + gatewayBalance, l1USDC.balanceOf(address(gateway))); - assertEq(amount + totalBridgedUSDCBefore, gateway.totalBridgedUSDC()); - assertEq(feeToPay + feeVaultBalance, address(feeVault).balance); - assertGt(l1Messenger.messageSendTimestamp(keccak256(xDomainCalldata)), 0); - } - } - - function _depositERC20WithRecipient( - bool useRouter, - uint256 amount, - address recipient, - uint256 gasLimit, - uint256 feePerGas - ) private { - amount = bound(amount, 0, l1USDC.balanceOf(address(this))); - gasLimit = bound(gasLimit, defaultGasLimit / 2, defaultGasLimit); - feePerGas = bound(feePerGas, 0, 1000); - - messageQueue.setL2BaseFee(feePerGas); - - uint256 feeToPay = feePerGas * gasLimit; - bytes memory message = abi.encodeWithSelector( - IL2ERC20Gateway.finalizeDepositERC20.selector, - address(l1USDC), - address(l2USDC), - address(this), - recipient, - amount, - new bytes(0) - ); - bytes memory xDomainCalldata = abi.encodeWithSignature( - "relayMessage(address,address,uint256,uint256,bytes)", - address(gateway), - address(counterpartGateway), - 0, - 0, - message - ); - - if (amount == 0) { - hevm.expectRevert("deposit zero amount"); - if (useRouter) { - router.depositERC20{value: feeToPay + extraValue}(address(l1USDC), recipient, amount, gasLimit); - } else { - gateway.depositERC20{value: feeToPay + extraValue}(address(l1USDC), recipient, amount, gasLimit); - } - } else { - // token is not l1USDC - hevm.expectRevert("only USDC is allowed"); - gateway.depositERC20(address(l2USDC), recipient, amount, gasLimit); - - // emit QueueTransaction from L1MessageQueue - { - hevm.expectEmit(true, true, false, true); - address sender = AddressAliasHelper.applyL1ToL2Alias(address(l1Messenger)); - emit QueueTransaction(sender, address(l2Messenger), 0, 0, gasLimit, xDomainCalldata); - } - - // emit SentMessage from L1ScrollMessenger - { - hevm.expectEmit(true, true, false, true); - emit SentMessage(address(gateway), address(counterpartGateway), 0, 0, gasLimit, message); - } - - // emit DepositERC20 from L1USDCGateway - hevm.expectEmit(true, true, true, true); - emit DepositERC20(address(l1USDC), address(l2USDC), address(this), recipient, amount, new bytes(0)); - - uint256 gatewayBalance = l1USDC.balanceOf(address(gateway)); - uint256 totalBridgedUSDCBefore = gateway.totalBridgedUSDC(); - uint256 feeVaultBalance = address(feeVault).balance; - assertEq(0, l1Messenger.messageSendTimestamp(keccak256(xDomainCalldata))); - if (useRouter) { - router.depositERC20{value: feeToPay + extraValue}(address(l1USDC), recipient, amount, gasLimit); - } else { - gateway.depositERC20{value: feeToPay + extraValue}(address(l1USDC), recipient, amount, gasLimit); - } - assertEq(amount + gatewayBalance, l1USDC.balanceOf(address(gateway))); - assertEq(amount + totalBridgedUSDCBefore, gateway.totalBridgedUSDC()); - assertEq(feeToPay + feeVaultBalance, address(feeVault).balance); - assertGt(l1Messenger.messageSendTimestamp(keccak256(xDomainCalldata)), 0); - } - } - - function _deployGateway(address messenger) internal returns (L1USDCGateway _gateway) { - _gateway = L1USDCGateway(_deployProxy(address(0))); - - admin.upgrade( - ITransparentUpgradeableProxy(address(_gateway)), - address( - new L1USDCGateway( - address(l1USDC), - address(l2USDC), - address(counterpartGateway), - address(router), - address(messenger) - ) - ) - ); - } -} diff --git a/contracts/src/test/L1WETHGateway.t.sol b/contracts/src/test/L1WETHGateway.t.sol deleted file mode 100644 index f2a14425d..000000000 --- a/contracts/src/test/L1WETHGateway.t.sol +++ /dev/null @@ -1,707 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {WETH} from "solmate/tokens/WETH.sol"; - -import {ITransparentUpgradeableProxy} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; - -import {L1GatewayRouter} from "../L1/gateways/L1GatewayRouter.sol"; -import {IL1ERC20Gateway, L1WETHGateway} from "../L1/gateways/L1WETHGateway.sol"; -import {IL1ScrollMessenger} from "../L1/IL1ScrollMessenger.sol"; -import {IL2ERC20Gateway, L2WETHGateway} from "../L2/gateways/L2WETHGateway.sol"; -import {AddressAliasHelper} from "../libraries/common/AddressAliasHelper.sol"; -import {ScrollConstants} from "../libraries/constants/ScrollConstants.sol"; - -import {L1GatewayTestBase} from "./L1GatewayTestBase.t.sol"; -import {MockScrollMessenger} from "./mocks/MockScrollMessenger.sol"; -import {MockGatewayRecipient} from "./mocks/MockGatewayRecipient.sol"; - -contract L1WETHGatewayTest is L1GatewayTestBase { - // from L1WETHGateway - event FinalizeWithdrawERC20( - address indexed _l1weth, - address indexed _l2weth, - address indexed _from, - address _to, - uint256 _amount, - bytes _data - ); - event DepositERC20( - address indexed _l1weth, - address indexed _l2weth, - address indexed _from, - address _to, - uint256 _amount, - bytes _data - ); - event RefundERC20(address indexed token, address indexed recipient, uint256 amount); - - WETH private l1weth; - WETH private l2weth; - - L1WETHGateway private gateway; - L1GatewayRouter private router; - - L2WETHGateway private counterpartGateway; - - function setUp() public { - __L1GatewayTestBase_setUp(); - - // Deploy tokens - l1weth = new WETH(); - l2weth = new WETH(); - - // Deploy L2 contracts - counterpartGateway = new L2WETHGateway(address(l2weth), address(l1weth), address(1), address(1), address(1)); - - // Deploy L1 contracts - router = L1GatewayRouter(_deployProxy(address(new L1GatewayRouter()))); - gateway = _deployGateway(address(l1Messenger)); - - // Initialize L1 contracts - gateway.initialize(address(counterpartGateway), address(router), address(l1Messenger)); - router.initialize(address(0), address(gateway)); - - // Prepare token balances - l1weth.deposit{value: address(this).balance / 2}(); - l1weth.approve(address(gateway), type(uint256).max); - l1weth.approve(address(router), type(uint256).max); - } - - function testInitialized() public { - assertEq(address(counterpartGateway), gateway.counterpart()); - assertEq(address(router), gateway.router()); - assertEq(address(l1Messenger), gateway.messenger()); - assertEq(address(l1weth), gateway.WETH()); - assertEq(address(l2weth), gateway.l2WETH()); - assertEq(address(l2weth), gateway.getL2ERC20Address(address(l1weth))); - - hevm.expectRevert("Initializable: contract is already initialized"); - gateway.initialize(address(counterpartGateway), address(router), address(l1Messenger)); - } - - function testDirectTransferETH(uint256 amount) public { - amount = bound(amount, 0, address(this).balance); - // solhint-disable-next-line avoid-low-level-calls - (bool success, bytes memory result) = address(gateway).call{value: amount}(""); - assertBoolEq(success, false); - assertEq(string(result), string(abi.encodeWithSignature("Error(string)", "only WETH"))); - } - - function testDepositERC20( - uint256 amount, - uint256 gasLimit, - uint256 feePerGas - ) public { - _depositERC20(false, amount, gasLimit, feePerGas); - } - - function testDepositERC20WithRecipient( - uint256 amount, - address recipient, - uint256 gasLimit, - uint256 feePerGas - ) public { - _depositERC20WithRecipient(false, amount, recipient, gasLimit, feePerGas); - } - - function testDepositERC20WithRecipientAndCalldata( - uint256 amount, - address recipient, - bytes memory dataToCall, - uint256 gasLimit, - uint256 feePerGas - ) public { - _depositERC20WithRecipientAndCalldata(false, amount, recipient, dataToCall, gasLimit, feePerGas); - } - - function testRouterDepositERC20( - uint256 amount, - uint256 gasLimit, - uint256 feePerGas - ) public { - _depositERC20(true, amount, gasLimit, feePerGas); - } - - function testRouterDepositERC20WithRecipient( - uint256 amount, - address recipient, - uint256 gasLimit, - uint256 feePerGas - ) public { - _depositERC20WithRecipient(true, amount, recipient, gasLimit, feePerGas); - } - - function testRouterDepositERC20WithRecipientAndCalldata( - uint256 amount, - address recipient, - bytes memory dataToCall, - uint256 gasLimit, - uint256 feePerGas - ) public { - _depositERC20WithRecipientAndCalldata(true, amount, recipient, dataToCall, gasLimit, feePerGas); - } - - function testDropMessageMocking() public { - MockScrollMessenger mockMessenger = new MockScrollMessenger(); - gateway = _deployGateway(address(mockMessenger)); - gateway.initialize(address(counterpartGateway), address(router), address(mockMessenger)); - - // only messenger can call, revert - hevm.expectRevert(ErrorCallerIsNotMessenger.selector); - gateway.onDropMessage(new bytes(0)); - - // only called in drop context, revert - hevm.expectRevert(ErrorNotInDropMessageContext.selector); - mockMessenger.callTarget( - address(gateway), - abi.encodeWithSelector(gateway.onDropMessage.selector, new bytes(0)) - ); - - mockMessenger.setXDomainMessageSender(ScrollConstants.DROP_XDOMAIN_MESSAGE_SENDER); - - // invalid selector, revert - hevm.expectRevert("invalid selector"); - mockMessenger.callTarget( - address(gateway), - abi.encodeWithSelector(gateway.onDropMessage.selector, new bytes(4)) - ); - - bytes memory message = abi.encodeWithSelector( - IL2ERC20Gateway.finalizeDepositERC20.selector, - address(l1weth), - address(l2weth), - address(this), - address(this), - 100, - new bytes(0) - ); - - // token not WETH, revert - hevm.expectRevert("token not WETH"); - mockMessenger.callTarget( - address(gateway), - abi.encodeWithSelector( - gateway.onDropMessage.selector, - abi.encodeWithSelector( - IL2ERC20Gateway.finalizeDepositERC20.selector, - address(l2weth), - address(l2weth), - address(this), - address(this), - 100, - new bytes(0) - ) - ) - ); - - // msg.value mismatch, revert - hevm.expectRevert("msg.value mismatch"); - mockMessenger.callTarget{value: 99}( - address(gateway), - abi.encodeWithSelector(gateway.onDropMessage.selector, message) - ); - } - - function testDropMessage( - uint256 amount, - address recipient, - bytes memory dataToCall - ) public { - amount = bound(amount, 1, l1weth.balanceOf(address(this))); - bytes memory message = abi.encodeWithSelector( - IL2ERC20Gateway.finalizeDepositERC20.selector, - address(l1weth), - address(l2weth), - address(this), - recipient, - amount, - dataToCall - ); - gateway.depositERC20AndCall(address(l1weth), recipient, amount, dataToCall, defaultGasLimit); - - // skip message 0 - hevm.startPrank(address(rollup)); - messageQueue.popCrossDomainMessage(0, 1, 0x1); - assertEq(messageQueue.pendingQueueIndex(), 1); - hevm.stopPrank(); - - // drop message 0 - hevm.expectEmit(true, true, false, true); - emit RefundERC20(address(l1weth), address(this), amount); - - uint256 balance = l1weth.balanceOf(address(this)); - l1Messenger.dropMessage(address(gateway), address(counterpartGateway), amount, 0, message); - assertEq(balance + amount, l1weth.balanceOf(address(this))); - } - - function testFinalizeWithdrawERC20FailedMocking( - address sender, - address recipient, - uint256 amount, - bytes memory dataToCall - ) public { - amount = bound(amount, 1, 100000); - - // revert when caller is not messenger - hevm.expectRevert(ErrorCallerIsNotMessenger.selector); - gateway.finalizeWithdrawERC20(address(l1weth), address(l2weth), sender, recipient, amount, dataToCall); - - MockScrollMessenger mockMessenger = new MockScrollMessenger(); - gateway = _deployGateway(address(mockMessenger)); - gateway.initialize(address(counterpartGateway), address(router), address(mockMessenger)); - - // only call by counterpart - hevm.expectRevert(ErrorCallerIsNotCounterpartGateway.selector); - mockMessenger.callTarget( - address(gateway), - abi.encodeWithSelector( - gateway.finalizeWithdrawERC20.selector, - address(l1weth), - address(l2weth), - sender, - recipient, - amount, - dataToCall - ) - ); - - mockMessenger.setXDomainMessageSender(address(counterpartGateway)); - - // l1 token not WETH - hevm.expectRevert("l1 token not WETH"); - mockMessenger.callTarget( - address(gateway), - abi.encodeWithSelector( - gateway.finalizeWithdrawERC20.selector, - address(l2weth), - address(l2weth), - sender, - recipient, - amount, - dataToCall - ) - ); - - // l2 token not WETH - hevm.expectRevert("l2 token not WETH"); - mockMessenger.callTarget( - address(gateway), - abi.encodeWithSelector( - gateway.finalizeWithdrawERC20.selector, - address(l1weth), - address(l1weth), - sender, - recipient, - amount, - dataToCall - ) - ); - - // msg.value mismatch - hevm.expectRevert("msg.value mismatch"); - mockMessenger.callTarget( - address(gateway), - abi.encodeWithSelector( - gateway.finalizeWithdrawERC20.selector, - address(l1weth), - address(l2weth), - sender, - recipient, - amount, - dataToCall - ) - ); - } - - function testFinalizeWithdrawERC20Failed( - address sender, - address recipient, - uint256 amount, - bytes memory dataToCall - ) public { - // blacklist some addresses - hevm.assume(recipient != address(0)); - hevm.assume(recipient != address(gateway)); - - amount = bound(amount, 1, l1weth.balanceOf(address(this))); - - // deposit some WETH to L1ScrollMessenger - gateway.depositERC20(address(l1weth), amount, defaultGasLimit); - - // do finalize withdraw eth - bytes memory message = abi.encodeWithSelector( - IL1ERC20Gateway.finalizeWithdrawERC20.selector, - address(l1weth), - address(l2weth), - sender, - recipient, - amount, - dataToCall - ); - bytes memory xDomainCalldata = abi.encodeWithSignature( - "relayMessage(address,address,uint256,uint256,bytes)", - address(uint160(address(counterpartGateway)) + 1), - address(gateway), - amount, - 0, - message - ); - - prepareL2MessageRoot(keccak256(xDomainCalldata)); - - IL1ScrollMessenger.L2MessageProof memory proof; - proof.batchIndex = rollup.lastFinalizedBatchIndex(); - - // counterpart is not L2WETHGateway - // emit FailedRelayedMessage from L1ScrollMessenger - hevm.expectEmit(true, false, false, true); - emit FailedRelayedMessage(keccak256(xDomainCalldata)); - - uint256 messengerBalance = address(l1Messenger).balance; - uint256 recipientBalance = l1weth.balanceOf(recipient); - assertBoolEq(false, l1Messenger.isL2MessageExecuted(keccak256(xDomainCalldata))); - l1Messenger.relayMessageWithProof( - address(uint160(address(counterpartGateway)) + 1), - address(gateway), - amount, - 0, - message, - proof - ); - assertEq(messengerBalance, address(l1Messenger).balance); - assertEq(recipientBalance, l1weth.balanceOf(recipient)); - assertBoolEq(false, l1Messenger.isL2MessageExecuted(keccak256(xDomainCalldata))); - } - - function testFinalizeWithdrawERC20( - address sender, - uint256 amount, - bytes memory dataToCall - ) public { - MockGatewayRecipient recipient = new MockGatewayRecipient(); - - amount = bound(amount, 1, l1weth.balanceOf(address(this))); - - // deposit some WETH to L1ScrollMessenger - gateway.depositERC20(address(l1weth), amount, defaultGasLimit); - - // do finalize withdraw eth - bytes memory message = abi.encodeWithSelector( - IL1ERC20Gateway.finalizeWithdrawERC20.selector, - address(l1weth), - address(l2weth), - sender, - address(recipient), - amount, - dataToCall - ); - bytes memory xDomainCalldata = abi.encodeWithSignature( - "relayMessage(address,address,uint256,uint256,bytes)", - address(counterpartGateway), - address(gateway), - amount, - 0, - message - ); - - prepareL2MessageRoot(keccak256(xDomainCalldata)); - - IL1ScrollMessenger.L2MessageProof memory proof; - proof.batchIndex = rollup.lastFinalizedBatchIndex(); - - // emit FinalizeWithdrawERC20 from L1WETHGateway - { - hevm.expectEmit(true, true, true, true); - emit FinalizeWithdrawERC20( - address(l1weth), - address(l2weth), - sender, - address(recipient), - amount, - dataToCall - ); - } - - // emit RelayedMessage from L1ScrollMessenger - { - hevm.expectEmit(true, false, false, true); - emit RelayedMessage(keccak256(xDomainCalldata)); - } - - uint256 messengerBalance = address(l1Messenger).balance; - uint256 recipientBalance = l1weth.balanceOf(address(recipient)); - assertBoolEq(false, l1Messenger.isL2MessageExecuted(keccak256(xDomainCalldata))); - l1Messenger.relayMessageWithProof(address(counterpartGateway), address(gateway), amount, 0, message, proof); - assertEq(messengerBalance - amount, address(l1Messenger).balance); - assertEq(recipientBalance + amount, l1weth.balanceOf(address(recipient))); - assertBoolEq(true, l1Messenger.isL2MessageExecuted(keccak256(xDomainCalldata))); - } - - function _depositERC20( - bool useRouter, - uint256 amount, - uint256 gasLimit, - uint256 feePerGas - ) private { - amount = bound(amount, 0, l1weth.balanceOf(address(this))); - gasLimit = bound(gasLimit, defaultGasLimit / 2, defaultGasLimit); - feePerGas = bound(feePerGas, 0, 1000); - - messageQueue.setL2BaseFee(feePerGas); - - uint256 feeToPay = feePerGas * gasLimit; - bytes memory message = abi.encodeWithSelector( - IL2ERC20Gateway.finalizeDepositERC20.selector, - address(l1weth), - address(l2weth), - address(this), - address(this), - amount, - new bytes(0) - ); - bytes memory xDomainCalldata = abi.encodeWithSignature( - "relayMessage(address,address,uint256,uint256,bytes)", - address(gateway), - address(counterpartGateway), - amount, - 0, - message - ); - - if (amount == 0) { - hevm.expectRevert("deposit zero amount"); - if (useRouter) { - router.depositERC20{value: feeToPay + extraValue}(address(l1weth), amount, gasLimit); - } else { - gateway.depositERC20{value: feeToPay + extraValue}(address(l1weth), amount, gasLimit); - } - } else { - // token is not l1WETH - hevm.expectRevert("only WETH is allowed"); - gateway.depositERC20(address(l2weth), amount, gasLimit); - - // emit QueueTransaction from L1MessageQueue - { - hevm.expectEmit(true, true, false, true); - address sender = AddressAliasHelper.applyL1ToL2Alias(address(l1Messenger)); - emit QueueTransaction(sender, address(l2Messenger), 0, 0, gasLimit, xDomainCalldata); - } - - // emit SentMessage from L1ScrollMessenger - { - hevm.expectEmit(true, true, false, true); - emit SentMessage(address(gateway), address(counterpartGateway), amount, 0, gasLimit, message); - } - - // emit DepositERC20 from L1WETHGateway - hevm.expectEmit(true, true, true, true); - emit DepositERC20(address(l1weth), address(l2weth), address(this), address(this), amount, new bytes(0)); - - uint256 messengerBalance = address(l1Messenger).balance; - uint256 feeVaultBalance = address(feeVault).balance; - assertEq(l1Messenger.messageSendTimestamp(keccak256(xDomainCalldata)), 0); - if (useRouter) { - router.depositERC20{value: feeToPay + extraValue}(address(l1weth), amount, gasLimit); - } else { - gateway.depositERC20{value: feeToPay + extraValue}(address(l1weth), amount, gasLimit); - } - assertEq(amount + messengerBalance, address(l1Messenger).balance); - assertEq(feeToPay + feeVaultBalance, address(feeVault).balance); - assertGt(l1Messenger.messageSendTimestamp(keccak256(xDomainCalldata)), 0); - } - } - - function _depositERC20WithRecipient( - bool useRouter, - uint256 amount, - address recipient, - uint256 gasLimit, - uint256 feePerGas - ) private { - amount = bound(amount, 0, l1weth.balanceOf(address(this))); - gasLimit = bound(gasLimit, defaultGasLimit / 2, defaultGasLimit); - feePerGas = bound(feePerGas, 0, 1000); - - messageQueue.setL2BaseFee(feePerGas); - - uint256 feeToPay = feePerGas * gasLimit; - bytes memory message = abi.encodeWithSelector( - IL2ERC20Gateway.finalizeDepositERC20.selector, - address(l1weth), - address(l2weth), - address(this), - recipient, - amount, - new bytes(0) - ); - bytes memory xDomainCalldata = abi.encodeWithSignature( - "relayMessage(address,address,uint256,uint256,bytes)", - address(gateway), - address(counterpartGateway), - amount, - 0, - message - ); - - if (amount == 0) { - hevm.expectRevert("deposit zero amount"); - if (useRouter) { - router.depositERC20{value: feeToPay + extraValue}(address(l1weth), recipient, amount, gasLimit); - } else { - gateway.depositERC20{value: feeToPay + extraValue}(address(l1weth), recipient, amount, gasLimit); - } - } else { - // token is not l1WETH - hevm.expectRevert("only WETH is allowed"); - gateway.depositERC20(address(l2weth), recipient, amount, gasLimit); - - // emit QueueTransaction from L1MessageQueue - { - hevm.expectEmit(true, true, false, true); - address sender = AddressAliasHelper.applyL1ToL2Alias(address(l1Messenger)); - emit QueueTransaction(sender, address(l2Messenger), 0, 0, gasLimit, xDomainCalldata); - } - - // emit SentMessage from L1ScrollMessenger - { - hevm.expectEmit(true, true, false, true); - emit SentMessage(address(gateway), address(counterpartGateway), amount, 0, gasLimit, message); - } - - // emit DepositERC20 from L1WETHGateway - hevm.expectEmit(true, true, true, true); - emit DepositERC20(address(l1weth), address(l2weth), address(this), recipient, amount, new bytes(0)); - - uint256 messengerBalance = address(l1Messenger).balance; - uint256 feeVaultBalance = address(feeVault).balance; - assertEq(l1Messenger.messageSendTimestamp(keccak256(xDomainCalldata)), 0); - if (useRouter) { - router.depositERC20{value: feeToPay + extraValue}(address(l1weth), recipient, amount, gasLimit); - } else { - gateway.depositERC20{value: feeToPay + extraValue}(address(l1weth), recipient, amount, gasLimit); - } - assertEq(amount + messengerBalance, address(l1Messenger).balance); - assertEq(feeToPay + feeVaultBalance, address(feeVault).balance); - assertGt(l1Messenger.messageSendTimestamp(keccak256(xDomainCalldata)), 0); - } - } - - function _depositERC20WithRecipientAndCalldata( - bool useRouter, - uint256 amount, - address recipient, - bytes memory dataToCall, - uint256 gasLimit, - uint256 feePerGas - ) private { - amount = bound(amount, 0, l1weth.balanceOf(address(this))); - gasLimit = bound(gasLimit, defaultGasLimit / 2, defaultGasLimit); - feePerGas = bound(feePerGas, 0, 1000); - - messageQueue.setL2BaseFee(feePerGas); - - uint256 feeToPay = feePerGas * gasLimit; - bytes memory message = abi.encodeWithSelector( - IL2ERC20Gateway.finalizeDepositERC20.selector, - address(l1weth), - address(l2weth), - address(this), - recipient, - amount, - dataToCall - ); - bytes memory xDomainCalldata = abi.encodeWithSignature( - "relayMessage(address,address,uint256,uint256,bytes)", - address(gateway), - address(counterpartGateway), - amount, - 0, - message - ); - - if (amount == 0) { - hevm.expectRevert("deposit zero amount"); - if (useRouter) { - router.depositERC20AndCall{value: feeToPay + extraValue}( - address(l1weth), - recipient, - amount, - dataToCall, - gasLimit - ); - } else { - gateway.depositERC20AndCall{value: feeToPay + extraValue}( - address(l1weth), - recipient, - amount, - dataToCall, - gasLimit - ); - } - } else { - // token is not l1WETH - hevm.expectRevert("only WETH is allowed"); - gateway.depositERC20AndCall(address(l2weth), recipient, amount, dataToCall, gasLimit); - - // emit QueueTransaction from L1MessageQueue - { - hevm.expectEmit(true, true, false, true); - address sender = AddressAliasHelper.applyL1ToL2Alias(address(l1Messenger)); - emit QueueTransaction(sender, address(l2Messenger), 0, 0, gasLimit, xDomainCalldata); - } - - // emit SentMessage from L1ScrollMessenger - { - hevm.expectEmit(true, true, false, true); - emit SentMessage(address(gateway), address(counterpartGateway), amount, 0, gasLimit, message); - } - - // emit DepositERC20 from L1WETHGateway - hevm.expectEmit(true, true, true, true); - emit DepositERC20(address(l1weth), address(l2weth), address(this), recipient, amount, dataToCall); - - uint256 messengerBalance = address(l1Messenger).balance; - uint256 feeVaultBalance = address(feeVault).balance; - assertEq(l1Messenger.messageSendTimestamp(keccak256(xDomainCalldata)), 0); - if (useRouter) { - router.depositERC20AndCall{value: feeToPay + extraValue}( - address(l1weth), - recipient, - amount, - dataToCall, - gasLimit - ); - } else { - gateway.depositERC20AndCall{value: feeToPay + extraValue}( - address(l1weth), - recipient, - amount, - dataToCall, - gasLimit - ); - } - assertEq(amount + messengerBalance, address(l1Messenger).balance); - assertEq(feeToPay + feeVaultBalance, address(feeVault).balance); - assertGt(l1Messenger.messageSendTimestamp(keccak256(xDomainCalldata)), 0); - } - } - - function _deployGateway(address messenger) internal returns (L1WETHGateway _gateway) { - _gateway = L1WETHGateway(payable(_deployProxy(address(0)))); - - admin.upgrade( - ITransparentUpgradeableProxy(address(_gateway)), - address( - new L1WETHGateway( - address(l1weth), - address(l2weth), - address(counterpartGateway), - address(router), - address(messenger) - ) - ) - ); - } -} diff --git a/contracts/src/test/L2CustomERC20Gateway.t.sol b/contracts/src/test/L2CustomERC20Gateway.t.sol deleted file mode 100644 index 5a0838f2f..000000000 --- a/contracts/src/test/L2CustomERC20Gateway.t.sol +++ /dev/null @@ -1,583 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {MockERC20} from "solmate/test/utils/mocks/MockERC20.sol"; - -import {ITransparentUpgradeableProxy} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; - -import {IL1ERC20Gateway, L1CustomERC20Gateway} from "../L1/gateways/L1CustomERC20Gateway.sol"; -import {IL2ERC20Gateway, L2CustomERC20Gateway} from "../L2/gateways/L2CustomERC20Gateway.sol"; -import {L2GatewayRouter} from "../L2/gateways/L2GatewayRouter.sol"; - -import {AddressAliasHelper} from "../libraries/common/AddressAliasHelper.sol"; - -import {L2GatewayTestBase} from "./L2GatewayTestBase.t.sol"; -import {MockScrollMessenger} from "./mocks/MockScrollMessenger.sol"; -import {MockGatewayRecipient} from "./mocks/MockGatewayRecipient.sol"; - -contract L2CustomERC20GatewayTest is L2GatewayTestBase { - // from L1CustomERC20Gateway - event WithdrawERC20( - address indexed _l1Token, - address indexed _l2Token, - address indexed _from, - address _to, - uint256 _amount, - bytes _data - ); - event FinalizeDepositERC20( - address indexed _l1Token, - address indexed _l2Token, - address indexed _from, - address _to, - uint256 _amount, - bytes _data - ); - - L2CustomERC20Gateway private gateway; - L2GatewayRouter private router; - - L1CustomERC20Gateway private counterpartGateway; - - MockERC20 private l1Token; - MockERC20 private l2Token; - - function setUp() public { - setUpBase(); - // Deploy tokens - l1Token = new MockERC20("Mock L1", "ML1", 18); - l2Token = new MockERC20("Mock L2", "ML2", 18); - - // Deploy L1 contracts - counterpartGateway = new L1CustomERC20Gateway(address(1), address(1), address(1)); - - // Deploy L2 contracts - router = L2GatewayRouter(_deployProxy(address(new L2GatewayRouter()))); - gateway = _deployGateway(address(l2Messenger)); - - // Initialize L2 contracts - gateway.initialize(address(counterpartGateway), address(router), address(l2Messenger)); - router.initialize(address(0), address(gateway)); - - // Prepare token balances - l2Token.mint(address(this), type(uint128).max); - l2Token.approve(address(gateway), type(uint256).max); - } - - function testInitialized() public { - assertEq(address(this), gateway.owner()); - assertEq(address(counterpartGateway), gateway.counterpart()); - assertEq(address(router), gateway.router()); - assertEq(address(l2Messenger), gateway.messenger()); - - assertEq(address(0), gateway.getL1ERC20Address(address(l2Token))); - - hevm.expectRevert("unimplemented"); - gateway.getL2ERC20Address(address(l1Token)); - - hevm.expectRevert("Initializable: contract is already initialized"); - gateway.initialize(address(counterpartGateway), address(router), address(l2Messenger)); - } - - function testUpdateTokenMappingFailed(address token2) public { - // call by non-owner, should revert - hevm.startPrank(address(1)); - hevm.expectRevert("Ownable: caller is not the owner"); - gateway.updateTokenMapping(token2, token2); - hevm.stopPrank(); - - // l1 token is zero, should revert - hevm.expectRevert("token address cannot be 0"); - gateway.updateTokenMapping(token2, address(0)); - } - - function testUpdateTokenMappingSuccess(address token1, address token2) public { - hevm.assume(token1 != address(0)); - - assertEq(gateway.getL1ERC20Address(token2), address(0)); - gateway.updateTokenMapping(token2, token1); - assertEq(gateway.getL1ERC20Address(token2), token1); - } - - function testWithdrawERC20( - uint256 amount, - uint256 gasLimit, - uint256 feePerGas - ) public { - _withdrawERC20(false, amount, gasLimit, feePerGas); - } - - function testWithdrawERC20WithRecipient( - uint256 amount, - address recipient, - uint256 gasLimit, - uint256 feePerGas - ) public { - _withdrawERC20WithRecipient(false, amount, recipient, gasLimit, feePerGas); - } - - function testWithdrawERC20WithRecipientAndCalldata( - uint256 amount, - address recipient, - bytes memory dataToCall, - uint256 gasLimit, - uint256 feePerGas - ) public { - _withdrawERC20WithRecipientAndCalldata(false, amount, recipient, dataToCall, gasLimit, feePerGas); - } - - function testWithdrawERC20ByRouter( - uint256 amount, - uint256 gasLimit, - uint256 feePerGas - ) public { - _withdrawERC20(true, amount, gasLimit, feePerGas); - } - - function testWithdrawERC20WithRecipientByRouter( - uint256 amount, - address recipient, - uint256 gasLimit, - uint256 feePerGas - ) public { - _withdrawERC20WithRecipient(true, amount, recipient, gasLimit, feePerGas); - } - - function testWithdrawERC20WithRecipientAndCalldataByRouter( - uint256 amount, - address recipient, - bytes memory dataToCall, - uint256 gasLimit, - uint256 feePerGas - ) public { - _withdrawERC20WithRecipientAndCalldata(true, amount, recipient, dataToCall, gasLimit, feePerGas); - } - - function testFinalizeDepositERC20FailedMocking( - address sender, - address recipient, - uint256 amount, - bytes memory dataToCall - ) public { - amount = bound(amount, 1, 100000); - - // revert when caller is not messenger - hevm.expectRevert(ErrorCallerIsNotMessenger.selector); - gateway.finalizeDepositERC20(address(l1Token), address(l2Token), sender, recipient, amount, dataToCall); - - MockScrollMessenger mockMessenger = new MockScrollMessenger(); - gateway = _deployGateway(address(mockMessenger)); - gateway.initialize(address(counterpartGateway), address(router), address(mockMessenger)); - - // only call by counterpart - hevm.expectRevert(ErrorCallerIsNotCounterpartGateway.selector); - mockMessenger.callTarget( - address(gateway), - abi.encodeWithSelector( - gateway.finalizeDepositERC20.selector, - address(l1Token), - address(l2Token), - sender, - recipient, - amount, - dataToCall - ) - ); - - mockMessenger.setXDomainMessageSender(address(counterpartGateway)); - - // msg.value mismatch - hevm.expectRevert("nonzero msg.value"); - mockMessenger.callTarget{value: 1}( - address(gateway), - abi.encodeWithSelector( - gateway.finalizeDepositERC20.selector, - address(l1Token), - address(l2Token), - sender, - recipient, - amount, - dataToCall - ) - ); - - // l1 token mismatch - hevm.expectRevert("l1 token mismatch"); - mockMessenger.callTarget( - address(gateway), - abi.encodeWithSelector( - gateway.finalizeDepositERC20.selector, - address(l1Token), - address(l2Token), - sender, - recipient, - amount, - dataToCall - ) - ); - } - - function testFinalizeDepositERC20Failed( - address sender, - address recipient, - uint256 amount, - bytes memory dataToCall - ) public { - // blacklist some addresses - hevm.assume(recipient != address(0)); - - gateway.updateTokenMapping(address(l2Token), address(l1Token)); - - amount = bound(amount, 1, l2Token.balanceOf(address(this))); - - // do finalize deposit token - bytes memory message = abi.encodeWithSelector( - IL2ERC20Gateway.finalizeDepositERC20.selector, - address(l1Token), - address(l2Token), - sender, - recipient, - amount, - dataToCall - ); - bytes memory xDomainCalldata = abi.encodeWithSignature( - "relayMessage(address,address,uint256,uint256,bytes)", - address(uint160(address(counterpartGateway)) + 1), - address(gateway), - 0, - 0, - message - ); - - // counterpart is not L1CustomERC20Gateway - // emit FailedRelayedMessage from L2ScrollMessenger - hevm.expectEmit(true, false, false, true); - emit FailedRelayedMessage(keccak256(xDomainCalldata)); - - uint256 gatewayBalance = l2Token.balanceOf(address(gateway)); - uint256 recipientBalance = l2Token.balanceOf(recipient); - assertBoolEq(false, l2Messenger.isL1MessageExecuted(keccak256(xDomainCalldata))); - hevm.startPrank(AddressAliasHelper.applyL1ToL2Alias(address(l1Messenger))); - l2Messenger.relayMessage(address(uint160(address(counterpartGateway)) + 1), address(gateway), 0, 0, message); - hevm.stopPrank(); - assertEq(gatewayBalance, l2Token.balanceOf(address(gateway))); - assertEq(recipientBalance, l2Token.balanceOf(recipient)); - assertBoolEq(false, l2Messenger.isL1MessageExecuted(keccak256(xDomainCalldata))); - } - - function testFinalizeDepositERC20( - address sender, - uint256 amount, - bytes memory dataToCall - ) public { - MockGatewayRecipient recipient = new MockGatewayRecipient(); - - gateway.updateTokenMapping(address(l2Token), address(l1Token)); - - amount = bound(amount, 1, l2Token.balanceOf(address(this))); - - // do finalize deposit token - bytes memory message = abi.encodeWithSelector( - IL2ERC20Gateway.finalizeDepositERC20.selector, - address(l1Token), - address(l2Token), - sender, - address(recipient), - amount, - dataToCall - ); - bytes memory xDomainCalldata = abi.encodeWithSignature( - "relayMessage(address,address,uint256,uint256,bytes)", - address(counterpartGateway), - address(gateway), - 0, - 0, - message - ); - - // emit FinalizeDepositERC20 from L2CustomERC20Gateway - { - hevm.expectEmit(true, true, true, true); - emit FinalizeDepositERC20( - address(l1Token), - address(l2Token), - sender, - address(recipient), - amount, - dataToCall - ); - } - - // emit RelayedMessage from L2ScrollMessenger - { - hevm.expectEmit(true, false, false, true); - emit RelayedMessage(keccak256(xDomainCalldata)); - } - - uint256 gatewayBalance = l2Token.balanceOf(address(gateway)); - uint256 recipientBalance = l2Token.balanceOf(address(recipient)); - assertBoolEq(false, l2Messenger.isL1MessageExecuted(keccak256(xDomainCalldata))); - hevm.startPrank(AddressAliasHelper.applyL1ToL2Alias(address(l1Messenger))); - l2Messenger.relayMessage(address(counterpartGateway), address(gateway), 0, 0, message); - hevm.stopPrank(); - assertEq(gatewayBalance, l2Token.balanceOf(address(gateway))); - assertEq(recipientBalance + amount, l2Token.balanceOf(address(recipient))); - assertBoolEq(true, l2Messenger.isL1MessageExecuted(keccak256(xDomainCalldata))); - } - - function _withdrawERC20( - bool useRouter, - uint256 amount, - uint256 gasLimit, - uint256 feePerGas - ) private { - amount = bound(amount, 0, l2Token.balanceOf(address(this))); - gasLimit = bound(gasLimit, 21000, 1000000); - feePerGas = 0; - - setL1BaseFee(feePerGas); - - uint256 feeToPay = feePerGas * gasLimit; - bytes memory message = abi.encodeWithSelector( - IL1ERC20Gateway.finalizeWithdrawERC20.selector, - address(l1Token), - address(l2Token), - address(this), - address(this), - amount, - new bytes(0) - ); - bytes memory xDomainCalldata = abi.encodeWithSignature( - "relayMessage(address,address,uint256,uint256,bytes)", - address(gateway), - address(counterpartGateway), - 0, - 0, - message - ); - - hevm.expectRevert("no corresponding l1 token"); - if (useRouter) { - router.withdrawERC20{value: feeToPay}(address(l2Token), amount, gasLimit); - } else { - gateway.withdrawERC20{value: feeToPay}(address(l2Token), amount, gasLimit); - } - - gateway.updateTokenMapping(address(l2Token), address(l1Token)); - if (amount == 0) { - hevm.expectRevert("withdraw zero amount"); - if (useRouter) { - router.withdrawERC20{value: feeToPay}(address(l2Token), amount, gasLimit); - } else { - gateway.withdrawERC20{value: feeToPay}(address(l2Token), amount, gasLimit); - } - } else { - // emit AppendMessage from L2MessageQueue - { - hevm.expectEmit(false, false, false, true); - emit AppendMessage(0, keccak256(xDomainCalldata)); - } - - // emit SentMessage from L2ScrollMessenger - { - hevm.expectEmit(true, true, false, true); - emit SentMessage(address(gateway), address(counterpartGateway), 0, 0, gasLimit, message); - } - - // emit WithdrawERC20 from L2CustomERC20Gateway - hevm.expectEmit(true, true, true, true); - emit WithdrawERC20(address(l1Token), address(l2Token), address(this), address(this), amount, new bytes(0)); - - uint256 gatewayBalance = l2Token.balanceOf(address(gateway)); - uint256 feeVaultBalance = address(feeVault).balance; - assertEq(l2Messenger.messageSendTimestamp(keccak256(xDomainCalldata)), 0); - if (useRouter) { - router.withdrawERC20{value: feeToPay}(address(l2Token), amount, gasLimit); - } else { - gateway.withdrawERC20{value: feeToPay}(address(l2Token), amount, gasLimit); - } - assertEq(gatewayBalance, l1Token.balanceOf(address(gateway))); - assertEq(feeToPay + feeVaultBalance, address(feeVault).balance); - assertGt(l2Messenger.messageSendTimestamp(keccak256(xDomainCalldata)), 0); - } - } - - function _withdrawERC20WithRecipient( - bool useRouter, - uint256 amount, - address recipient, - uint256 gasLimit, - uint256 feePerGas - ) private { - amount = bound(amount, 0, l2Token.balanceOf(address(this))); - gasLimit = bound(gasLimit, 21000, 1000000); - feePerGas = 0; - - setL1BaseFee(feePerGas); - - uint256 feeToPay = feePerGas * gasLimit; - bytes memory message = abi.encodeWithSelector( - IL1ERC20Gateway.finalizeWithdrawERC20.selector, - address(l1Token), - address(l2Token), - address(this), - recipient, - amount, - new bytes(0) - ); - bytes memory xDomainCalldata = abi.encodeWithSignature( - "relayMessage(address,address,uint256,uint256,bytes)", - address(gateway), - address(counterpartGateway), - 0, - 0, - message - ); - - hevm.expectRevert("no corresponding l1 token"); - if (useRouter) { - router.withdrawERC20{value: feeToPay}(address(l2Token), amount, gasLimit); - } else { - gateway.withdrawERC20{value: feeToPay}(address(l2Token), amount, gasLimit); - } - - gateway.updateTokenMapping(address(l2Token), address(l1Token)); - if (amount == 0) { - hevm.expectRevert("withdraw zero amount"); - if (useRouter) { - router.withdrawERC20{value: feeToPay}(address(l2Token), recipient, amount, gasLimit); - } else { - gateway.withdrawERC20{value: feeToPay}(address(l2Token), recipient, amount, gasLimit); - } - } else { - // emit AppendMessage from L2MessageQueue - { - hevm.expectEmit(false, false, false, true); - emit AppendMessage(0, keccak256(xDomainCalldata)); - } - - // emit SentMessage from L2ScrollMessenger - { - hevm.expectEmit(true, true, false, true); - emit SentMessage(address(gateway), address(counterpartGateway), 0, 0, gasLimit, message); - } - - // emit WithdrawERC20 from L2CustomERC20Gateway - hevm.expectEmit(true, true, true, true); - emit WithdrawERC20(address(l1Token), address(l2Token), address(this), recipient, amount, new bytes(0)); - - uint256 gatewayBalance = l2Token.balanceOf(address(gateway)); - uint256 feeVaultBalance = address(feeVault).balance; - assertEq(l2Messenger.messageSendTimestamp(keccak256(xDomainCalldata)), 0); - if (useRouter) { - router.withdrawERC20{value: feeToPay}(address(l2Token), recipient, amount, gasLimit); - } else { - gateway.withdrawERC20{value: feeToPay}(address(l2Token), recipient, amount, gasLimit); - } - assertEq(gatewayBalance, l2Token.balanceOf(address(gateway))); - assertEq(feeToPay + feeVaultBalance, address(feeVault).balance); - assertGt(l2Messenger.messageSendTimestamp(keccak256(xDomainCalldata)), 0); - } - } - - function _withdrawERC20WithRecipientAndCalldata( - bool useRouter, - uint256 amount, - address recipient, - bytes memory dataToCall, - uint256 gasLimit, - uint256 feePerGas - ) private { - amount = bound(amount, 0, l2Token.balanceOf(address(this))); - gasLimit = bound(gasLimit, 21000, 1000000); - feePerGas = 0; - - setL1BaseFee(feePerGas); - - uint256 feeToPay = feePerGas * gasLimit; - bytes memory message = abi.encodeWithSelector( - IL1ERC20Gateway.finalizeWithdrawERC20.selector, - address(l1Token), - address(l2Token), - address(this), - recipient, - amount, - dataToCall - ); - bytes memory xDomainCalldata = abi.encodeWithSignature( - "relayMessage(address,address,uint256,uint256,bytes)", - address(gateway), - address(counterpartGateway), - 0, - 0, - message - ); - - hevm.expectRevert("no corresponding l1 token"); - if (useRouter) { - router.withdrawERC20{value: feeToPay}(address(l2Token), amount, gasLimit); - } else { - gateway.withdrawERC20{value: feeToPay}(address(l2Token), amount, gasLimit); - } - - gateway.updateTokenMapping(address(l2Token), address(l1Token)); - if (amount == 0) { - hevm.expectRevert("withdraw zero amount"); - if (useRouter) { - router.withdrawERC20AndCall{value: feeToPay}(address(l2Token), recipient, amount, dataToCall, gasLimit); - } else { - gateway.withdrawERC20AndCall{value: feeToPay}( - address(l2Token), - recipient, - amount, - dataToCall, - gasLimit - ); - } - } else { - // emit AppendMessage from L2MessageQueue - { - hevm.expectEmit(false, false, false, true); - emit AppendMessage(0, keccak256(xDomainCalldata)); - } - - // emit SentMessage from L2ScrollMessenger - { - hevm.expectEmit(true, true, false, true); - emit SentMessage(address(gateway), address(counterpartGateway), 0, 0, gasLimit, message); - } - - // emit WithdrawERC20 from L2CustomERC20Gateway - hevm.expectEmit(true, true, true, true); - emit WithdrawERC20(address(l1Token), address(l2Token), address(this), recipient, amount, dataToCall); - - uint256 gatewayBalance = l2Token.balanceOf(address(gateway)); - uint256 feeVaultBalance = address(feeVault).balance; - assertEq(l2Messenger.messageSendTimestamp(keccak256(xDomainCalldata)), 0); - if (useRouter) { - router.withdrawERC20AndCall{value: feeToPay}(address(l2Token), recipient, amount, dataToCall, gasLimit); - } else { - gateway.withdrawERC20AndCall{value: feeToPay}( - address(l2Token), - recipient, - amount, - dataToCall, - gasLimit - ); - } - assertEq(gatewayBalance, l2Token.balanceOf(address(gateway))); - assertEq(feeToPay + feeVaultBalance, address(feeVault).balance); - assertGt(l2Messenger.messageSendTimestamp(keccak256(xDomainCalldata)), 0); - } - } - - function _deployGateway(address messenger) internal returns (L2CustomERC20Gateway _gateway) { - _gateway = L2CustomERC20Gateway(_deployProxy(address(0))); - - admin.upgrade( - ITransparentUpgradeableProxy(address(_gateway)), - address(new L2CustomERC20Gateway(address(counterpartGateway), address(router), address(messenger))) - ); - } -} diff --git a/contracts/src/test/L2ERC1155Gateway.t.sol b/contracts/src/test/L2ERC1155Gateway.t.sol deleted file mode 100644 index b436306fd..000000000 --- a/contracts/src/test/L2ERC1155Gateway.t.sol +++ /dev/null @@ -1,374 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {DSTestPlus} from "solmate/test/utils/DSTestPlus.sol"; -import {MockERC1155} from "solmate/test/utils/mocks/MockERC1155.sol"; -import {ERC1155TokenReceiver} from "solmate/tokens/ERC1155.sol"; - -import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; - -import {L1ERC1155Gateway} from "../L1/gateways/L1ERC1155Gateway.sol"; -import {L2ERC1155Gateway} from "../L2/gateways/L2ERC1155Gateway.sol"; -import {MockScrollMessenger} from "./mocks/MockScrollMessenger.sol"; -import {MockERC1155Recipient} from "./mocks/MockERC1155Recipient.sol"; - -contract L2ERC1155GatewayTest is DSTestPlus, ERC1155TokenReceiver { - /********** - * Errors * - **********/ - - // from IScrollGateway - error ErrorZeroAddress(); - error ErrorCallerIsNotMessenger(); - error ErrorCallerIsNotCounterpartGateway(); - error ErrorNotInDropMessageContext(); - - uint256 private constant TOKEN_COUNT = 100; - - MockScrollMessenger private messenger; - L1ERC1155Gateway private counterpart; - L2ERC1155Gateway private gateway; - - MockERC1155 private token; - MockERC1155Recipient private mockRecipient; - - function setUp() public { - messenger = new MockScrollMessenger(); - counterpart = new L1ERC1155Gateway(address(1), address(1)); - - gateway = _deployGateway(address(messenger)); - gateway.initialize(address(counterpart), address(messenger)); - - token = new MockERC1155(); - for (uint256 i = 0; i < TOKEN_COUNT; i++) { - token.mint(address(this), i, type(uint256).max, ""); - } - token.setApprovalForAll(address(gateway), true); - - mockRecipient = new MockERC1155Recipient(); - } - - function testReinitilize() public { - hevm.expectRevert("Initializable: contract is already initialized"); - gateway.initialize(address(1), address(messenger)); - } - - function testUpdateTokenMappingFailed(address token1) public { - // call by non-owner, should revert - hevm.startPrank(address(1)); - hevm.expectRevert("Ownable: caller is not the owner"); - gateway.updateTokenMapping(token1, token1); - hevm.stopPrank(); - - // l2 token is zero, should revert - hevm.expectRevert("token address cannot be 0"); - gateway.updateTokenMapping(token1, address(0)); - } - - function testUpdateTokenMappingSuccess(address token1, address token2) public { - if (token2 == address(0)) token2 = address(1); - - assertEq(gateway.tokenMapping(token1), address(0)); - gateway.updateTokenMapping(token1, token2); - assertEq(gateway.tokenMapping(token1), token2); - } - - /// @dev failed to withdraw erc1155 - function testWithdrawERC1155WithGatewayFailed(address to) public { - // token not support - hevm.expectRevert("no corresponding l1 token"); - if (to == address(0)) { - gateway.withdrawERC1155(address(token), 0, 1, 0); - } else { - gateway.withdrawERC1155(address(token), to, 0, 1, 0); - } - - // withdraw zero amount - hevm.expectRevert("withdraw zero amount"); - if (to == address(0)) { - gateway.withdrawERC1155(address(token), 0, 0, 0); - } else { - gateway.withdrawERC1155(address(token), to, 0, 0, 0); - } - } - - /// @dev withdraw erc1155 without recipient - function testWithdrawERC1155WithGatewaySuccess(uint256 tokenId, uint256 amount) public { - tokenId = bound(tokenId, 0, TOKEN_COUNT - 1); - amount = bound(amount, 1, type(uint256).max); - gateway.updateTokenMapping(address(token), address(token)); - - gateway.withdrawERC1155(address(token), tokenId, amount, 0); - assertEq(token.balanceOf(address(gateway), tokenId), 0); - assertEq(token.balanceOf(address(this), tokenId), type(uint256).max - amount); - - // @todo check event - } - - /// @dev withdraw erc1155 with recipient - function testWithdrawERC1155WithGatewaySuccess( - uint256 tokenId, - uint256 amount, - address to - ) public { - tokenId = bound(tokenId, 0, TOKEN_COUNT - 1); - amount = bound(amount, 1, type(uint256).max); - gateway.updateTokenMapping(address(token), address(token)); - - gateway.withdrawERC1155(address(token), to, tokenId, amount, 0); - assertEq(token.balanceOf(address(gateway), tokenId), 0); - assertEq(token.balanceOf(address(this), tokenId), type(uint256).max - amount); - - // @todo check event - } - - /// @dev failed to batch withdraw erc1155 - function testBatchWithdrawERC1155WithGatewayFailed(address to) public { - // no token to withdraw - hevm.expectRevert("no token to withdraw"); - if (to == address(0)) { - gateway.batchWithdrawERC1155(address(token), new uint256[](0), new uint256[](0), 0); - } else { - gateway.batchWithdrawERC1155(address(token), to, new uint256[](0), new uint256[](0), 0); - } - - // length mismatch - hevm.expectRevert("length mismatch"); - if (to == address(0)) { - gateway.batchWithdrawERC1155(address(token), new uint256[](1), new uint256[](0), 0); - } else { - gateway.batchWithdrawERC1155(address(token), to, new uint256[](1), new uint256[](0), 0); - } - - uint256[] memory amounts = new uint256[](1); - // withdraw zero amount - hevm.expectRevert("withdraw zero amount"); - if (to == address(0)) { - gateway.batchWithdrawERC1155(address(token), new uint256[](1), amounts, 0); - } else { - gateway.batchWithdrawERC1155(address(token), to, new uint256[](1), amounts, 0); - } - - // token not support - amounts[0] = 1; - hevm.expectRevert("no corresponding l1 token"); - if (to == address(0)) { - gateway.batchWithdrawERC1155(address(token), new uint256[](1), amounts, 0); - } else { - gateway.batchWithdrawERC1155(address(token), to, new uint256[](1), amounts, 0); - } - } - - /// @dev batch withdraw erc1155 without recipient - function testBatchWithdrawERC1155WithGatewaySuccess(uint256 count, uint256 amount) public { - count = bound(count, 1, TOKEN_COUNT); - amount = bound(amount, 1, type(uint256).max); - gateway.updateTokenMapping(address(token), address(token)); - - uint256[] memory _tokenIds = new uint256[](count); - uint256[] memory _amounts = new uint256[](count); - for (uint256 i = 0; i < count; i++) { - _tokenIds[i] = i; - _amounts[i] = amount; - } - - gateway.batchWithdrawERC1155(address(token), _tokenIds, _amounts, 0); - for (uint256 i = 0; i < count; i++) { - assertEq(token.balanceOf(address(gateway), i), 0); - assertEq(token.balanceOf(address(this), i), type(uint256).max - amount); - } - - // @todo check event - } - - /// @dev batch withdraw erc1155 with recipient - function testBatchWithdrawERC1155WithGatewaySuccess( - uint256 count, - uint256 amount, - address to - ) public { - count = bound(count, 1, TOKEN_COUNT); - amount = bound(amount, 1, type(uint256).max); - gateway.updateTokenMapping(address(token), address(token)); - - uint256[] memory _tokenIds = new uint256[](count); - uint256[] memory _amounts = new uint256[](count); - for (uint256 i = 0; i < count; i++) { - _tokenIds[i] = i; - _amounts[i] = amount; - } - - gateway.batchWithdrawERC1155(address(token), to, _tokenIds, _amounts, 0); - for (uint256 i = 0; i < count; i++) { - assertEq(token.balanceOf(address(gateway), i), 0); - assertEq(token.balanceOf(address(this), i), type(uint256).max - _amounts[i]); - } - - // @todo check event - } - - /// @dev failed to finalize deposit erc1155 - function testFinalizeDepositERC1155Failed() public { - // should revert, called by non-messenger - hevm.expectRevert(ErrorCallerIsNotMessenger.selector); - gateway.finalizeDepositERC1155(address(0), address(0), address(0), address(0), 0, 1); - - // should revert, called by messenger, xDomainMessageSender not set - hevm.expectRevert(ErrorCallerIsNotCounterpartGateway.selector); - messenger.callTarget( - address(gateway), - abi.encodeWithSelector( - L2ERC1155Gateway.finalizeDepositERC1155.selector, - address(0), - address(0), - address(0), - address(0), - 0, - 1 - ) - ); - - // should revert, called by messenger, xDomainMessageSender set wrong - messenger.setXDomainMessageSender(address(2)); - hevm.expectRevert(ErrorCallerIsNotCounterpartGateway.selector); - messenger.callTarget( - address(gateway), - abi.encodeWithSelector( - L2ERC1155Gateway.finalizeDepositERC1155.selector, - address(0), - address(0), - address(0), - address(0), - 0, - 1 - ) - ); - } - - /// @dev finalize deposit erc1155 - function testFinalizeDepositERC1155( - address from, - address to, - uint256 tokenId, - uint256 amount - ) public { - hevm.assume(to != address(0)); - hevm.assume(to.code.length == 0); - - gateway.updateTokenMapping(address(token), address(token)); - tokenId = bound(tokenId, 0, TOKEN_COUNT - 1); - amount = bound(amount, 1, type(uint256).max); - - // finalize deposit - messenger.setXDomainMessageSender(address(counterpart)); - messenger.callTarget( - address(gateway), - abi.encodeWithSelector( - L2ERC1155Gateway.finalizeDepositERC1155.selector, - address(token), - address(token), - from, - to, - tokenId, - amount - ) - ); - assertEq(token.balanceOf(to, tokenId), amount); - } - - /// @dev failed to finalize batch deposit erc1155 - function testFinalizeBatchDepositERC1155Failed() public { - // should revert, called by non-messenger - hevm.expectRevert(ErrorCallerIsNotMessenger.selector); - gateway.finalizeBatchDepositERC1155( - address(0), - address(0), - address(0), - address(0), - new uint256[](0), - new uint256[](0) - ); - - // should revert, called by messenger, xDomainMessageSender not set - hevm.expectRevert(ErrorCallerIsNotCounterpartGateway.selector); - messenger.callTarget( - address(gateway), - abi.encodeWithSelector( - L2ERC1155Gateway.finalizeBatchDepositERC1155.selector, - address(0), - address(0), - address(0), - address(0), - new uint256[](0), - new uint256[](0) - ) - ); - - // should revert, called by messenger, xDomainMessageSender set wrong - messenger.setXDomainMessageSender(address(2)); - hevm.expectRevert(ErrorCallerIsNotCounterpartGateway.selector); - messenger.callTarget( - address(gateway), - abi.encodeWithSelector( - L2ERC1155Gateway.finalizeBatchDepositERC1155.selector, - address(0), - address(0), - address(0), - address(0), - new uint256[](0), - new uint256[](0) - ) - ); - } - - /// @dev finalize batch withdraw erc1155 - function testFinalizeBatchWithdrawERC1155( - address from, - address to, - uint256 count, - uint256 amount - ) public { - if (to == address(0) || to.code.length > 0) to = address(1); - gateway.updateTokenMapping(address(token), address(token)); - - count = bound(count, 1, TOKEN_COUNT); - amount = bound(amount, 1, type(uint256).max); - uint256[] memory _tokenIds = new uint256[](count); - uint256[] memory _amounts = new uint256[](count); - for (uint256 i = 0; i < count; i++) { - _tokenIds[i] = i; - _amounts[i] = amount; - } - - // finalzie batch deposit - messenger.setXDomainMessageSender(address(counterpart)); - messenger.callTarget( - address(gateway), - abi.encodeWithSelector( - L2ERC1155Gateway.finalizeBatchDepositERC1155.selector, - address(token), - address(token), - from, - to, - _tokenIds, - _amounts - ) - ); - for (uint256 i = 0; i < count; i++) { - assertEq(token.balanceOf(to, i), _amounts[i]); - } - } - - function _deployGateway(address _messenger) internal returns (L2ERC1155Gateway) { - return - L2ERC1155Gateway( - address( - new ERC1967Proxy( - address(new L2ERC1155Gateway(address(counterpart), address(_messenger))), - new bytes(0) - ) - ) - ); - } -} diff --git a/contracts/src/test/L2ERC721Gateway.t.sol b/contracts/src/test/L2ERC721Gateway.t.sol deleted file mode 100644 index 2534f0fa8..000000000 --- a/contracts/src/test/L2ERC721Gateway.t.sol +++ /dev/null @@ -1,343 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {DSTestPlus} from "solmate/test/utils/DSTestPlus.sol"; -import {MockERC721} from "solmate/test/utils/mocks/MockERC721.sol"; - -import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; - -import {L1ERC721Gateway} from "../L1/gateways/L1ERC721Gateway.sol"; -import {L2ERC721Gateway} from "../L2/gateways/L2ERC721Gateway.sol"; -import {MockScrollMessenger} from "./mocks/MockScrollMessenger.sol"; -import {MockERC721Recipient} from "./mocks/MockERC721Recipient.sol"; - -contract L2ERC721GatewayTest is DSTestPlus { - /********** - * Errors * - **********/ - - // from IScrollGateway - error ErrorZeroAddress(); - error ErrorCallerIsNotMessenger(); - error ErrorCallerIsNotCounterpartGateway(); - error ErrorNotInDropMessageContext(); - - uint256 private constant TOKEN_COUNT = 100; - uint256 private constant NOT_OWNED_TOKEN_ID = 233333; - - MockScrollMessenger private messenger; - L1ERC721Gateway private counterpart; - L2ERC721Gateway private gateway; - - MockERC721 private token; - MockERC721Recipient private mockRecipient; - - function setUp() public { - messenger = new MockScrollMessenger(); - counterpart = new L1ERC721Gateway(address(1), address(1)); - - gateway = _deployGateway(address(messenger)); - gateway.initialize(address(counterpart), address(messenger)); - - token = new MockERC721("Mock", "M"); - for (uint256 i = 0; i < TOKEN_COUNT; i++) { - token.mint(address(this), i); - } - - mockRecipient = new MockERC721Recipient(); - token.mint(address(mockRecipient), NOT_OWNED_TOKEN_ID); - } - - function testReinitilize() public { - hevm.expectRevert("Initializable: contract is already initialized"); - gateway.initialize(address(1), address(messenger)); - } - - function testUpdateTokenMappingFailed(address token1) public { - // call by non-owner, should revert - hevm.startPrank(address(1)); - hevm.expectRevert("Ownable: caller is not the owner"); - gateway.updateTokenMapping(token1, token1); - hevm.stopPrank(); - - // l1 token is zero, should revert - hevm.expectRevert("token address cannot be 0"); - gateway.updateTokenMapping(token1, address(0)); - } - - function testUpdateTokenMappingSuccess(address token1, address token2) public { - if (token2 == address(0)) token2 = address(1); - - assertEq(gateway.tokenMapping(token1), address(0)); - gateway.updateTokenMapping(token1, token2); - assertEq(gateway.tokenMapping(token1), token2); - } - - /// @dev failed to withdraw erc721 - function testWithdrawERC721WithGatewayFailed(address to) public { - // token not support - hevm.expectRevert("no corresponding l1 token"); - if (to == address(0)) { - gateway.withdrawERC721(address(token), 0, 0); - } else { - gateway.withdrawERC721(address(token), to, 0, 0); - } - - // token not owned - gateway.updateTokenMapping(address(token), address(token)); - hevm.expectRevert("token not owned"); - if (to == address(0)) { - gateway.withdrawERC721(address(token), NOT_OWNED_TOKEN_ID, 0); - } else { - gateway.withdrawERC721(address(token), to, NOT_OWNED_TOKEN_ID, 0); - } - } - - /// @dev withdraw erc721 without recipient - function testWithdrawERC721WithGatewaySuccess(uint256 tokenId) public { - tokenId = bound(tokenId, 0, TOKEN_COUNT - 1); - gateway.updateTokenMapping(address(token), address(token)); - - gateway.withdrawERC721(address(token), tokenId, 0); - hevm.expectRevert("NOT_MINTED"); - token.ownerOf(tokenId); - assertEq(token.balanceOf(address(this)), TOKEN_COUNT - 1); - - // @todo check event - } - - /// @dev withdraw erc721 with recipient - function testWithdrawERC721WithGatewaySuccess(uint256 tokenId, address to) public { - tokenId = bound(tokenId, 0, TOKEN_COUNT - 1); - gateway.updateTokenMapping(address(token), address(token)); - - gateway.withdrawERC721(address(token), to, tokenId, 0); - hevm.expectRevert("NOT_MINTED"); - token.ownerOf(tokenId); - assertEq(token.balanceOf(address(this)), TOKEN_COUNT - 1); - - // @todo check event - } - - /// @dev failed to batch withdraw erc721 - function testBatchWithdrawERC721WithGatewayFailed(address to) public { - // token not support - hevm.expectRevert("no corresponding l1 token"); - if (to == address(0)) { - gateway.batchWithdrawERC721(address(token), new uint256[](1), 0); - } else { - gateway.batchWithdrawERC721(address(token), to, new uint256[](1), 0); - } - - // no token to withdraw - hevm.expectRevert("no token to withdraw"); - if (to == address(0)) { - gateway.batchWithdrawERC721(address(token), new uint256[](0), 0); - } else { - gateway.batchWithdrawERC721(address(token), to, new uint256[](0), 0); - } - - // token not owned - gateway.updateTokenMapping(address(token), address(token)); - uint256[] memory tokenIds = new uint256[](1); - tokenIds[0] = NOT_OWNED_TOKEN_ID; - hevm.expectRevert("token not owned"); - if (to == address(0)) { - gateway.batchWithdrawERC721(address(token), tokenIds, 0); - } else { - gateway.batchWithdrawERC721(address(token), to, tokenIds, 0); - } - } - - /// @dev batch withdraw erc721 without recipient - function testBatchWithdrawERC721WithGatewaySuccess(uint256 count) public { - count = bound(count, 1, TOKEN_COUNT); - gateway.updateTokenMapping(address(token), address(token)); - - uint256[] memory _tokenIds = new uint256[](count); - for (uint256 i = 0; i < count; i++) { - _tokenIds[i] = i; - } - - gateway.batchWithdrawERC721(address(token), _tokenIds, 0); - for (uint256 i = 0; i < count; i++) { - hevm.expectRevert("NOT_MINTED"); - token.ownerOf(i); - } - assertEq(token.balanceOf(address(this)), TOKEN_COUNT - count); - - // @todo check event - } - - /// @dev batch withdraw erc721 with recipient - function testBatchWithdrawERC721WithGatewaySuccess(uint256 count, address to) public { - count = bound(count, 1, TOKEN_COUNT); - gateway.updateTokenMapping(address(token), address(token)); - - uint256[] memory _tokenIds = new uint256[](count); - for (uint256 i = 0; i < count; i++) { - _tokenIds[i] = i; - } - - gateway.batchWithdrawERC721(address(token), to, _tokenIds, 0); - for (uint256 i = 0; i < count; i++) { - hevm.expectRevert("NOT_MINTED"); - token.ownerOf(i); - } - assertEq(token.balanceOf(address(this)), TOKEN_COUNT - count); - - // @todo check event - } - - /// @dev failed to finalize withdraw erc721 - function testFinalizeDepositERC721Failed() public { - // should revert, called by non-messenger - hevm.expectRevert(ErrorCallerIsNotMessenger.selector); - gateway.finalizeDepositERC721(address(0), address(0), address(0), address(0), 0); - - // should revert, called by messenger, xDomainMessageSender not set - hevm.expectRevert(ErrorCallerIsNotCounterpartGateway.selector); - messenger.callTarget( - address(gateway), - abi.encodeWithSelector( - L2ERC721Gateway.finalizeDepositERC721.selector, - address(0), - address(0), - address(0), - address(0), - 0 - ) - ); - - // should revert, called by messenger, xDomainMessageSender set wrong - messenger.setXDomainMessageSender(address(2)); - hevm.expectRevert(ErrorCallerIsNotCounterpartGateway.selector); - messenger.callTarget( - address(gateway), - abi.encodeWithSelector( - L2ERC721Gateway.finalizeDepositERC721.selector, - address(0), - address(0), - address(0), - address(0), - 0 - ) - ); - } - - /// @dev finalize withdraw erc721 - function testFinalizeDepositERC721( - address from, - address to, - uint256 tokenId - ) public { - hevm.assume(to != address(0)); - hevm.assume(to.code.length == 0); - - tokenId = bound(tokenId, NOT_OWNED_TOKEN_ID + 1, type(uint256).max); - gateway.updateTokenMapping(address(token), address(token)); - - // finalize deposit - messenger.setXDomainMessageSender(address(counterpart)); - messenger.callTarget( - address(gateway), - abi.encodeWithSelector( - L2ERC721Gateway.finalizeDepositERC721.selector, - address(token), - address(token), - from, - to, - tokenId - ) - ); - assertEq(token.balanceOf(to), 1); - assertEq(token.ownerOf(tokenId), to); - } - - /// @dev failed to finalize batch withdraw erc721 - function testFinalizeBatchDepositERC721Failed() public { - // should revert, called by non-messenger - hevm.expectRevert(ErrorCallerIsNotMessenger.selector); - gateway.finalizeBatchDepositERC721(address(0), address(0), address(0), address(0), new uint256[](0)); - - // should revert, called by messenger, xDomainMessageSender not set - hevm.expectRevert(ErrorCallerIsNotCounterpartGateway.selector); - messenger.callTarget( - address(gateway), - abi.encodeWithSelector( - L2ERC721Gateway.finalizeBatchDepositERC721.selector, - address(0), - address(0), - address(0), - address(0), - new uint256[](0) - ) - ); - - // should revert, called by messenger, xDomainMessageSender set wrong - messenger.setXDomainMessageSender(address(2)); - hevm.expectRevert(ErrorCallerIsNotCounterpartGateway.selector); - messenger.callTarget( - address(gateway), - abi.encodeWithSelector( - L2ERC721Gateway.finalizeBatchDepositERC721.selector, - address(0), - address(0), - address(0), - address(0), - new uint256[](0) - ) - ); - } - - /// @dev finalize batch withdraw erc721 - function testFinalizeBatchDepositERC721( - address from, - address to, - uint256 count - ) public { - if (to == address(0)) to = address(1); - if (to == address(mockRecipient)) to = address(1); - if (to == address(this)) to = address(1); - - gateway.updateTokenMapping(address(token), address(token)); - - // deposit first - count = bound(count, 1, TOKEN_COUNT); - uint256[] memory _tokenIds = new uint256[](count); - for (uint256 i = 0; i < count; i++) { - _tokenIds[i] = i + NOT_OWNED_TOKEN_ID + 1; - } - - // then withdraw - messenger.setXDomainMessageSender(address(counterpart)); - messenger.callTarget( - address(gateway), - abi.encodeWithSelector( - L2ERC721Gateway.finalizeBatchDepositERC721.selector, - address(token), - address(token), - from, - to, - _tokenIds - ) - ); - assertEq(token.balanceOf(to), count); - for (uint256 i = 0; i < count; i++) { - assertEq(token.ownerOf(_tokenIds[i]), to); - } - } - - function _deployGateway(address _messenger) internal returns (L2ERC721Gateway) { - return - L2ERC721Gateway( - address( - new ERC1967Proxy( - address(new L2ERC721Gateway(address(counterpart), address(_messenger))), - new bytes(0) - ) - ) - ); - } -} diff --git a/contracts/src/test/L2ETHGateway.t.sol b/contracts/src/test/L2ETHGateway.t.sol deleted file mode 100644 index 324d5335f..000000000 --- a/contracts/src/test/L2ETHGateway.t.sol +++ /dev/null @@ -1,459 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {ITransparentUpgradeableProxy} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; - -import {L2GatewayRouter} from "../L2/gateways/L2GatewayRouter.sol"; -import {IL1ETHGateway, L1ETHGateway} from "../L1/gateways/L1ETHGateway.sol"; -import {IL2ETHGateway, L2ETHGateway} from "../L2/gateways/L2ETHGateway.sol"; - -import {AddressAliasHelper} from "../libraries/common/AddressAliasHelper.sol"; - -import {L2GatewayTestBase} from "./L2GatewayTestBase.t.sol"; -import {MockScrollMessenger} from "./mocks/MockScrollMessenger.sol"; -import {MockGatewayRecipient} from "./mocks/MockGatewayRecipient.sol"; - -contract L2ETHGatewayTest is L2GatewayTestBase { - // from L2ETHGateway - event WithdrawETH(address indexed from, address indexed to, uint256 amount, bytes data); - event FinalizeDepositETH(address indexed from, address indexed to, uint256 amount, bytes data); - - L2ETHGateway private gateway; - L2GatewayRouter private router; - - L1ETHGateway private counterpartGateway; - - function setUp() public { - setUpBase(); - - // Deploy L1 contracts - counterpartGateway = new L1ETHGateway(address(1), address(1), address(1)); - - // Deploy L2 contracts - router = L2GatewayRouter(_deployProxy(address(new L2GatewayRouter()))); - gateway = _deployGateway(address(l2Messenger)); - - // Initialize L2 contracts - gateway.initialize(address(counterpartGateway), address(router), address(l2Messenger)); - router.initialize(address(gateway), address(0)); - } - - function testInitialized() public { - assertEq(address(counterpartGateway), gateway.counterpart()); - assertEq(address(router), gateway.router()); - assertEq(address(l2Messenger), gateway.messenger()); - - hevm.expectRevert("Initializable: contract is already initialized"); - gateway.initialize(address(counterpartGateway), address(router), address(l2Messenger)); - } - - function testWithdrawETH( - uint256 amount, - uint256 gasLimit, - uint256 feePerGas - ) public { - _withdrawETH(false, amount, gasLimit, feePerGas); - } - - function testWithdrawETHWithRecipient( - uint256 amount, - address recipient, - uint256 gasLimit, - uint256 feePerGas - ) public { - _withdrawETHWithRecipient(false, amount, recipient, gasLimit, feePerGas); - } - - function testWithdrawETHWithRecipientAndCalldata( - uint256 amount, - address recipient, - bytes memory dataToCall, - uint256 gasLimit, - uint256 feePerGas - ) public { - _withdrawETHWithRecipientAndCalldata(false, amount, recipient, dataToCall, gasLimit, feePerGas); - } - - function testRouterWithdrawETH( - uint256 amount, - uint256 gasLimit, - uint256 feePerGas - ) public { - _withdrawETH(true, amount, gasLimit, feePerGas); - } - - function testRouterWithdrawETHWithRecipient( - uint256 amount, - address recipient, - uint256 gasLimit, - uint256 feePerGas - ) public { - _withdrawETHWithRecipient(true, amount, recipient, gasLimit, feePerGas); - } - - function testRouterWithdrawETHWithRecipientAndCalldata( - uint256 amount, - address recipient, - bytes memory dataToCall, - uint256 gasLimit, - uint256 feePerGas - ) public { - _withdrawETHWithRecipientAndCalldata(true, amount, recipient, dataToCall, gasLimit, feePerGas); - } - - function testFinalizeDepositETHFailedMocking( - address sender, - address recipient, - uint256 amount, - bytes memory dataToCall - ) public { - amount = bound(amount, 1, address(this).balance / 2); - - // revert when caller is not messenger - hevm.expectRevert(ErrorCallerIsNotMessenger.selector); - gateway.finalizeDepositETH(sender, recipient, amount, dataToCall); - - MockScrollMessenger mockMessenger = new MockScrollMessenger(); - gateway = _deployGateway(address(mockMessenger)); - gateway.initialize(address(counterpartGateway), address(router), address(mockMessenger)); - - // only call by counterpart - hevm.expectRevert(ErrorCallerIsNotCounterpartGateway.selector); - mockMessenger.callTarget( - address(gateway), - abi.encodeWithSelector(gateway.finalizeDepositETH.selector, sender, recipient, amount, dataToCall) - ); - - mockMessenger.setXDomainMessageSender(address(counterpartGateway)); - - // msg.value mismatch - hevm.expectRevert("msg.value mismatch"); - mockMessenger.callTarget( - address(gateway), - abi.encodeWithSelector(gateway.finalizeDepositETH.selector, sender, recipient, amount, dataToCall) - ); - - // ETH transfer failed - hevm.expectRevert("ETH transfer failed"); - mockMessenger.callTarget{value: amount}( - address(gateway), - abi.encodeWithSelector(gateway.finalizeDepositETH.selector, sender, address(this), amount, dataToCall) - ); - } - - function testFinalizeWithdrawETHFailed( - address sender, - address recipient, - uint256 amount, - bytes memory dataToCall - ) public { - amount = bound(amount, 1, address(this).balance / 2); - - // send some ETH to L2ScrollMessenger - gateway.withdrawETH{value: amount}(amount, 21000); - - // do finalize withdraw eth - bytes memory message = abi.encodeWithSelector( - IL2ETHGateway.finalizeDepositETH.selector, - sender, - recipient, - amount, - dataToCall - ); - bytes memory xDomainCalldata = abi.encodeWithSignature( - "relayMessage(address,address,uint256,uint256,bytes)", - address(uint160(address(counterpartGateway)) + 1), - address(gateway), - amount, - 0, - message - ); - - // counterpart is not L1ETHGateway - // emit FailedRelayedMessage from L2ScrollMessenger - hevm.expectEmit(true, false, false, true); - emit FailedRelayedMessage(keccak256(xDomainCalldata)); - - uint256 messengerBalance = address(l2Messenger).balance; - uint256 recipientBalance = recipient.balance; - assertBoolEq(false, l2Messenger.isL1MessageExecuted(keccak256(xDomainCalldata))); - hevm.startPrank(AddressAliasHelper.applyL1ToL2Alias(address(l1Messenger))); - l2Messenger.relayMessage( - address(uint160(address(counterpartGateway)) + 1), - address(gateway), - amount, - 0, - message - ); - hevm.stopPrank(); - assertEq(messengerBalance, address(l2Messenger).balance); - assertEq(recipientBalance, recipient.balance); - assertBoolEq(false, l2Messenger.isL1MessageExecuted(keccak256(xDomainCalldata))); - } - - function testFinalizeWithdrawETH( - address sender, - uint256 amount, - bytes memory dataToCall - ) public { - MockGatewayRecipient recipient = new MockGatewayRecipient(); - - amount = bound(amount, 1, address(this).balance / 2); - - // send some ETH to L2ScrollMessenger - gateway.withdrawETH{value: amount}(amount, 21000); - - // do finalize withdraw eth - bytes memory message = abi.encodeWithSelector( - IL2ETHGateway.finalizeDepositETH.selector, - sender, - address(recipient), - amount, - dataToCall - ); - bytes memory xDomainCalldata = abi.encodeWithSignature( - "relayMessage(address,address,uint256,uint256,bytes)", - address(counterpartGateway), - address(gateway), - amount, - 0, - message - ); - - // emit FinalizeDepositETH from L2ETHGateway - { - hevm.expectEmit(true, true, false, true); - emit FinalizeDepositETH(sender, address(recipient), amount, dataToCall); - } - - // emit RelayedMessage from L2ScrollMessenger - { - hevm.expectEmit(true, false, false, true); - emit RelayedMessage(keccak256(xDomainCalldata)); - } - - uint256 messengerBalance = address(l2Messenger).balance; - uint256 recipientBalance = address(recipient).balance; - assertBoolEq(false, l2Messenger.isL1MessageExecuted(keccak256(xDomainCalldata))); - hevm.startPrank(AddressAliasHelper.applyL1ToL2Alias(address(l1Messenger))); - l2Messenger.relayMessage(address(counterpartGateway), address(gateway), amount, 0, message); - hevm.stopPrank(); - assertEq(messengerBalance - amount, address(l2Messenger).balance); - assertEq(recipientBalance + amount, address(recipient).balance); - assertBoolEq(true, l2Messenger.isL1MessageExecuted(keccak256(xDomainCalldata))); - } - - function _withdrawETH( - bool useRouter, - uint256 amount, - uint256 gasLimit, - uint256 feePerGas - ) private { - amount = bound(amount, 0, address(this).balance / 2); - gasLimit = bound(gasLimit, 21000, 1000000); - feePerGas = 0; - - setL1BaseFee(feePerGas); - - uint256 feeToPay = feePerGas * gasLimit; - bytes memory message = abi.encodeWithSelector( - IL1ETHGateway.finalizeWithdrawETH.selector, - address(this), - address(this), - amount, - new bytes(0) - ); - bytes memory xDomainCalldata = abi.encodeWithSignature( - "relayMessage(address,address,uint256,uint256,bytes)", - address(gateway), - address(counterpartGateway), - amount, - 0, - message - ); - - if (amount == 0) { - hevm.expectRevert("withdraw zero eth"); - if (useRouter) { - router.withdrawETH{value: amount}(amount, gasLimit); - } else { - gateway.withdrawETH{value: amount}(amount, gasLimit); - } - } else { - // emit AppendMessage from L2MessageQueue - { - hevm.expectEmit(false, false, false, true); - emit AppendMessage(0, keccak256(xDomainCalldata)); - } - - // emit SentMessage from L2ScrollMessenger - { - hevm.expectEmit(true, true, false, true); - emit SentMessage(address(gateway), address(counterpartGateway), amount, 0, gasLimit, message); - } - - // emit WithdrawETH from L2ETHGateway - hevm.expectEmit(true, true, false, true); - emit WithdrawETH(address(this), address(this), amount, new bytes(0)); - - uint256 messengerBalance = address(l2Messenger).balance; - uint256 feeVaultBalance = address(feeVault).balance; - assertEq(l2Messenger.messageSendTimestamp(keccak256(xDomainCalldata)), 0); - if (useRouter) { - router.withdrawETH{value: amount + feeToPay}(amount, gasLimit); - } else { - gateway.withdrawETH{value: amount + feeToPay}(amount, gasLimit); - } - assertEq(amount + messengerBalance, address(l2Messenger).balance); - assertEq(feeToPay + feeVaultBalance, address(feeVault).balance); - assertGt(l2Messenger.messageSendTimestamp(keccak256(xDomainCalldata)), 0); - } - } - - function _withdrawETHWithRecipient( - bool useRouter, - uint256 amount, - address recipient, - uint256 gasLimit, - uint256 feePerGas - ) private { - amount = bound(amount, 0, address(this).balance / 2); - gasLimit = bound(gasLimit, 21000, 1000000); - feePerGas = 0; - - setL1BaseFee(feePerGas); - - uint256 feeToPay = feePerGas * gasLimit; - bytes memory message = abi.encodeWithSelector( - IL1ETHGateway.finalizeWithdrawETH.selector, - address(this), - recipient, - amount, - new bytes(0) - ); - bytes memory xDomainCalldata = abi.encodeWithSignature( - "relayMessage(address,address,uint256,uint256,bytes)", - address(gateway), - address(counterpartGateway), - amount, - 0, - message - ); - - if (amount == 0) { - hevm.expectRevert("withdraw zero eth"); - if (useRouter) { - router.withdrawETH{value: amount}(recipient, amount, gasLimit); - } else { - gateway.withdrawETH{value: amount}(recipient, amount, gasLimit); - } - } else { - // emit AppendMessage from L2MessageQueue - { - hevm.expectEmit(false, false, false, true); - emit AppendMessage(0, keccak256(xDomainCalldata)); - } - - // emit SentMessage from L2ScrollMessenger - { - hevm.expectEmit(true, true, false, true); - emit SentMessage(address(gateway), address(counterpartGateway), amount, 0, gasLimit, message); - } - - // emit WithdrawETH from L2ETHGateway - hevm.expectEmit(true, true, false, true); - emit WithdrawETH(address(this), recipient, amount, new bytes(0)); - - uint256 messengerBalance = address(l2Messenger).balance; - uint256 feeVaultBalance = address(feeVault).balance; - assertEq(l2Messenger.messageSendTimestamp(keccak256(xDomainCalldata)), 0); - if (useRouter) { - router.withdrawETH{value: amount + feeToPay}(recipient, amount, gasLimit); - } else { - gateway.withdrawETH{value: amount + feeToPay}(recipient, amount, gasLimit); - } - assertEq(amount + messengerBalance, address(l2Messenger).balance); - assertEq(feeToPay + feeVaultBalance, address(feeVault).balance); - assertGt(l2Messenger.messageSendTimestamp(keccak256(xDomainCalldata)), 0); - } - } - - function _withdrawETHWithRecipientAndCalldata( - bool useRouter, - uint256 amount, - address recipient, - bytes memory dataToCall, - uint256 gasLimit, - uint256 feePerGas - ) private { - amount = bound(amount, 0, address(this).balance / 2); - gasLimit = bound(gasLimit, 21000, 1000000); - feePerGas = 0; - - setL1BaseFee(feePerGas); - - uint256 feeToPay = feePerGas * gasLimit; - bytes memory message = abi.encodeWithSelector( - IL1ETHGateway.finalizeWithdrawETH.selector, - address(this), - recipient, - amount, - dataToCall - ); - bytes memory xDomainCalldata = abi.encodeWithSignature( - "relayMessage(address,address,uint256,uint256,bytes)", - address(gateway), - address(counterpartGateway), - amount, - 0, - message - ); - - if (amount == 0) { - hevm.expectRevert("withdraw zero eth"); - if (useRouter) { - router.withdrawETHAndCall{value: amount}(recipient, amount, dataToCall, gasLimit); - } else { - gateway.withdrawETHAndCall{value: amount}(recipient, amount, dataToCall, gasLimit); - } - } else { - // emit AppendMessage from L2MessageQueue - { - hevm.expectEmit(false, false, false, true); - emit AppendMessage(0, keccak256(xDomainCalldata)); - } - - // emit SentMessage from L2ScrollMessenger - { - hevm.expectEmit(true, true, false, true); - emit SentMessage(address(gateway), address(counterpartGateway), amount, 0, gasLimit, message); - } - - // emit WithdrawETH from L2ETHGateway - hevm.expectEmit(true, true, false, true); - emit WithdrawETH(address(this), recipient, amount, dataToCall); - - uint256 messengerBalance = address(l2Messenger).balance; - uint256 feeVaultBalance = address(feeVault).balance; - assertEq(l2Messenger.messageSendTimestamp(keccak256(xDomainCalldata)), 0); - if (useRouter) { - router.withdrawETHAndCall{value: amount + feeToPay}(recipient, amount, dataToCall, gasLimit); - } else { - gateway.withdrawETHAndCall{value: amount + feeToPay}(recipient, amount, dataToCall, gasLimit); - } - assertEq(amount + messengerBalance, address(l2Messenger).balance); - assertEq(feeToPay + feeVaultBalance, address(feeVault).balance); - assertGt(l2Messenger.messageSendTimestamp(keccak256(xDomainCalldata)), 0); - } - } - - function _deployGateway(address messenger) internal returns (L2ETHGateway _gateway) { - _gateway = L2ETHGateway(_deployProxy(address(0))); - - admin.upgrade( - ITransparentUpgradeableProxy(address(_gateway)), - address(new L2ETHGateway(address(counterpartGateway), address(router), address(messenger))) - ); - } -} diff --git a/contracts/src/test/L2GasPriceOracle.t.sol b/contracts/src/test/L2GasPriceOracle.t.sol deleted file mode 100644 index dd5a583d4..000000000 --- a/contracts/src/test/L2GasPriceOracle.t.sol +++ /dev/null @@ -1,90 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {DSTestPlus} from "solmate/test/utils/DSTestPlus.sol"; - -import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; - -import {L2GasPriceOracle} from "../L1/rollup/L2GasPriceOracle.sol"; -import {Whitelist} from "../L2/predeploys/Whitelist.sol"; - -contract L2GasPriceOracleTest is DSTestPlus { - // events - event L2BaseFeeUpdated(uint256 oldL2BaseFee, uint256 newL2BaseFee); - event UpdateWhitelist(address _oldWhitelist, address _newWhitelist); - - L2GasPriceOracle private oracle; - Whitelist private whitelist; - uint256 fee; - - event Log(address addr); - - function setUp() public { - whitelist = new Whitelist(address(this)); - oracle = L2GasPriceOracle(address(new ERC1967Proxy(address(new L2GasPriceOracle()), new bytes(0)))); - - oracle.initialize(1, 2, 1, 1); - oracle.updateWhitelist(address(whitelist)); - - address[] memory _accounts = new address[](1); - _accounts[0] = address(this); - whitelist.updateWhitelistStatus(_accounts, true); - } - - function testCalculateIntrinsicGasFee() external { - uint256 intrinsicGasFee = oracle.calculateIntrinsicGasFee(hex"00"); - assertEq(intrinsicGasFee, 2); - uint64 zeroGas = 5; - uint64 nonZeroGas = 10; - oracle.setIntrinsicParams(20000, 50000, zeroGas, nonZeroGas); - - intrinsicGasFee = oracle.calculateIntrinsicGasFee(hex"001122"); - // 20000 + 1 zero bytes * 5 + 2 nonzero byte * 10 = 20025 - assertEq(intrinsicGasFee, 20025); - - zeroGas = 50; - nonZeroGas = 100; - oracle.setIntrinsicParams(10000, 20000, zeroGas, nonZeroGas); - - intrinsicGasFee = oracle.calculateIntrinsicGasFee(hex"0011220033"); - // 10000 + 3 nonzero byte * 100 + 2 zero bytes * 50 = 10000 + 300 + 100 = 10400 - assertEq(intrinsicGasFee, 10400); - } - - function testSetIntrinsicParamsAccess() external { - hevm.startPrank(address(4)); - hevm.expectRevert("Ownable: caller is not the owner"); - oracle.setIntrinsicParams(1, 0, 0, 1); - } - - function testSetL2BaseFee(uint256 _baseFee1, uint256 _baseFee2) external { - // call by non-whitelister, should revert - hevm.startPrank(address(1)); - hevm.expectRevert("Not whitelisted sender"); - oracle.setL2BaseFee(_baseFee1); - hevm.stopPrank(); - - // call by owner, should succeed - assertEq(oracle.l2BaseFee(), 0); - hevm.expectEmit(false, false, false, true); - emit L2BaseFeeUpdated(0, _baseFee1); - oracle.setL2BaseFee(_baseFee1); - assertEq(oracle.l2BaseFee(), _baseFee1); - - hevm.expectEmit(false, false, false, true); - emit L2BaseFeeUpdated(_baseFee1, _baseFee2); - oracle.setL2BaseFee(_baseFee2); - assertEq(oracle.l2BaseFee(), _baseFee2); - } - - function testEstimateCrossDomainMessageFee(uint256 baseFee, uint256 gasLimit) external { - gasLimit = bound(gasLimit, 0, 3000000); - baseFee = bound(baseFee, 0, 1000000000); - - assertEq(oracle.estimateCrossDomainMessageFee(gasLimit), 0); - - oracle.setL2BaseFee(baseFee); - assertEq(oracle.estimateCrossDomainMessageFee(gasLimit), baseFee * gasLimit); - } -} diff --git a/contracts/src/test/L2GatewayRouter.t.sol b/contracts/src/test/L2GatewayRouter.t.sol deleted file mode 100644 index edf090411..000000000 --- a/contracts/src/test/L2GatewayRouter.t.sol +++ /dev/null @@ -1,183 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {MockERC20} from "solmate/test/utils/mocks/MockERC20.sol"; - -import {ITransparentUpgradeableProxy} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; - -import {L1ETHGateway} from "../L1/gateways/L1ETHGateway.sol"; -import {L1StandardERC20Gateway} from "../L1/gateways/L1StandardERC20Gateway.sol"; -import {L1ScrollMessenger} from "../L1/L1ScrollMessenger.sol"; -import {ScrollChain} from "../L1/rollup/ScrollChain.sol"; -import {L2ETHGateway} from "../L2/gateways/L2ETHGateway.sol"; -import {L2GatewayRouter} from "../L2/gateways/L2GatewayRouter.sol"; -import {L2StandardERC20Gateway} from "../L2/gateways/L2StandardERC20Gateway.sol"; -import {AddressAliasHelper} from "../libraries/common/AddressAliasHelper.sol"; -import {ScrollStandardERC20} from "../libraries/token/ScrollStandardERC20.sol"; -import {ScrollStandardERC20Factory} from "../libraries/token/ScrollStandardERC20Factory.sol"; - -import {L2GatewayTestBase} from "./L2GatewayTestBase.t.sol"; - -contract L2GatewayRouterTest is L2GatewayTestBase { - // from L2GatewayRouter - event SetETHGateway(address indexed oldETHGateway, address indexed newEthGateway); - event SetDefaultERC20Gateway(address indexed oldDefaultERC20Gateway, address indexed newDefaultERC20Gateway); - event SetERC20Gateway(address indexed token, address indexed oldGateway, address indexed newGateway); - - ScrollStandardERC20 private template; - ScrollStandardERC20Factory private factory; - - L1StandardERC20Gateway private l1StandardERC20Gateway; - L2StandardERC20Gateway private l2StandardERC20Gateway; - - L1ETHGateway private l1ETHGateway; - L2ETHGateway private l2ETHGateway; - - L2GatewayRouter private router; - MockERC20 private l1Token; - MockERC20 private l2Token; - - function setUp() public { - setUpBase(); - - // Deploy tokens - l1Token = new MockERC20("Mock", "M", 18); - template = new ScrollStandardERC20(); - factory = new ScrollStandardERC20Factory(address(template)); - - // Deploy L1 contracts - l1StandardERC20Gateway = new L1StandardERC20Gateway( - address(1), - address(1), - address(1), - address(template), - address(factory) - ); - l1ETHGateway = new L1ETHGateway(address(1), address(1), address(1)); - - // Deploy L2 contracts - l2StandardERC20Gateway = L2StandardERC20Gateway(_deployProxy(address(0))); - l2ETHGateway = L2ETHGateway(_deployProxy(address(0))); - router = L2GatewayRouter(_deployProxy(address(new L2GatewayRouter()))); - - admin.upgrade( - ITransparentUpgradeableProxy(address(l2StandardERC20Gateway)), - address( - new L2StandardERC20Gateway( - address(l1StandardERC20Gateway), - address(router), - address(l2Messenger), - address(factory) - ) - ) - ); - admin.upgrade( - ITransparentUpgradeableProxy(address(l2ETHGateway)), - address(new L2ETHGateway(address(l1ETHGateway), address(router), address(l2Messenger))) - ); - - // Initialize L2 contracts - factory.transferOwnership(address(l2StandardERC20Gateway)); - l2StandardERC20Gateway.initialize( - address(l1StandardERC20Gateway), - address(router), - address(l1Messenger), - address(factory) - ); - l2ETHGateway.initialize(address(l1ETHGateway), address(router), address(l2Messenger)); - router.initialize(address(l2ETHGateway), address(l2StandardERC20Gateway)); - - // Prepare token balances - l2Token = MockERC20(l2StandardERC20Gateway.getL2ERC20Address(address(l1Token))); - hevm.startPrank(AddressAliasHelper.applyL1ToL2Alias(address(l1Messenger))); - l2Messenger.relayMessage( - address(l1StandardERC20Gateway), - address(l2StandardERC20Gateway), - 0, - 0, - abi.encodeWithSelector( - L2StandardERC20Gateway.finalizeDepositERC20.selector, - address(l1Token), - address(l2Token), - address(this), - address(this), - type(uint128).max, - abi.encode(true, abi.encode("", abi.encode("symbol", "name", 18))) - ) - ); - hevm.stopPrank(); - } - - function testOwnership() public { - assertEq(address(this), router.owner()); - } - - function testInitialized() public { - assertEq(address(l2StandardERC20Gateway), router.defaultERC20Gateway()); - assertEq(address(l2StandardERC20Gateway), router.getERC20Gateway(address(l2Token))); - - assertEq(address(l1Token), router.getL1ERC20Address(address(l2Token))); - hevm.expectRevert("unsupported"); - router.getL2ERC20Address(address(l1Token)); - - hevm.expectRevert("Initializable: contract is already initialized"); - router.initialize(address(l2ETHGateway), address(l2StandardERC20Gateway)); - } - - function testSetDefaultERC20Gateway() public { - router.setDefaultERC20Gateway(address(0)); - - // set by non-owner, should revert - hevm.startPrank(address(1)); - hevm.expectRevert("Ownable: caller is not the owner"); - router.setDefaultERC20Gateway(address(l2StandardERC20Gateway)); - hevm.stopPrank(); - - // set by owner, should succeed - hevm.expectEmit(true, true, false, true); - emit SetDefaultERC20Gateway(address(0), address(l2StandardERC20Gateway)); - - assertEq(address(0), router.getERC20Gateway(address(l2Token))); - assertEq(address(0), router.getL1ERC20Address(address(l2Token))); - assertEq(address(0), router.defaultERC20Gateway()); - router.setDefaultERC20Gateway(address(l2StandardERC20Gateway)); - assertEq(address(l2StandardERC20Gateway), router.getERC20Gateway(address(l2Token))); - assertEq(address(l2StandardERC20Gateway), router.defaultERC20Gateway()); - } - - function testSetERC20Gateway() public { - router.setDefaultERC20Gateway(address(0)); - - // length mismatch, should revert - address[] memory empty = new address[](0); - address[] memory single = new address[](1); - hevm.expectRevert("length mismatch"); - router.setERC20Gateway(empty, single); - hevm.expectRevert("length mismatch"); - router.setERC20Gateway(single, empty); - - // set by owner, should succeed - address[] memory _tokens = new address[](1); - address[] memory _gateways = new address[](1); - _tokens[0] = address(l2Token); - _gateways[0] = address(l2StandardERC20Gateway); - - hevm.expectEmit(true, true, true, true); - emit SetERC20Gateway(address(l2Token), address(0), address(l2StandardERC20Gateway)); - - assertEq(address(0), router.getERC20Gateway(address(l2Token))); - router.setERC20Gateway(_tokens, _gateways); - assertEq(address(l2StandardERC20Gateway), router.getERC20Gateway(address(l2Token))); - } - - function testFinalizeDepositERC20() public { - hevm.expectRevert("should never be called"); - router.finalizeDepositERC20(address(0), address(0), address(0), address(0), 0, ""); - } - - function testFinalizeDepositETH() public { - hevm.expectRevert("should never be called"); - router.finalizeDepositETH(address(0), address(0), 0, ""); - } -} diff --git a/contracts/src/test/L2GatewayTestBase.t.sol b/contracts/src/test/L2GatewayTestBase.t.sol deleted file mode 100644 index 180fba2b8..000000000 --- a/contracts/src/test/L2GatewayTestBase.t.sol +++ /dev/null @@ -1,103 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {DSTestPlus} from "solmate/test/utils/DSTestPlus.sol"; - -import {ProxyAdmin} from "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol"; -import {ITransparentUpgradeableProxy, TransparentUpgradeableProxy} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; - -import {IL1BlockContainer, L1BlockContainer} from "../L2/predeploys/L1BlockContainer.sol"; -import {IL1GasPriceOracle, L1GasPriceOracle} from "../L2/predeploys/L1GasPriceOracle.sol"; -import {L2MessageQueue} from "../L2/predeploys/L2MessageQueue.sol"; -import {Whitelist} from "../L2/predeploys/Whitelist.sol"; -import {L1ScrollMessenger} from "../L1/L1ScrollMessenger.sol"; -import {L2ScrollMessenger} from "../L2/L2ScrollMessenger.sol"; -import {EmptyContract} from "../misc/EmptyContract.sol"; - -abstract contract L2GatewayTestBase is DSTestPlus { - // from L2MessageQueue - event AppendMessage(uint256 index, bytes32 messageHash); - - // from L2ScrollMessenger - event SentMessage( - address indexed sender, - address indexed target, - uint256 value, - uint256 messageNonce, - uint256 gasLimit, - bytes message - ); - event RelayedMessage(bytes32 indexed messageHash); - event FailedRelayedMessage(bytes32 indexed messageHash); - - /********** - * Errors * - **********/ - - // from IScrollGateway - error ErrorZeroAddress(); - error ErrorCallerIsNotMessenger(); - error ErrorCallerIsNotCounterpartGateway(); - error ErrorNotInDropMessageContext(); - - // pay 0.1 extra ETH to test refund - uint256 internal constant extraValue = 1e17; - - ProxyAdmin internal admin; - EmptyContract private placeholder; - - L1ScrollMessenger internal l1Messenger; - - address internal feeVault; - Whitelist private whitelist; - - L2ScrollMessenger internal l2Messenger; - L1BlockContainer internal l1BlockContainer; - L2MessageQueue internal l2MessageQueue; - L1GasPriceOracle internal l1GasOracle; - - function setUpBase() internal { - placeholder = new EmptyContract(); - admin = new ProxyAdmin(); - feeVault = address(uint160(address(this)) - 1); - - // Deploy L1 contracts - l1Messenger = L1ScrollMessenger(payable(_deployProxy(address(0)))); - - // Deploy L2 contracts - whitelist = new Whitelist(address(this)); - l1BlockContainer = new L1BlockContainer(address(this)); - l2MessageQueue = new L2MessageQueue(address(this)); - l1GasOracle = new L1GasPriceOracle(address(this)); - l2Messenger = L2ScrollMessenger(payable(_deployProxy(address(0)))); - - // Upgrade the L2ScrollMessenger implementation and initialize - admin.upgrade( - ITransparentUpgradeableProxy(address(l2Messenger)), - address(new L2ScrollMessenger(address(l1Messenger), address(l2MessageQueue))) - ); - l2Messenger.initialize(address(l1Messenger)); - - // Initialize L2 contracts - l2MessageQueue.initialize(address(l2Messenger)); - l1GasOracle.updateWhitelist(address(whitelist)); - - address[] memory _accounts = new address[](1); - _accounts[0] = address(this); - whitelist.updateWhitelistStatus(_accounts, true); - - // make nonzero block.timestamp - hevm.warp(1); - } - - function setL1BaseFee(uint256 baseFee) internal { - l1GasOracle.setL1BaseFee(baseFee); - } - - function _deployProxy(address _logic) internal returns (address) { - if (_logic == address(0)) _logic = address(placeholder); - TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy(_logic, address(admin), new bytes(0)); - return address(proxy); - } -} diff --git a/contracts/src/test/L2MessageQueue.t.sol b/contracts/src/test/L2MessageQueue.t.sol deleted file mode 100644 index d0068c1d6..000000000 --- a/contracts/src/test/L2MessageQueue.t.sol +++ /dev/null @@ -1,76 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {DSTestPlus} from "solmate/test/utils/DSTestPlus.sol"; - -import {L2MessageQueue} from "../L2/predeploys/L2MessageQueue.sol"; - -contract L2MessageQueueTest is DSTestPlus { - L2MessageQueue queue; - - function setUp() public { - queue = new L2MessageQueue(address(this)); - queue.initialize(address(this)); - } - - function testConstructor() external { - assertEq(queue.messenger(), address(this)); - assertEq(queue.nextMessageIndex(), 0); - } - - function testPassMessageFailed() external { - // not messenger - hevm.startPrank(address(0)); - hevm.expectRevert("only messenger"); - queue.appendMessage(bytes32(0)); - hevm.stopPrank(); - } - - function testPassMessageOnceSuccess(bytes32 _message) external { - queue.appendMessage(_message); - assertEq(queue.nextMessageIndex(), 1); - assertEq(queue.branches(0), _message); - assertEq(queue.messageRoot(), _message); - } - - function testPassMessageSuccess() external { - queue.appendMessage(bytes32(uint256(1))); - assertEq(queue.nextMessageIndex(), 1); - assertEq(queue.branches(0), bytes32(uint256(1))); - assertEq(queue.messageRoot(), bytes32(uint256(1))); - - queue.appendMessage(bytes32(uint256(2))); - assertEq(queue.nextMessageIndex(), 2); - assertEq( - queue.branches(1), - bytes32(uint256(0xe90b7bceb6e7df5418fb78d8ee546e97c83a08bbccc01a0644d599ccd2a7c2e0)) - ); - assertEq( - queue.messageRoot(), - bytes32(uint256(0xe90b7bceb6e7df5418fb78d8ee546e97c83a08bbccc01a0644d599ccd2a7c2e0)) - ); - - queue.appendMessage(bytes32(uint256(3))); - assertEq(queue.nextMessageIndex(), 3); - assertEq( - queue.branches(2), - bytes32(uint256(0x222ff5e0b5877792c2bc1670e2ccd0c2c97cd7bb1672a57d598db05092d3d72c)) - ); - assertEq( - queue.messageRoot(), - bytes32(uint256(0x222ff5e0b5877792c2bc1670e2ccd0c2c97cd7bb1672a57d598db05092d3d72c)) - ); - - queue.appendMessage(bytes32(uint256(4))); - assertEq(queue.nextMessageIndex(), 4); - assertEq( - queue.branches(2), - bytes32(uint256(0xa9bb8c3f1f12e9aa903a50c47f314b57610a3ab32f2d463293f58836def38d36)) - ); - assertEq( - queue.messageRoot(), - bytes32(uint256(0xa9bb8c3f1f12e9aa903a50c47f314b57610a3ab32f2d463293f58836def38d36)) - ); - } -} diff --git a/contracts/src/test/L2ScrollMessenger.t.sol b/contracts/src/test/L2ScrollMessenger.t.sol deleted file mode 100644 index 6dea30edc..000000000 --- a/contracts/src/test/L2ScrollMessenger.t.sol +++ /dev/null @@ -1,83 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {DSTestPlus} from "solmate/test/utils/DSTestPlus.sol"; - -import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; - -import {L1BlockContainer} from "../L2/predeploys/L1BlockContainer.sol"; -import {L1GasPriceOracle} from "../L2/predeploys/L1GasPriceOracle.sol"; -import {L2MessageQueue} from "../L2/predeploys/L2MessageQueue.sol"; -import {Whitelist} from "../L2/predeploys/Whitelist.sol"; -import {L1ScrollMessenger} from "../L1/L1ScrollMessenger.sol"; -import {L2ScrollMessenger} from "../L2/L2ScrollMessenger.sol"; - -import {AddressAliasHelper} from "../libraries/common/AddressAliasHelper.sol"; - -contract L2ScrollMessengerTest is DSTestPlus { - L1ScrollMessenger internal l1Messenger; - - address internal feeVault; - Whitelist private whitelist; - - L2ScrollMessenger internal l2Messenger; - L1BlockContainer internal l1BlockContainer; - L2MessageQueue internal l2MessageQueue; - L1GasPriceOracle internal l1GasOracle; - - function setUp() public { - // Deploy L1 contracts - l1Messenger = new L1ScrollMessenger(address(1), address(1), address(1)); - - // Deploy L2 contracts - whitelist = new Whitelist(address(this)); - l1BlockContainer = new L1BlockContainer(address(this)); - l2MessageQueue = new L2MessageQueue(address(this)); - l1GasOracle = new L1GasPriceOracle(address(this)); - l2Messenger = L2ScrollMessenger( - payable( - new ERC1967Proxy( - address(new L2ScrollMessenger(address(l1Messenger), address(l2MessageQueue))), - new bytes(0) - ) - ) - ); - - // Initialize L2 contracts - l2Messenger.initialize(address(l1Messenger)); - l2MessageQueue.initialize(address(l2Messenger)); - l1GasOracle.updateWhitelist(address(whitelist)); - } - - function testRelayByCounterparty() external { - hevm.expectRevert("Caller is not L1ScrollMessenger"); - l2Messenger.relayMessage(address(this), address(this), 0, 0, new bytes(0)); - } - - function testForbidCallFromL1() external { - hevm.startPrank(AddressAliasHelper.applyL1ToL2Alias(address(l1Messenger))); - hevm.expectRevert("Forbid to call message queue"); - l2Messenger.relayMessage(address(this), address(l2MessageQueue), 0, 0, new bytes(0)); - - hevm.expectRevert("Forbid to call self"); - l2Messenger.relayMessage(address(this), address(l2Messenger), 0, 0, new bytes(0)); - hevm.stopPrank(); - } - - function testSendMessage(address refundAddress) external { - hevm.assume(refundAddress.code.length == 0); - hevm.assume(uint256(uint160(refundAddress)) > 100); // ignore some precompile contracts - hevm.assume(refundAddress != address(0x000000000000000000636F6e736F6c652e6c6f67)); // ignore console/console2 - hevm.assume(refundAddress != address(this)); - - // Insufficient msg.value - hevm.expectRevert("msg.value mismatch"); - l2Messenger.sendMessage(address(0), 1, new bytes(0), 21000, refundAddress); - - // succeed normally - uint256 balanceBefore = refundAddress.balance; - l2Messenger.sendMessage{value: 1}(address(0), 1, new bytes(0), 21000, refundAddress); - assertEq(balanceBefore, refundAddress.balance); - } -} diff --git a/contracts/src/test/L2StandardERC20Gateway.t.sol b/contracts/src/test/L2StandardERC20Gateway.t.sol deleted file mode 100644 index a1fb335a1..000000000 --- a/contracts/src/test/L2StandardERC20Gateway.t.sol +++ /dev/null @@ -1,601 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {MockERC20} from "solmate/test/utils/mocks/MockERC20.sol"; - -import {ITransparentUpgradeableProxy} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; - -import {IL1ERC20Gateway, L1StandardERC20Gateway} from "../L1/gateways/L1StandardERC20Gateway.sol"; -import {L2GatewayRouter} from "../L2/gateways/L2GatewayRouter.sol"; -import {IL2ERC20Gateway, L2StandardERC20Gateway} from "../L2/gateways/L2StandardERC20Gateway.sol"; -import {ScrollStandardERC20} from "../libraries/token/ScrollStandardERC20.sol"; -import {ScrollStandardERC20Factory} from "../libraries/token/ScrollStandardERC20Factory.sol"; - -import {AddressAliasHelper} from "../libraries/common/AddressAliasHelper.sol"; - -import {L2GatewayTestBase} from "./L2GatewayTestBase.t.sol"; -import {MockScrollMessenger} from "./mocks/MockScrollMessenger.sol"; -import {MockGatewayRecipient} from "./mocks/MockGatewayRecipient.sol"; - -contract L2StandardERC20GatewayTest is L2GatewayTestBase { - // from L2StandardERC20Gateway - event WithdrawERC20( - address indexed _l1Token, - address indexed _l2Token, - address indexed _from, - address _to, - uint256 _amount, - bytes _data - ); - event FinalizeDepositERC20( - address indexed _l1Token, - address indexed _l2Token, - address indexed _from, - address _to, - uint256 _amount, - bytes _data - ); - - ScrollStandardERC20 private template; - ScrollStandardERC20Factory private factory; - - L2StandardERC20Gateway private gateway; - L2GatewayRouter private router; - - L1StandardERC20Gateway private counterpartGateway; - - MockERC20 private badToken; - MockERC20 private l1Token; - MockERC20 private l2Token; - - function setUp() public { - setUpBase(); - - // Deploy tokens - l1Token = new MockERC20("L1", "L1", 18); - badToken = new MockERC20("Mock Bad", "M", 18); - template = new ScrollStandardERC20(); - factory = new ScrollStandardERC20Factory(address(template)); - - // Deploy L1 contracts - counterpartGateway = new L1StandardERC20Gateway( - address(1), - address(1), - address(1), - address(template), - address(factory) - ); - - // Deploy L2 contracts - router = L2GatewayRouter(_deployProxy(address(new L2GatewayRouter()))); - gateway = _deployGateway(address(l2Messenger)); - - // Initialize L2 contracts - factory.transferOwnership(address(gateway)); - gateway.initialize(address(counterpartGateway), address(router), address(l2Messenger), address(factory)); - router.initialize(address(0), address(gateway)); - - // Prepare token balances - l2Token = MockERC20(gateway.getL2ERC20Address(address(l1Token))); - hevm.startPrank(AddressAliasHelper.applyL1ToL2Alias(address(l1Messenger))); - l2Messenger.relayMessage( - address(counterpartGateway), - address(gateway), - 0, - 0, - abi.encodeWithSelector( - L2StandardERC20Gateway.finalizeDepositERC20.selector, - address(l1Token), - address(l2Token), - address(this), - address(this), - type(uint128).max, - abi.encode(true, abi.encode("", abi.encode("symbol", "name", 18))) - ) - ); - hevm.stopPrank(); - } - - function testInitialized() public { - assertEq(address(counterpartGateway), gateway.counterpart()); - assertEq(address(router), gateway.router()); - assertEq(address(l2Messenger), gateway.messenger()); - assertEq(address(factory), gateway.tokenFactory()); - assertEq(address(l1Token), gateway.getL1ERC20Address(address(l2Token))); - - hevm.expectRevert("Initializable: contract is already initialized"); - gateway.initialize(address(counterpartGateway), address(router), address(l1Messenger), address(factory)); - } - - function testGetL2ERC20Address(address l1Address) public { - assertEq(gateway.getL2ERC20Address(l1Address), factory.computeL2TokenAddress(address(gateway), l1Address)); - } - - function testWithdrawERC20( - uint256 amount, - uint256 gasLimit, - uint256 feePerGas - ) public { - _withdrawERC20(false, amount, gasLimit, feePerGas); - } - - function testWithdrawERC20WithRecipient( - uint256 amount, - address recipient, - uint256 gasLimit, - uint256 feePerGas - ) public { - _withdrawERC20WithRecipient(false, amount, recipient, gasLimit, feePerGas); - } - - function testWithdrawERC20WithRecipientAndCalldata( - uint256 amount, - address recipient, - bytes memory dataToCall, - uint256 gasLimit, - uint256 feePerGas - ) public { - _withdrawERC20WithRecipientAndCalldata(false, amount, recipient, dataToCall, gasLimit, feePerGas); - } - - function testRouterDepositERC20( - uint256 amount, - uint256 gasLimit, - uint256 feePerGas - ) public { - _withdrawERC20(true, amount, gasLimit, feePerGas); - } - - function testRouterDepositERC20WithRecipient( - uint256 amount, - address recipient, - uint256 gasLimit, - uint256 feePerGas - ) public { - _withdrawERC20WithRecipient(true, amount, recipient, gasLimit, feePerGas); - } - - function testRouterDepositERC20WithRecipientAndCalldata( - uint256 amount, - address recipient, - bytes memory dataToCall, - uint256 gasLimit, - uint256 feePerGas - ) public { - _withdrawERC20WithRecipientAndCalldata(true, amount, recipient, dataToCall, gasLimit, feePerGas); - } - - function testFinalizeDepositERC20FailedMocking( - address sender, - address recipient, - uint256 amount, - bytes memory dataToCall - ) public { - amount = bound(amount, 1, 100000); - - // revert when caller is not messenger - hevm.expectRevert(ErrorCallerIsNotMessenger.selector); - gateway.finalizeDepositERC20(address(l1Token), address(l2Token), sender, recipient, amount, dataToCall); - - MockScrollMessenger mockMessenger = new MockScrollMessenger(); - gateway = _deployGateway(address(mockMessenger)); - gateway.initialize(address(counterpartGateway), address(router), address(mockMessenger), address(factory)); - - // only call by counterpart - hevm.expectRevert(ErrorCallerIsNotCounterpartGateway.selector); - mockMessenger.callTarget( - address(gateway), - abi.encodeWithSelector( - gateway.finalizeDepositERC20.selector, - address(l1Token), - address(l2Token), - sender, - recipient, - amount, - dataToCall - ) - ); - - mockMessenger.setXDomainMessageSender(address(counterpartGateway)); - - // msg.value mismatch - hevm.expectRevert("nonzero msg.value"); - mockMessenger.callTarget{value: 1}( - address(gateway), - abi.encodeWithSelector( - gateway.finalizeDepositERC20.selector, - address(l1Token), - address(l2Token), - sender, - recipient, - amount, - dataToCall - ) - ); - - // l1 token mismatch - hevm.expectRevert("l2 token mismatch"); - mockMessenger.callTarget( - address(gateway), - abi.encodeWithSelector( - gateway.finalizeDepositERC20.selector, - address(l2Token), - address(l2Token), - sender, - recipient, - amount, - dataToCall - ) - ); - } - - function testFinalizeDepositERC20Failed( - address sender, - address recipient, - uint256 amount, - bytes memory dataToCall - ) public { - // blacklist some addresses - hevm.assume(recipient != address(0)); - - amount = bound(amount, 1, l2Token.balanceOf(address(this))); - - // do finalize withdraw token - bytes memory message = abi.encodeWithSelector( - IL2ERC20Gateway.finalizeDepositERC20.selector, - address(l1Token), - address(l2Token), - sender, - recipient, - amount, - dataToCall - ); - bytes memory xDomainCalldata = abi.encodeWithSignature( - "relayMessage(address,address,uint256,uint256,bytes)", - address(uint160(address(counterpartGateway)) + 1), - address(gateway), - 0, - 0, - message - ); - - // counterpart is not L2WETHGateway - // emit FailedRelayedMessage from L1ScrollMessenger - hevm.expectEmit(true, false, false, true); - emit FailedRelayedMessage(keccak256(xDomainCalldata)); - - uint256 gatewayBalance = l2Token.balanceOf(address(gateway)); - uint256 recipientBalance = l2Token.balanceOf(recipient); - assertBoolEq(false, l2Messenger.isL1MessageExecuted(keccak256(xDomainCalldata))); - hevm.startPrank(AddressAliasHelper.applyL1ToL2Alias(address(l1Messenger))); - l2Messenger.relayMessage(address(uint160(address(counterpartGateway)) + 1), address(gateway), 0, 0, message); - hevm.stopPrank(); - assertEq(gatewayBalance, l2Token.balanceOf(address(gateway))); - assertEq(recipientBalance, l2Token.balanceOf(recipient)); - assertBoolEq(false, l2Messenger.isL1MessageExecuted(keccak256(xDomainCalldata))); - } - - function testFinalizeDepositERC20( - address sender, - uint256 amount, - bytes memory dataToCall - ) public { - MockGatewayRecipient recipient = new MockGatewayRecipient(); - - amount = bound(amount, 1, l2Token.balanceOf(address(this))); - - // do finalize withdraw token - bytes memory message = abi.encodeWithSelector( - IL2ERC20Gateway.finalizeDepositERC20.selector, - address(l1Token), - address(l2Token), - sender, - address(recipient), - amount, - abi.encode(false, dataToCall) - ); - bytes memory xDomainCalldata = abi.encodeWithSignature( - "relayMessage(address,address,uint256,uint256,bytes)", - address(counterpartGateway), - address(gateway), - 0, - 0, - message - ); - - // emit FinalizeDepositERC20 from L2StandardERC20Gateway - { - hevm.expectEmit(true, true, true, true); - emit FinalizeDepositERC20( - address(l1Token), - address(l2Token), - sender, - address(recipient), - amount, - dataToCall - ); - } - - // emit RelayedMessage from L2ScrollMessenger - { - hevm.expectEmit(true, false, false, true); - emit RelayedMessage(keccak256(xDomainCalldata)); - } - - uint256 gatewayBalance = l2Token.balanceOf(address(gateway)); - uint256 recipientBalance = l2Token.balanceOf(address(recipient)); - assertBoolEq(false, l2Messenger.isL1MessageExecuted(keccak256(xDomainCalldata))); - hevm.startPrank(AddressAliasHelper.applyL1ToL2Alias(address(l1Messenger))); - l2Messenger.relayMessage(address(counterpartGateway), address(gateway), 0, 0, message); - hevm.stopPrank(); - assertEq(gatewayBalance, l2Token.balanceOf(address(gateway))); - assertEq(recipientBalance + amount, l2Token.balanceOf(address(recipient))); - assertBoolEq(true, l2Messenger.isL1MessageExecuted(keccak256(xDomainCalldata))); - } - - function _withdrawERC20( - bool useRouter, - uint256 amount, - uint256 gasLimit, - uint256 feePerGas - ) private { - amount = bound(amount, 0, l2Token.balanceOf(address(this))); - gasLimit = bound(gasLimit, 21000, 1000000); - feePerGas = 0; - - setL1BaseFee(feePerGas); - - uint256 feeToPay = feePerGas * gasLimit; - bytes memory message = abi.encodeWithSelector( - IL1ERC20Gateway.finalizeWithdrawERC20.selector, - address(l1Token), - address(l2Token), - address(this), - address(this), - amount, - new bytes(0) - ); - bytes memory xDomainCalldata = abi.encodeWithSignature( - "relayMessage(address,address,uint256,uint256,bytes)", - address(gateway), - address(counterpartGateway), - 0, - 0, - message - ); - - if (amount == 0) { - hevm.expectRevert("withdraw zero amount"); - if (useRouter) { - router.withdrawERC20{value: feeToPay}(address(l2Token), amount, gasLimit); - } else { - gateway.withdrawERC20{value: feeToPay}(address(l2Token), amount, gasLimit); - } - } else { - hevm.expectRevert("no corresponding l1 token"); - if (useRouter) { - router.withdrawERC20{value: feeToPay}(address(l1Token), amount, gasLimit); - } else { - gateway.withdrawERC20{value: feeToPay}(address(l1Token), amount, gasLimit); - } - - // emit AppendMessage from L2MessageQueue - { - hevm.expectEmit(false, false, false, true); - emit AppendMessage(0, keccak256(xDomainCalldata)); - } - - // emit SentMessage from L2ScrollMessenger - { - hevm.expectEmit(true, true, false, true); - emit SentMessage(address(gateway), address(counterpartGateway), 0, 0, gasLimit, message); - } - - // emit WithdrawERC20 from L2StandardERC20Gateway - hevm.expectEmit(true, true, true, true); - emit WithdrawERC20(address(l1Token), address(l2Token), address(this), address(this), amount, new bytes(0)); - - uint256 gatewayBalance = l2Token.balanceOf(address(gateway)); - uint256 feeVaultBalance = address(feeVault).balance; - assertEq(l2Messenger.messageSendTimestamp(keccak256(xDomainCalldata)), 0); - if (useRouter) { - router.withdrawERC20{value: feeToPay}(address(l2Token), amount, gasLimit); - } else { - gateway.withdrawERC20{value: feeToPay}(address(l2Token), amount, gasLimit); - } - assertEq(gatewayBalance, l2Token.balanceOf(address(gateway))); - assertEq(feeToPay + feeVaultBalance, address(feeVault).balance); - assertGt(l2Messenger.messageSendTimestamp(keccak256(xDomainCalldata)), 0); - } - } - - function _withdrawERC20WithRecipient( - bool useRouter, - uint256 amount, - address recipient, - uint256 gasLimit, - uint256 feePerGas - ) private { - amount = bound(amount, 0, l2Token.balanceOf(address(this))); - gasLimit = bound(gasLimit, 21000, 1000000); - feePerGas = 0; - - setL1BaseFee(feePerGas); - - uint256 feeToPay = feePerGas * gasLimit; - bytes memory message = abi.encodeWithSelector( - IL1ERC20Gateway.finalizeWithdrawERC20.selector, - address(l1Token), - address(l2Token), - address(this), - recipient, - amount, - new bytes(0) - ); - bytes memory xDomainCalldata = abi.encodeWithSignature( - "relayMessage(address,address,uint256,uint256,bytes)", - address(gateway), - address(counterpartGateway), - 0, - 0, - message - ); - - if (amount == 0) { - hevm.expectRevert("withdraw zero amount"); - if (useRouter) { - router.withdrawERC20{value: feeToPay}(address(l2Token), recipient, amount, gasLimit); - } else { - gateway.withdrawERC20{value: feeToPay}(address(l2Token), recipient, amount, gasLimit); - } - } else { - hevm.expectRevert("no corresponding l1 token"); - if (useRouter) { - router.withdrawERC20{value: feeToPay}(address(l1Token), recipient, amount, gasLimit); - } else { - gateway.withdrawERC20{value: feeToPay}(address(l1Token), recipient, amount, gasLimit); - } - - // emit AppendMessage from L2MessageQueue - { - hevm.expectEmit(false, false, false, true); - emit AppendMessage(0, keccak256(xDomainCalldata)); - } - - // emit SentMessage from L1ScrollMessenger - { - hevm.expectEmit(true, true, false, true); - emit SentMessage(address(gateway), address(counterpartGateway), 0, 0, gasLimit, message); - } - - // emit WithdrawERC20 from L1StandardERC20Gateway - hevm.expectEmit(true, true, true, true); - emit WithdrawERC20(address(l1Token), address(l2Token), address(this), recipient, amount, new bytes(0)); - - uint256 gatewayBalance = l2Token.balanceOf(address(gateway)); - uint256 feeVaultBalance = address(feeVault).balance; - assertEq(l2Messenger.messageSendTimestamp(keccak256(xDomainCalldata)), 0); - if (useRouter) { - router.withdrawERC20{value: feeToPay}(address(l2Token), recipient, amount, gasLimit); - } else { - gateway.withdrawERC20{value: feeToPay}(address(l2Token), recipient, amount, gasLimit); - } - assertEq(gatewayBalance, l2Token.balanceOf(address(gateway))); - assertEq(feeToPay + feeVaultBalance, address(feeVault).balance); - assertGt(l2Messenger.messageSendTimestamp(keccak256(xDomainCalldata)), 0); - } - } - - function _withdrawERC20WithRecipientAndCalldata( - bool useRouter, - uint256 amount, - address recipient, - bytes memory dataToCall, - uint256 gasLimit, - uint256 feePerGas - ) private { - amount = bound(amount, 0, l2Token.balanceOf(address(this))); - gasLimit = bound(gasLimit, 21000, 1000000); - feePerGas = 0; - - setL1BaseFee(feePerGas); - - uint256 feeToPay = feePerGas * gasLimit; - bytes memory message = abi.encodeWithSelector( - IL1ERC20Gateway.finalizeWithdrawERC20.selector, - address(l1Token), - address(l2Token), - address(this), - recipient, - amount, - dataToCall - ); - bytes memory xDomainCalldata = abi.encodeWithSignature( - "relayMessage(address,address,uint256,uint256,bytes)", - address(gateway), - address(counterpartGateway), - 0, - 0, - message - ); - - if (amount == 0) { - hevm.expectRevert("withdraw zero amount"); - if (useRouter) { - router.withdrawERC20AndCall{value: feeToPay}(address(l2Token), recipient, amount, dataToCall, gasLimit); - } else { - gateway.withdrawERC20AndCall{value: feeToPay}( - address(l2Token), - recipient, - amount, - dataToCall, - gasLimit - ); - } - } else { - hevm.expectRevert("no corresponding l1 token"); - if (useRouter) { - router.withdrawERC20AndCall{value: feeToPay}(address(l1Token), recipient, amount, dataToCall, gasLimit); - } else { - gateway.withdrawERC20AndCall{value: feeToPay}( - address(l1Token), - recipient, - amount, - dataToCall, - gasLimit - ); - } - - // emit AppendMessage from L2MessageQueue - { - hevm.expectEmit(false, false, false, true); - emit AppendMessage(0, keccak256(xDomainCalldata)); - } - - // emit SentMessage from L1ScrollMessenger - { - hevm.expectEmit(true, true, false, true); - emit SentMessage(address(gateway), address(counterpartGateway), 0, 0, gasLimit, message); - } - - // emit WithdrawERC20 from L1StandardERC20Gateway - hevm.expectEmit(true, true, true, true); - emit WithdrawERC20(address(l1Token), address(l2Token), address(this), recipient, amount, dataToCall); - - uint256 gatewayBalance = l2Token.balanceOf(address(gateway)); - uint256 feeVaultBalance = address(feeVault).balance; - assertEq(l2Messenger.messageSendTimestamp(keccak256(xDomainCalldata)), 0); - if (useRouter) { - router.withdrawERC20AndCall{value: feeToPay}(address(l2Token), recipient, amount, dataToCall, gasLimit); - } else { - gateway.withdrawERC20AndCall{value: feeToPay}( - address(l2Token), - recipient, - amount, - dataToCall, - gasLimit - ); - } - assertEq(gatewayBalance, l2Token.balanceOf(address(gateway))); - assertEq(feeToPay + feeVaultBalance, address(feeVault).balance); - assertGt(l2Messenger.messageSendTimestamp(keccak256(xDomainCalldata)), 0); - } - } - - function _deployGateway(address messenger) internal returns (L2StandardERC20Gateway _gateway) { - _gateway = L2StandardERC20Gateway(_deployProxy(address(0))); - - admin.upgrade( - ITransparentUpgradeableProxy(address(_gateway)), - address( - new L2StandardERC20Gateway( - address(counterpartGateway), - address(router), - address(messenger), - address(factory) - ) - ) - ); - } -} diff --git a/contracts/src/test/L2TxFeeVault.t.sol b/contracts/src/test/L2TxFeeVault.t.sol deleted file mode 100644 index 04f3d89e9..000000000 --- a/contracts/src/test/L2TxFeeVault.t.sol +++ /dev/null @@ -1,154 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {DSTestPlus} from "solmate/test/utils/DSTestPlus.sol"; - -import {MockScrollMessenger} from "./mocks/MockScrollMessenger.sol"; -import {L2TxFeeVault} from "../L2/predeploys/L2TxFeeVault.sol"; - -contract L2TxFeeVaultTest is DSTestPlus { - // events - event UpdateMessenger(address indexed oldMessenger, address indexed newMessenger); - event UpdateRecipient(address indexed oldRecipient, address indexed newRecipient); - event UpdateMinWithdrawAmount(uint256 oldMinWithdrawAmount, uint256 newMinWithdrawAmount); - - MockScrollMessenger private messenger; - L2TxFeeVault private vault; - - function setUp() public { - messenger = new MockScrollMessenger(); - vault = new L2TxFeeVault(address(this), address(1), 10 ether); - vault.updateMessenger(address(messenger)); - } - - function testCantWithdrawBelowMinimum() public { - hevm.deal(address(vault), 9 ether); - hevm.expectRevert("FeeVault: withdrawal amount must be greater than minimum withdrawal amount"); - vault.withdraw(); - } - - function testCantWithdrawAmountBelowMinimum(uint256 amount) public { - amount = bound(amount, 0 ether, 10 ether - 1); - hevm.deal(address(vault), 100 ether); - hevm.expectRevert("FeeVault: withdrawal amount must be greater than minimum withdrawal amount"); - vault.withdraw(amount); - } - - function testCantWithdrawMoreThanBalance(uint256 amount) public { - hevm.assume(amount >= 10 ether); - hevm.deal(address(vault), amount - 1); - hevm.expectRevert("FeeVault: insufficient balance to withdraw"); - vault.withdraw(amount); - } - - function testWithdrawOnce() public { - hevm.deal(address(vault), 11 ether); - vault.withdraw(); - assertEq(address(messenger).balance, 11 ether); - assertEq(vault.totalProcessed(), 11 ether); - } - - function testWithdrawAmountOnce(uint256 amount) public { - amount = bound(amount, 10 ether, 100 ether); - - hevm.deal(address(vault), 100 ether); - vault.withdraw(amount); - - assertEq(address(messenger).balance, amount); - assertEq(vault.totalProcessed(), amount); - assertEq(address(vault).balance, 100 ether - amount); - } - - function testWithdrawTwice() public { - hevm.deal(address(vault), 11 ether); - vault.withdraw(); - assertEq(address(messenger).balance, 11 ether); - assertEq(vault.totalProcessed(), 11 ether); - - hevm.deal(address(vault), 22 ether); - vault.withdraw(); - assertEq(address(messenger).balance, 33 ether); - assertEq(vault.totalProcessed(), 33 ether); - } - - function testWithdrawAmountTwice(uint256 amount1, uint256 amount2) public { - amount1 = bound(amount1, 10 ether, 100 ether); - amount2 = bound(amount2, 10 ether, 100 ether); - - hevm.deal(address(vault), 200 ether); - - vault.withdraw(amount1); - assertEq(address(messenger).balance, amount1); - assertEq(vault.totalProcessed(), amount1); - - vault.withdraw(amount2); - assertEq(address(messenger).balance, amount1 + amount2); - assertEq(vault.totalProcessed(), amount1 + amount2); - - assertEq(address(vault).balance, 200 ether - amount1 - amount2); - } - - function testUpdateMinWithdrawAmount(uint256 amount1, uint256 amount2) external { - // set by non-owner, should revert - hevm.startPrank(address(1)); - hevm.expectRevert("caller is not the owner"); - vault.updateMinWithdrawAmount(amount1); - hevm.stopPrank(); - - // set by owner, should succeed - assertEq(10 ether, vault.minWithdrawAmount()); - - hevm.expectEmit(false, false, false, true); - emit UpdateMinWithdrawAmount(10 ether, amount1); - vault.updateMinWithdrawAmount(amount1); - assertEq(amount1, vault.minWithdrawAmount()); - - hevm.expectEmit(false, false, false, true); - emit UpdateMinWithdrawAmount(amount1, amount2); - vault.updateMinWithdrawAmount(amount2); - assertEq(amount2, vault.minWithdrawAmount()); - } - - function testUpdateRecipient(address recipient1, address recipient2) external { - // set by non-owner, should revert - hevm.startPrank(address(1)); - hevm.expectRevert("caller is not the owner"); - vault.updateRecipient(recipient1); - hevm.stopPrank(); - - // set by owner, should succeed - assertEq(address(1), vault.recipient()); - - hevm.expectEmit(true, true, false, true); - emit UpdateRecipient(address(1), recipient1); - vault.updateRecipient(recipient1); - assertEq(recipient1, vault.recipient()); - - hevm.expectEmit(true, true, false, true); - emit UpdateRecipient(recipient1, recipient2); - vault.updateRecipient(recipient2); - assertEq(recipient2, vault.recipient()); - } - - function testUpdateMessenger(address messenger1, address messenger2) external { - // set by non-owner, should revert - hevm.startPrank(address(1)); - hevm.expectRevert("caller is not the owner"); - vault.updateMessenger(messenger1); - hevm.stopPrank(); - - // set by owner, should succeed - assertEq(address(messenger), vault.messenger()); - - hevm.expectEmit(true, true, false, true); - emit UpdateMessenger(address(messenger), messenger1); - vault.updateMessenger(messenger1); - assertEq(messenger1, vault.messenger()); - - hevm.expectEmit(true, true, false, true); - emit UpdateMessenger(messenger1, messenger2); - vault.updateMessenger(messenger2); - assertEq(messenger2, vault.messenger()); - } -} diff --git a/contracts/src/test/L2USDCGateway.t.sol b/contracts/src/test/L2USDCGateway.t.sol deleted file mode 100644 index 498275d42..000000000 --- a/contracts/src/test/L2USDCGateway.t.sol +++ /dev/null @@ -1,543 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {ITransparentUpgradeableProxy} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; - -import {L1USDCGateway} from "../L1/gateways/usdc/L1USDCGateway.sol"; -import {IL1ERC20Gateway} from "../L1/gateways/IL1ERC20Gateway.sol"; -import {L2GatewayRouter} from "../L2/gateways/L2GatewayRouter.sol"; -import {IL2ERC20Gateway, L2USDCGateway} from "../L2/gateways/usdc/L2USDCGateway.sol"; - -import {MockERC20} from "../mocks/MockERC20.sol"; - -import {AddressAliasHelper} from "../libraries/common/AddressAliasHelper.sol"; - -import {L2GatewayTestBase} from "./L2GatewayTestBase.t.sol"; -import {MockScrollMessenger} from "./mocks/MockScrollMessenger.sol"; -import {MockGatewayRecipient} from "./mocks/MockGatewayRecipient.sol"; - -contract L2USDCGatewayTest is L2GatewayTestBase { - // from L2USDCGateway - event WithdrawERC20( - address indexed _l1Token, - address indexed _l2Token, - address indexed _from, - address _to, - uint256 _amount, - bytes _data - ); - event FinalizeDepositERC20( - address indexed _l1Token, - address indexed _l2Token, - address indexed _from, - address _to, - uint256 _amount, - bytes _data - ); - - MockERC20 private l1USDC; - MockERC20 private l2USDC; - - L2USDCGateway private gateway; - L2GatewayRouter private router; - - L1USDCGateway private counterpartGateway; - - function setUp() public { - setUpBase(); - - // Deploy tokens - l1USDC = new MockERC20("USDC", "USDC", 6); - l2USDC = new MockERC20("USDC", "USDC", 6); - - // Deploy L1 contracts - counterpartGateway = new L1USDCGateway(address(l1USDC), address(l2USDC), address(1), address(1), address(1)); - - // Deploy L2 contracts - router = L2GatewayRouter(_deployProxy(address(new L2GatewayRouter()))); - gateway = _deployGateway(address(l2Messenger)); - - // Initialize L2 contracts - gateway.initialize(address(counterpartGateway), address(router), address(l2Messenger)); - router.initialize(address(0), address(gateway)); - - // Prepare token balances - l2USDC.mint(address(this), type(uint128).max); - l2USDC.approve(address(gateway), type(uint256).max); - l2USDC.transferOwnership(address(gateway)); - } - - function testInitialized() public { - assertEq(l2USDC.owner(), address(gateway)); - assertEq(address(counterpartGateway), gateway.counterpart()); - assertEq(address(router), gateway.router()); - assertEq(address(l2Messenger), gateway.messenger()); - assertEq(address(l1USDC), gateway.l1USDC()); - assertEq(address(l2USDC), gateway.l2USDC()); - assertEq(address(l1USDC), gateway.getL1ERC20Address(address(l2USDC))); - assertEq(address(l2USDC), gateway.getL2ERC20Address(address(l1USDC))); - - hevm.expectRevert("Initializable: contract is already initialized"); - gateway.initialize(address(counterpartGateway), address(router), address(l2Messenger)); - } - - function testTransferUSDCRoles(address owner) external { - hevm.assume(owner != address(0)); - - // non-whitelisted caller call, should revert - hevm.expectRevert("only circle caller"); - gateway.transferUSDCRoles(owner); - - // whitelisted caller call - gateway.updateCircleCaller(address(this)); - assertEq(l2USDC.owner(), address(gateway)); - gateway.transferUSDCRoles(owner); - assertEq(l2USDC.owner(), owner); - } - - function testUpdateCircleCaller(address caller) external { - // non-owner call pause, should revert - hevm.startPrank(address(1)); - hevm.expectRevert("Ownable: caller is not the owner"); - gateway.updateCircleCaller(caller); - hevm.stopPrank(); - - // succeed - assertEq(address(0), gateway.circleCaller()); - gateway.updateCircleCaller(caller); - assertEq(caller, gateway.circleCaller()); - } - - function testWithdrawPaused() public { - // non-owner call pause, should revert - hevm.startPrank(address(1)); - hevm.expectRevert("Ownable: caller is not the owner"); - gateway.pauseWithdraw(false); - hevm.expectRevert("Ownable: caller is not the owner"); - gateway.pauseWithdraw(true); - hevm.stopPrank(); - - // pause withdraw - gateway.pauseWithdraw(true); - - // withdraw paused, should revert - hevm.expectRevert("withdraw paused"); - gateway.withdrawERC20(address(l2USDC), 1, 0); - hevm.expectRevert("withdraw paused"); - gateway.withdrawERC20(address(l2USDC), address(this), 1, 0); - hevm.expectRevert("withdraw paused"); - gateway.withdrawERC20AndCall(address(l2USDC), address(this), 1, new bytes(0), 0); - } - - function testPauseDeposit() public { - // non-owner call pause, should revert - hevm.startPrank(address(1)); - hevm.expectRevert("Ownable: caller is not the owner"); - gateway.pauseDeposit(false); - hevm.expectRevert("Ownable: caller is not the owner"); - gateway.pauseDeposit(true); - hevm.stopPrank(); - } - - function testWithdrawERC20( - uint256 amount, - uint256 gasLimit, - uint256 feePerGas - ) public { - _withdrawERC20(false, amount, gasLimit, feePerGas); - } - - function testWithdrawERC20WithRecipient( - uint256 amount, - address recipient, - uint256 gasLimit, - uint256 feePerGas - ) public { - _withdrawERC20WithRecipient(false, amount, recipient, gasLimit, feePerGas); - } - - function testRouterWithdrawERC20( - uint256 amount, - uint256 gasLimit, - uint256 feePerGas - ) public { - _withdrawERC20(true, amount, gasLimit, feePerGas); - } - - function testRouterWithdrawERC20WithRecipient( - uint256 amount, - address recipient, - uint256 gasLimit, - uint256 feePerGas - ) public { - _withdrawERC20WithRecipient(true, amount, recipient, gasLimit, feePerGas); - } - - function testFinalizeDepositERC20FailedMocking( - address sender, - address recipient, - uint256 amount, - bytes memory dataToCall - ) public { - amount = bound(amount, 1, 100000); - - // revert when caller is not messenger - hevm.expectRevert(ErrorCallerIsNotMessenger.selector); - gateway.finalizeDepositERC20(address(l1USDC), address(l2USDC), sender, recipient, amount, dataToCall); - - MockScrollMessenger mockMessenger = new MockScrollMessenger(); - gateway = _deployGateway(address(mockMessenger)); - gateway.initialize(address(counterpartGateway), address(router), address(mockMessenger)); - - // only call by counterpart - hevm.expectRevert(ErrorCallerIsNotCounterpartGateway.selector); - mockMessenger.callTarget( - address(gateway), - abi.encodeWithSelector( - gateway.finalizeDepositERC20.selector, - address(l1USDC), - address(l2USDC), - sender, - recipient, - amount, - dataToCall - ) - ); - - mockMessenger.setXDomainMessageSender(address(counterpartGateway)); - - // nonzero msg.value - hevm.expectRevert("nonzero msg.value"); - mockMessenger.callTarget{value: 1}( - address(gateway), - abi.encodeWithSelector( - gateway.finalizeDepositERC20.selector, - address(l1USDC), - address(l2USDC), - sender, - recipient, - amount, - dataToCall - ) - ); - - // l1 token not USDC - hevm.expectRevert("l1 token not USDC"); - mockMessenger.callTarget( - address(gateway), - abi.encodeWithSelector( - gateway.finalizeDepositERC20.selector, - address(l2USDC), - address(l2USDC), - sender, - recipient, - amount, - dataToCall - ) - ); - - // l2 token not USDC - hevm.expectRevert("l2 token not USDC"); - mockMessenger.callTarget( - address(gateway), - abi.encodeWithSelector( - gateway.finalizeDepositERC20.selector, - address(l1USDC), - address(l1USDC), - sender, - recipient, - amount, - dataToCall - ) - ); - - // deposit paused - gateway.pauseDeposit(true); - hevm.expectRevert("deposit paused"); - mockMessenger.callTarget( - address(gateway), - abi.encodeWithSelector( - gateway.finalizeDepositERC20.selector, - address(l1USDC), - address(l2USDC), - sender, - recipient, - amount, - dataToCall - ) - ); - } - - function testFinalizeDepositERC20Failed( - address sender, - address recipient, - uint256 amount, - bytes memory dataToCall - ) public { - // blacklist some addresses - hevm.assume(recipient != address(0)); - hevm.assume(recipient != address(gateway)); - - amount = bound(amount, 1, l2USDC.balanceOf(address(this))); - - // send some USDC to L2ScrollMessenger - gateway.withdrawERC20(address(l2USDC), amount, 21000); - - // do finalize withdraw eth - bytes memory message = abi.encodeWithSelector( - IL2ERC20Gateway.finalizeDepositERC20.selector, - address(l1USDC), - address(l2USDC), - sender, - recipient, - amount, - dataToCall - ); - bytes memory xDomainCalldata = abi.encodeWithSignature( - "relayMessage(address,address,uint256,uint256,bytes)", - address(uint160(address(counterpartGateway)) + 1), - address(gateway), - 0, - 0, - message - ); - - // conterpart is not L1USDCGateway - // emit FailedRelayedMessage from L2ScrollMessenger - hevm.expectEmit(true, false, false, true); - emit FailedRelayedMessage(keccak256(xDomainCalldata)); - - uint256 gatewayBalance = l2USDC.balanceOf(address(gateway)); - uint256 recipientBalance = l2USDC.balanceOf(recipient); - assertBoolEq(false, l2Messenger.isL1MessageExecuted(keccak256(xDomainCalldata))); - hevm.startPrank(AddressAliasHelper.applyL1ToL2Alias(address(l1Messenger))); - l2Messenger.relayMessage(address(uint160(address(counterpartGateway)) + 1), address(gateway), 0, 0, message); - hevm.stopPrank(); - assertEq(gatewayBalance, l2USDC.balanceOf(address(gateway))); - assertEq(recipientBalance, l2USDC.balanceOf(recipient)); - assertBoolEq(false, l2Messenger.isL1MessageExecuted(keccak256(xDomainCalldata))); - } - - function testFinalizeDepositERC20( - address sender, - uint256 amount, - bytes memory dataToCall - ) public { - MockGatewayRecipient recipient = new MockGatewayRecipient(); - - amount = bound(amount, 1, l2USDC.balanceOf(address(this))); - - // send some USDC to L1ScrollMessenger - gateway.withdrawERC20(address(l2USDC), amount, 21000); - - // do finalize withdraw USDC - bytes memory message = abi.encodeWithSelector( - IL2ERC20Gateway.finalizeDepositERC20.selector, - address(l1USDC), - address(l2USDC), - sender, - address(recipient), - amount, - dataToCall - ); - bytes memory xDomainCalldata = abi.encodeWithSignature( - "relayMessage(address,address,uint256,uint256,bytes)", - address(counterpartGateway), - address(gateway), - 0, - 0, - message - ); - - // emit FinalizeDepositERC20 from L2USDCGateway - { - hevm.expectEmit(true, true, true, true); - emit FinalizeDepositERC20(address(l1USDC), address(l2USDC), sender, address(recipient), amount, dataToCall); - } - - // emit RelayedMessage from L2ScrollMessenger - { - hevm.expectEmit(true, false, false, true); - emit RelayedMessage(keccak256(xDomainCalldata)); - } - - uint256 gatewayBalance = l2USDC.balanceOf(address(gateway)); - uint256 recipientBalance = l2USDC.balanceOf(address(recipient)); - assertBoolEq(false, l2Messenger.isL1MessageExecuted(keccak256(xDomainCalldata))); - hevm.startPrank(AddressAliasHelper.applyL1ToL2Alias(address(l1Messenger))); - l2Messenger.relayMessage(address(counterpartGateway), address(gateway), 0, 0, message); - hevm.stopPrank(); - assertEq(gatewayBalance, l2USDC.balanceOf(address(gateway))); - assertEq(recipientBalance + amount, l2USDC.balanceOf(address(recipient))); - assertBoolEq(true, l2Messenger.isL1MessageExecuted(keccak256(xDomainCalldata))); - } - - function _withdrawERC20( - bool useRouter, - uint256 amount, - uint256 gasLimit, - uint256 feePerGas - ) private { - amount = bound(amount, 0, l2USDC.balanceOf(address(this))); - gasLimit = bound(gasLimit, 21000, 1000000); - feePerGas = 0; - - setL1BaseFee(feePerGas); - - uint256 feeToPay = feePerGas * gasLimit; - bytes memory message = abi.encodeWithSelector( - IL1ERC20Gateway.finalizeWithdrawERC20.selector, - address(l1USDC), - address(l2USDC), - address(this), - address(this), - amount, - new bytes(0) - ); - bytes memory xDomainCalldata = abi.encodeWithSignature( - "relayMessage(address,address,uint256,uint256,bytes)", - address(gateway), - address(counterpartGateway), - 0, - 0, - message - ); - - if (amount == 0) { - hevm.expectRevert("withdraw zero amount"); - if (useRouter) { - router.withdrawERC20{value: feeToPay}(address(l2USDC), amount, gasLimit); - } else { - gateway.withdrawERC20{value: feeToPay}(address(l2USDC), amount, gasLimit); - } - } else { - // token is not l2USDC - hevm.expectRevert("only USDC is allowed"); - gateway.withdrawERC20(address(l1USDC), amount, gasLimit); - - // emit AppendMessage from L2MessageQueue - { - hevm.expectEmit(false, false, false, true); - emit AppendMessage(0, keccak256(xDomainCalldata)); - } - - // emit SentMessage from L2ScrollMessenger - { - hevm.expectEmit(true, true, false, true); - emit SentMessage(address(gateway), address(counterpartGateway), 0, 0, gasLimit, message); - } - - // emit WithdrawERC20 from L2USDCGateway - hevm.expectEmit(true, true, true, true); - emit WithdrawERC20(address(l1USDC), address(l2USDC), address(this), address(this), amount, new bytes(0)); - - uint256 senderBalance = l2USDC.balanceOf(address(this)); - uint256 gatewayBalance = l2USDC.balanceOf(address(gateway)); - uint256 feeVaultBalance = address(feeVault).balance; - assertEq(l2Messenger.messageSendTimestamp(keccak256(xDomainCalldata)), 0); - if (useRouter) { - router.withdrawERC20{value: feeToPay}(address(l2USDC), amount, gasLimit); - } else { - gateway.withdrawERC20{value: feeToPay}(address(l2USDC), amount, gasLimit); - } - assertEq(senderBalance - amount, l2USDC.balanceOf(address(this))); - assertEq(gatewayBalance, l2USDC.balanceOf(address(gateway))); - assertEq(feeToPay + feeVaultBalance, address(feeVault).balance); - assertGt(l2Messenger.messageSendTimestamp(keccak256(xDomainCalldata)), 0); - } - } - - function _withdrawERC20WithRecipient( - bool useRouter, - uint256 amount, - address recipient, - uint256 gasLimit, - uint256 feePerGas - ) private { - amount = bound(amount, 0, l2USDC.balanceOf(address(this))); - gasLimit = bound(gasLimit, 21000, 1000000); - feePerGas = 0; - - setL1BaseFee(feePerGas); - - uint256 feeToPay = feePerGas * gasLimit; - bytes memory message = abi.encodeWithSelector( - IL1ERC20Gateway.finalizeWithdrawERC20.selector, - address(l1USDC), - address(l2USDC), - address(this), - recipient, - amount, - new bytes(0) - ); - bytes memory xDomainCalldata = abi.encodeWithSignature( - "relayMessage(address,address,uint256,uint256,bytes)", - address(gateway), - address(counterpartGateway), - 0, - 0, - message - ); - - if (amount == 0) { - hevm.expectRevert("withdraw zero amount"); - if (useRouter) { - router.withdrawERC20{value: feeToPay}(address(l2USDC), recipient, amount, gasLimit); - } else { - gateway.withdrawERC20{value: feeToPay}(address(l2USDC), recipient, amount, gasLimit); - } - } else { - // token is not l1USDC - hevm.expectRevert("only USDC is allowed"); - gateway.withdrawERC20(address(l1USDC), recipient, amount, gasLimit); - - // emit AppendMessage from L2MessageQueue - { - hevm.expectEmit(false, false, false, true); - emit AppendMessage(0, keccak256(xDomainCalldata)); - } - - // emit SentMessage from L2ScrollMessenger - { - hevm.expectEmit(true, true, false, true); - emit SentMessage(address(gateway), address(counterpartGateway), 0, 0, gasLimit, message); - } - - // emit WithdrawERC20 from L2USDCGateway - hevm.expectEmit(true, true, true, true); - emit WithdrawERC20(address(l1USDC), address(l2USDC), address(this), recipient, amount, new bytes(0)); - - uint256 senderBalance = l2USDC.balanceOf(address(this)); - uint256 gatewayBalance = l2USDC.balanceOf(address(gateway)); - uint256 feeVaultBalance = address(feeVault).balance; - assertEq(l2Messenger.messageSendTimestamp(keccak256(xDomainCalldata)), 0); - if (useRouter) { - router.withdrawERC20{value: feeToPay}(address(l2USDC), recipient, amount, gasLimit); - } else { - gateway.withdrawERC20{value: feeToPay}(address(l2USDC), recipient, amount, gasLimit); - } - assertEq(senderBalance - amount, l2USDC.balanceOf(address(this))); - assertEq(gatewayBalance, l2USDC.balanceOf(address(gateway))); - assertEq(feeToPay + feeVaultBalance, address(feeVault).balance); - assertGt(l2Messenger.messageSendTimestamp(keccak256(xDomainCalldata)), 0); - } - } - - function _deployGateway(address messenger) internal returns (L2USDCGateway _gateway) { - _gateway = L2USDCGateway(_deployProxy(address(0))); - - admin.upgrade( - ITransparentUpgradeableProxy(address(_gateway)), - address( - new L2USDCGateway( - address(l1USDC), - address(l2USDC), - address(counterpartGateway), - address(router), - address(messenger) - ) - ) - ); - } -} diff --git a/contracts/src/test/L2WETHGateway.t.sol b/contracts/src/test/L2WETHGateway.t.sol deleted file mode 100644 index 2d36ce5c7..000000000 --- a/contracts/src/test/L2WETHGateway.t.sol +++ /dev/null @@ -1,571 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {WETH} from "solmate/tokens/WETH.sol"; - -import {ITransparentUpgradeableProxy} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; - -import {IL1ERC20Gateway, L1WETHGateway} from "../L1/gateways/L1WETHGateway.sol"; -import {L2GatewayRouter} from "../L2/gateways/L2GatewayRouter.sol"; -import {IL2ERC20Gateway, L2WETHGateway} from "../L2/gateways/L2WETHGateway.sol"; - -import {AddressAliasHelper} from "../libraries/common/AddressAliasHelper.sol"; - -import {L2GatewayTestBase} from "./L2GatewayTestBase.t.sol"; -import {MockScrollMessenger} from "./mocks/MockScrollMessenger.sol"; -import {MockGatewayRecipient} from "./mocks/MockGatewayRecipient.sol"; - -contract L2WETHGatewayTest is L2GatewayTestBase { - // from L2WETHGateway - event WithdrawERC20( - address indexed _l1Token, - address indexed _l2Token, - address indexed _from, - address _to, - uint256 _amount, - bytes _data - ); - event FinalizeDepositERC20( - address indexed _l1Token, - address indexed _l2Token, - address indexed _from, - address _to, - uint256 _amount, - bytes _data - ); - - WETH private l1weth; - WETH private l2weth; - - L2WETHGateway private gateway; - L2GatewayRouter private router; - - L1WETHGateway private counterpartGateway; - - function setUp() public { - setUpBase(); - - // Deploy tokens - l1weth = new WETH(); - l2weth = new WETH(); - - // Deploy L1 contracts - counterpartGateway = new L1WETHGateway(address(l1weth), address(l2weth), address(1), address(1), address(1)); - - // Deploy L2 contracts - router = L2GatewayRouter(_deployProxy(address(new L2GatewayRouter()))); - gateway = _deployGateway(address(l2Messenger)); - - // Initialize L2 contracts - gateway.initialize(address(counterpartGateway), address(router), address(l2Messenger)); - router.initialize(address(0), address(gateway)); - - // Prepare token balances - l2weth.deposit{value: address(this).balance / 2}(); - l2weth.approve(address(gateway), type(uint256).max); - } - - function testInitialized() public { - assertEq(address(counterpartGateway), gateway.counterpart()); - assertEq(address(router), gateway.router()); - assertEq(address(l2Messenger), gateway.messenger()); - assertEq(address(l2weth), gateway.WETH()); - assertEq(address(l1weth), gateway.l1WETH()); - assertEq(address(l1weth), gateway.getL1ERC20Address(address(l2weth))); - assertEq(address(l2weth), gateway.getL2ERC20Address(address(l1weth))); - - hevm.expectRevert("Initializable: contract is already initialized"); - gateway.initialize(address(counterpartGateway), address(router), address(l2Messenger)); - } - - function testDirectTransferETH(uint256 amount) public { - amount = bound(amount, 0, address(this).balance); - // solhint-disable-next-line avoid-low-level-calls - (bool success, bytes memory result) = address(gateway).call{value: amount}(""); - assertBoolEq(success, false); - assertEq(string(result), string(abi.encodeWithSignature("Error(string)", "only WETH"))); - } - - function testWithdrawERC20( - uint256 amount, - uint256 gasLimit, - uint256 feePerGas - ) public { - _withdrawERC20(false, amount, gasLimit, feePerGas); - } - - function testWithdrawERC20WithRecipient( - uint256 amount, - address recipient, - uint256 gasLimit, - uint256 feePerGas - ) public { - _withdrawERC20WithRecipient(false, amount, recipient, gasLimit, feePerGas); - } - - function testWithdrawERC20WithRecipientAndCalldata( - uint256 amount, - address recipient, - bytes memory dataToCall, - uint256 gasLimit, - uint256 feePerGas - ) public { - _withdrawERC20WithRecipientAndCalldata(false, amount, recipient, dataToCall, gasLimit, feePerGas); - } - - function testRouterDepositERC20( - uint256 amount, - uint256 gasLimit, - uint256 feePerGas - ) public { - _withdrawERC20(true, amount, gasLimit, feePerGas); - } - - function testRouterDepositERC20WithRecipient( - uint256 amount, - address recipient, - uint256 gasLimit, - uint256 feePerGas - ) public { - _withdrawERC20WithRecipient(true, amount, recipient, gasLimit, feePerGas); - } - - function testRouterDepositERC20WithRecipientAndCalldata( - uint256 amount, - address recipient, - bytes memory dataToCall, - uint256 gasLimit, - uint256 feePerGas - ) public { - _withdrawERC20WithRecipientAndCalldata(true, amount, recipient, dataToCall, gasLimit, feePerGas); - } - - function testFinalizeDepositERC20FailedMocking( - address sender, - address recipient, - uint256 amount, - bytes memory dataToCall - ) public { - amount = bound(amount, 1, 100000); - - // revert when caller is not messenger - hevm.expectRevert(ErrorCallerIsNotMessenger.selector); - gateway.finalizeDepositERC20(address(l1weth), address(l2weth), sender, recipient, amount, dataToCall); - - MockScrollMessenger mockMessenger = new MockScrollMessenger(); - gateway = _deployGateway(address(mockMessenger)); - gateway.initialize(address(counterpartGateway), address(router), address(mockMessenger)); - - // only call by counterpart - hevm.expectRevert(ErrorCallerIsNotCounterpartGateway.selector); - mockMessenger.callTarget( - address(gateway), - abi.encodeWithSelector( - gateway.finalizeDepositERC20.selector, - address(l1weth), - address(l2weth), - sender, - recipient, - amount, - dataToCall - ) - ); - - mockMessenger.setXDomainMessageSender(address(counterpartGateway)); - - // l1 token not WETH - hevm.expectRevert("l1 token not WETH"); - mockMessenger.callTarget( - address(gateway), - abi.encodeWithSelector( - gateway.finalizeDepositERC20.selector, - address(l2weth), - address(l2weth), - sender, - recipient, - amount, - dataToCall - ) - ); - - // l2 token not WETH - hevm.expectRevert("l2 token not WETH"); - mockMessenger.callTarget( - address(gateway), - abi.encodeWithSelector( - gateway.finalizeDepositERC20.selector, - address(l1weth), - address(l1weth), - sender, - recipient, - amount, - dataToCall - ) - ); - - // msg.value mismatch - hevm.expectRevert("msg.value mismatch"); - mockMessenger.callTarget( - address(gateway), - abi.encodeWithSelector( - gateway.finalizeDepositERC20.selector, - address(l1weth), - address(l2weth), - sender, - recipient, - amount, - dataToCall - ) - ); - } - - function testFinalizeDepositERC20Failed( - address sender, - address recipient, - uint256 amount, - bytes memory dataToCall - ) public { - // blacklist some addresses - hevm.assume(recipient != address(0)); - hevm.assume(recipient != address(gateway)); - - amount = bound(amount, 1, l2weth.balanceOf(address(this))); - - // send some WETH to L2ScrollMessenger - gateway.withdrawERC20(address(l2weth), amount, 21000); - - // do finalize withdraw eth - bytes memory message = abi.encodeWithSelector( - IL2ERC20Gateway.finalizeDepositERC20.selector, - address(l1weth), - address(l2weth), - sender, - recipient, - amount, - dataToCall - ); - bytes memory xDomainCalldata = abi.encodeWithSignature( - "relayMessage(address,address,uint256,uint256,bytes)", - address(uint160(address(counterpartGateway)) + 1), - address(gateway), - amount, - 0, - message - ); - - // counterpart is not L1WETHGateway - // emit FailedRelayedMessage from L2ScrollMessenger - hevm.expectEmit(true, false, false, true); - emit FailedRelayedMessage(keccak256(xDomainCalldata)); - - uint256 messengerBalance = address(l2Messenger).balance; - uint256 recipientBalance = l2weth.balanceOf(recipient); - assertBoolEq(false, l2Messenger.isL1MessageExecuted(keccak256(xDomainCalldata))); - hevm.startPrank(AddressAliasHelper.applyL1ToL2Alias(address(l1Messenger))); - l2Messenger.relayMessage( - address(uint160(address(counterpartGateway)) + 1), - address(gateway), - amount, - 0, - message - ); - hevm.stopPrank(); - assertEq(messengerBalance, address(l2Messenger).balance); - assertEq(recipientBalance, l2weth.balanceOf(recipient)); - assertBoolEq(false, l2Messenger.isL1MessageExecuted(keccak256(xDomainCalldata))); - } - - function testFinalizeDepositERC20( - address sender, - uint256 amount, - bytes memory dataToCall - ) public { - MockGatewayRecipient recipient = new MockGatewayRecipient(); - - amount = bound(amount, 1, l2weth.balanceOf(address(this))); - - // send some WETH to L1ScrollMessenger - gateway.withdrawERC20(address(l2weth), amount, 21000); - - // do finalize withdraw weth - bytes memory message = abi.encodeWithSelector( - IL2ERC20Gateway.finalizeDepositERC20.selector, - address(l1weth), - address(l2weth), - sender, - address(recipient), - amount, - dataToCall - ); - bytes memory xDomainCalldata = abi.encodeWithSignature( - "relayMessage(address,address,uint256,uint256,bytes)", - address(counterpartGateway), - address(gateway), - amount, - 0, - message - ); - - // emit FinalizeDepositERC20 from L2WETHGateway - { - hevm.expectEmit(true, true, true, true); - emit FinalizeDepositERC20(address(l1weth), address(l2weth), sender, address(recipient), amount, dataToCall); - } - - // emit RelayedMessage from L2ScrollMessenger - { - hevm.expectEmit(true, false, false, true); - emit RelayedMessage(keccak256(xDomainCalldata)); - } - - uint256 messengerBalance = address(l2Messenger).balance; - uint256 recipientBalance = l2weth.balanceOf(address(recipient)); - assertBoolEq(false, l2Messenger.isL1MessageExecuted(keccak256(xDomainCalldata))); - hevm.startPrank(AddressAliasHelper.applyL1ToL2Alias(address(l1Messenger))); - l2Messenger.relayMessage(address(counterpartGateway), address(gateway), amount, 0, message); - hevm.stopPrank(); - assertEq(messengerBalance - amount, address(l2Messenger).balance); - assertEq(recipientBalance + amount, l2weth.balanceOf(address(recipient))); - assertBoolEq(true, l2Messenger.isL1MessageExecuted(keccak256(xDomainCalldata))); - } - - function _withdrawERC20( - bool useRouter, - uint256 amount, - uint256 gasLimit, - uint256 feePerGas - ) private { - amount = bound(amount, 0, l2weth.balanceOf(address(this))); - gasLimit = bound(gasLimit, 21000, 1000000); - feePerGas = 0; - - setL1BaseFee(feePerGas); - - uint256 feeToPay = feePerGas * gasLimit; - bytes memory message = abi.encodeWithSelector( - IL1ERC20Gateway.finalizeWithdrawERC20.selector, - address(l1weth), - address(l2weth), - address(this), - address(this), - amount, - new bytes(0) - ); - bytes memory xDomainCalldata = abi.encodeWithSignature( - "relayMessage(address,address,uint256,uint256,bytes)", - address(gateway), - address(counterpartGateway), - amount, - 0, - message - ); - - if (amount == 0) { - hevm.expectRevert("withdraw zero amount"); - if (useRouter) { - router.withdrawERC20{value: feeToPay}(address(l2weth), amount, gasLimit); - } else { - gateway.withdrawERC20{value: feeToPay}(address(l2weth), amount, gasLimit); - } - } else { - // token is not l2WETH - hevm.expectRevert("only WETH is allowed"); - gateway.withdrawERC20(address(l1weth), amount, gasLimit); - - // emit AppendMessage from L2MessageQueue - { - hevm.expectEmit(false, false, false, true); - emit AppendMessage(0, keccak256(xDomainCalldata)); - } - - // emit SentMessage from L2ScrollMessenger - { - hevm.expectEmit(true, true, false, true); - emit SentMessage(address(gateway), address(counterpartGateway), amount, 0, gasLimit, message); - } - - // emit WithdrawERC20 from L2WETHGateway - hevm.expectEmit(true, true, true, true); - emit WithdrawERC20(address(l1weth), address(l2weth), address(this), address(this), amount, new bytes(0)); - - uint256 messengerBalance = address(l2Messenger).balance; - uint256 feeVaultBalance = address(feeVault).balance; - assertEq(l2Messenger.messageSendTimestamp(keccak256(xDomainCalldata)), 0); - if (useRouter) { - router.withdrawERC20{value: feeToPay}(address(l2weth), amount, gasLimit); - } else { - gateway.withdrawERC20{value: feeToPay}(address(l2weth), amount, gasLimit); - } - assertEq(amount + messengerBalance, address(l2Messenger).balance); - assertEq(feeToPay + feeVaultBalance, address(feeVault).balance); - assertGt(l2Messenger.messageSendTimestamp(keccak256(xDomainCalldata)), 0); - } - } - - function _withdrawERC20WithRecipient( - bool useRouter, - uint256 amount, - address recipient, - uint256 gasLimit, - uint256 feePerGas - ) private { - amount = bound(amount, 0, l2weth.balanceOf(address(this))); - gasLimit = bound(gasLimit, 21000, 1000000); - feePerGas = 0; - - setL1BaseFee(feePerGas); - - uint256 feeToPay = feePerGas * gasLimit; - bytes memory message = abi.encodeWithSelector( - IL1ERC20Gateway.finalizeWithdrawERC20.selector, - address(l1weth), - address(l2weth), - address(this), - recipient, - amount, - new bytes(0) - ); - bytes memory xDomainCalldata = abi.encodeWithSignature( - "relayMessage(address,address,uint256,uint256,bytes)", - address(gateway), - address(counterpartGateway), - amount, - 0, - message - ); - - if (amount == 0) { - hevm.expectRevert("withdraw zero amount"); - if (useRouter) { - router.withdrawERC20{value: feeToPay}(address(l2weth), recipient, amount, gasLimit); - } else { - gateway.withdrawERC20{value: feeToPay}(address(l2weth), recipient, amount, gasLimit); - } - } else { - // token is not l1WETH - hevm.expectRevert("only WETH is allowed"); - gateway.withdrawERC20(address(l1weth), recipient, amount, gasLimit); - - // emit AppendMessage from L2MessageQueue - { - hevm.expectEmit(false, false, false, true); - emit AppendMessage(0, keccak256(xDomainCalldata)); - } - - // emit SentMessage from L2ScrollMessenger - { - hevm.expectEmit(true, true, false, true); - emit SentMessage(address(gateway), address(counterpartGateway), amount, 0, gasLimit, message); - } - - // emit WithdrawERC20 from L2WETHGateway - hevm.expectEmit(true, true, true, true); - emit WithdrawERC20(address(l1weth), address(l2weth), address(this), recipient, amount, new bytes(0)); - - uint256 messengerBalance = address(l2Messenger).balance; - uint256 feeVaultBalance = address(feeVault).balance; - assertEq(l2Messenger.messageSendTimestamp(keccak256(xDomainCalldata)), 0); - if (useRouter) { - router.withdrawERC20{value: feeToPay}(address(l2weth), recipient, amount, gasLimit); - } else { - gateway.withdrawERC20{value: feeToPay}(address(l2weth), recipient, amount, gasLimit); - } - assertEq(amount + messengerBalance, address(l2Messenger).balance); - assertEq(feeToPay + feeVaultBalance, address(feeVault).balance); - assertGt(l2Messenger.messageSendTimestamp(keccak256(xDomainCalldata)), 0); - } - } - - function _withdrawERC20WithRecipientAndCalldata( - bool useRouter, - uint256 amount, - address recipient, - bytes memory dataToCall, - uint256 gasLimit, - uint256 feePerGas - ) private { - amount = bound(amount, 0, l2weth.balanceOf(address(this))); - gasLimit = bound(gasLimit, 21000, 1000000); - feePerGas = 0; - - setL1BaseFee(feePerGas); - - uint256 feeToPay = feePerGas * gasLimit; - bytes memory message = abi.encodeWithSelector( - IL1ERC20Gateway.finalizeWithdrawERC20.selector, - address(l1weth), - address(l2weth), - address(this), - recipient, - amount, - dataToCall - ); - bytes memory xDomainCalldata = abi.encodeWithSignature( - "relayMessage(address,address,uint256,uint256,bytes)", - address(gateway), - address(counterpartGateway), - amount, - 0, - message - ); - - if (amount == 0) { - hevm.expectRevert("withdraw zero amount"); - if (useRouter) { - router.withdrawERC20AndCall{value: feeToPay}(address(l2weth), recipient, amount, dataToCall, gasLimit); - } else { - gateway.withdrawERC20AndCall{value: feeToPay}(address(l2weth), recipient, amount, dataToCall, gasLimit); - } - } else { - // token is not l1WETH - hevm.expectRevert("only WETH is allowed"); - gateway.withdrawERC20AndCall(address(l1weth), recipient, amount, dataToCall, gasLimit); - - // emit AppendMessage from L2MessageQueue - { - hevm.expectEmit(false, false, false, true); - emit AppendMessage(0, keccak256(xDomainCalldata)); - } - - // emit SentMessage from L2ScrollMessenger - { - hevm.expectEmit(true, true, false, true); - emit SentMessage(address(gateway), address(counterpartGateway), amount, 0, gasLimit, message); - } - - // emit WithdrawERC20 from L2WETHGateway - hevm.expectEmit(true, true, true, true); - emit WithdrawERC20(address(l1weth), address(l2weth), address(this), recipient, amount, dataToCall); - - uint256 messengerBalance = address(l2Messenger).balance; - uint256 feeVaultBalance = address(feeVault).balance; - assertEq(l2Messenger.messageSendTimestamp(keccak256(xDomainCalldata)), 0); - if (useRouter) { - router.withdrawERC20AndCall{value: feeToPay}(address(l2weth), recipient, amount, dataToCall, gasLimit); - } else { - gateway.withdrawERC20AndCall{value: feeToPay}(address(l2weth), recipient, amount, dataToCall, gasLimit); - } - assertEq(amount + messengerBalance, address(l2Messenger).balance); - assertEq(feeToPay + feeVaultBalance, address(feeVault).balance); - assertGt(l2Messenger.messageSendTimestamp(keccak256(xDomainCalldata)), 0); - } - } - - function _deployGateway(address messenger) internal returns (L2WETHGateway _gateway) { - _gateway = L2WETHGateway(payable(_deployProxy(address(0)))); - - admin.upgrade( - ITransparentUpgradeableProxy(address(_gateway)), - address( - new L2WETHGateway( - address(l2weth), - address(l1weth), - address(counterpartGateway), - address(router), - address(messenger) - ) - ) - ); - } -} diff --git a/contracts/src/test/MultipleVersionRollupVerifier.t.sol b/contracts/src/test/MultipleVersionRollupVerifier.t.sol deleted file mode 100644 index 878c3e5ca..000000000 --- a/contracts/src/test/MultipleVersionRollupVerifier.t.sol +++ /dev/null @@ -1,199 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {DSTestPlus} from "solmate/test/utils/DSTestPlus.sol"; - -import {L1MessageQueue} from "../L1/rollup/L1MessageQueue.sol"; -import {MultipleVersionRollupVerifier} from "../L1/rollup/MultipleVersionRollupVerifier.sol"; - -import {MockScrollChain} from "./mocks/MockScrollChain.sol"; -import {MockZkEvmVerifier} from "./mocks/MockZkEvmVerifier.sol"; - -contract MultipleVersionRollupVerifierTest is DSTestPlus { - // from MultipleVersionRollupVerifier - event UpdateVerifier(uint256 startBatchIndex, address verifier); - - MultipleVersionRollupVerifier private verifier; - MockZkEvmVerifier private v0; - MockZkEvmVerifier private v1; - MockZkEvmVerifier private v2; - - function setUp() external { - v0 = new MockZkEvmVerifier(); - v1 = new MockZkEvmVerifier(); - v2 = new MockZkEvmVerifier(); - - uint256[] memory _versions = new uint256[](1); - address[] memory _verifiers = new address[](1); - _versions[0] = 0; - _verifiers[0] = address(v0); - verifier = new MultipleVersionRollupVerifier(_versions, _verifiers); - } - - function testUpdateVerifierVersion0(address _newVerifier) external { - hevm.assume(_newVerifier != address(0)); - - // set by non-owner, should revert - hevm.startPrank(address(1)); - hevm.expectRevert("Ownable: caller is not the owner"); - verifier.updateVerifier(0, 0, address(0)); - hevm.stopPrank(); - - // zero verifier address, revert - hevm.expectRevert(MultipleVersionRollupVerifier.ErrorZeroAddress.selector); - verifier.updateVerifier(0, 1, address(0)); - - // change to random operator - assertEq(verifier.legacyVerifiersLength(0), 0); - verifier.updateVerifier(0, uint64(100), _newVerifier); - assertEq(verifier.legacyVerifiersLength(0), 1); - (uint64 _startBatchIndex, address _verifier) = verifier.latestVerifier(0); - assertEq(_startBatchIndex, uint64(100)); - assertEq(_verifier, _newVerifier); - (_startBatchIndex, _verifier) = verifier.legacyVerifiers(0, 0); - assertEq(_startBatchIndex, uint64(0)); - assertEq(_verifier, address(v0)); - - // change to same batch index - verifier.updateVerifier(0, uint64(100), address(v1)); - (_startBatchIndex, _verifier) = verifier.latestVerifier(0); - assertEq(_startBatchIndex, uint64(100)); - assertEq(_verifier, address(v1)); - (_startBatchIndex, _verifier) = verifier.legacyVerifiers(0, 0); - assertEq(_startBatchIndex, uint64(0)); - assertEq(_verifier, address(v0)); - - // start batch index too small, revert - hevm.expectRevert(MultipleVersionRollupVerifier.ErrorStartBatchIndexTooSmall.selector); - verifier.updateVerifier(0, 99, _newVerifier); - } - - function testUpdateVerifierVersion(uint256 version, address _newVerifier) external { - hevm.assume(version != 0); - hevm.assume(_newVerifier != address(0)); - - // set v0 - assertEq(verifier.legacyVerifiersLength(version), 0); - verifier.updateVerifier(version, 1, address(v0)); - assertEq(verifier.legacyVerifiersLength(version), 0); - (uint64 _startBatchIndex, address _verifier) = verifier.latestVerifier(version); - assertEq(_startBatchIndex, 1); - assertEq(_verifier, address(v0)); - - // set by non-owner, should revert - hevm.startPrank(address(1)); - hevm.expectRevert("Ownable: caller is not the owner"); - verifier.updateVerifier(version, 0, address(0)); - hevm.stopPrank(); - - // zero verifier address, revert - hevm.expectRevert(MultipleVersionRollupVerifier.ErrorZeroAddress.selector); - verifier.updateVerifier(version, 1, address(0)); - - // change to random operator - assertEq(verifier.legacyVerifiersLength(version), 0); - verifier.updateVerifier(version, uint64(100), _newVerifier); - assertEq(verifier.legacyVerifiersLength(version), 1); - (_startBatchIndex, _verifier) = verifier.latestVerifier(version); - assertEq(_startBatchIndex, uint64(100)); - assertEq(_verifier, _newVerifier); - (_startBatchIndex, _verifier) = verifier.legacyVerifiers(version, 0); - assertEq(_startBatchIndex, uint64(1)); - assertEq(_verifier, address(v0)); - - // change to same batch index - verifier.updateVerifier(version, uint64(100), address(v1)); - (_startBatchIndex, _verifier) = verifier.latestVerifier(version); - assertEq(_startBatchIndex, uint64(100)); - assertEq(_verifier, address(v1)); - (_startBatchIndex, _verifier) = verifier.legacyVerifiers(version, 0); - assertEq(_startBatchIndex, uint64(1)); - assertEq(_verifier, address(v0)); - - // start batch index too small, revert - hevm.expectRevert(MultipleVersionRollupVerifier.ErrorStartBatchIndexTooSmall.selector); - verifier.updateVerifier(version, 99, _newVerifier); - } - - function testGetVerifierV0() external { - verifier.updateVerifier(0, 100, address(v1)); - verifier.updateVerifier(0, 300, address(v2)); - - assertEq(verifier.getVerifier(0, 0), address(v0)); - assertEq(verifier.getVerifier(0, 1), address(v0)); - assertEq(verifier.getVerifier(0, 99), address(v0)); - assertEq(verifier.getVerifier(0, 100), address(v1)); - assertEq(verifier.getVerifier(0, 101), address(v1)); - assertEq(verifier.getVerifier(0, 299), address(v1)); - assertEq(verifier.getVerifier(0, 300), address(v2)); - assertEq(verifier.getVerifier(0, 301), address(v2)); - assertEq(verifier.getVerifier(0, 10000), address(v2)); - } - - function testGetVerifier(uint256 version) external { - hevm.assume(version != 0); - - verifier.updateVerifier(version, 1, address(v0)); - verifier.updateVerifier(version, 100, address(v1)); - verifier.updateVerifier(version, 300, address(v2)); - - assertEq(verifier.getVerifier(version, 1), address(v0)); - assertEq(verifier.getVerifier(version, 99), address(v0)); - assertEq(verifier.getVerifier(version, 100), address(v1)); - assertEq(verifier.getVerifier(version, 101), address(v1)); - assertEq(verifier.getVerifier(version, 299), address(v1)); - assertEq(verifier.getVerifier(version, 300), address(v2)); - assertEq(verifier.getVerifier(version, 301), address(v2)); - assertEq(verifier.getVerifier(version, 10000), address(v2)); - } - - function testVerifyAggregateProofV0() external { - verifier.updateVerifier(0, 100, address(v1)); - verifier.updateVerifier(0, 300, address(v2)); - - hevm.expectRevert(abi.encode(address(v0))); - verifier.verifyAggregateProof(0, new bytes(0), bytes32(0)); - hevm.expectRevert(abi.encode(address(v0))); - verifier.verifyAggregateProof(1, new bytes(0), bytes32(0)); - hevm.expectRevert(abi.encode(address(v0))); - verifier.verifyAggregateProof(99, new bytes(0), bytes32(0)); - hevm.expectRevert(abi.encode(address(v1))); - verifier.verifyAggregateProof(100, new bytes(0), bytes32(0)); - hevm.expectRevert(abi.encode(address(v1))); - verifier.verifyAggregateProof(101, new bytes(0), bytes32(0)); - hevm.expectRevert(abi.encode(address(v1))); - verifier.verifyAggregateProof(299, new bytes(0), bytes32(0)); - hevm.expectRevert(abi.encode(address(v2))); - verifier.verifyAggregateProof(300, new bytes(0), bytes32(0)); - hevm.expectRevert(abi.encode(address(v2))); - verifier.verifyAggregateProof(301, new bytes(0), bytes32(0)); - hevm.expectRevert(abi.encode(address(v2))); - verifier.verifyAggregateProof(10000, new bytes(0), bytes32(0)); - } - - function testVerifyAggregateProof(uint256 version) external { - hevm.assume(version != 0); - - verifier.updateVerifier(version, 1, address(v0)); - verifier.updateVerifier(version, 100, address(v1)); - verifier.updateVerifier(version, 300, address(v2)); - - hevm.expectRevert(abi.encode(address(v0))); - verifier.verifyAggregateProof(version, 1, new bytes(0), bytes32(0)); - hevm.expectRevert(abi.encode(address(v0))); - verifier.verifyAggregateProof(version, 99, new bytes(0), bytes32(0)); - hevm.expectRevert(abi.encode(address(v1))); - verifier.verifyAggregateProof(version, 100, new bytes(0), bytes32(0)); - hevm.expectRevert(abi.encode(address(v1))); - verifier.verifyAggregateProof(version, 101, new bytes(0), bytes32(0)); - hevm.expectRevert(abi.encode(address(v1))); - verifier.verifyAggregateProof(version, 299, new bytes(0), bytes32(0)); - hevm.expectRevert(abi.encode(address(v2))); - verifier.verifyAggregateProof(version, 300, new bytes(0), bytes32(0)); - hevm.expectRevert(abi.encode(address(v2))); - verifier.verifyAggregateProof(version, 301, new bytes(0), bytes32(0)); - hevm.expectRevert(abi.encode(address(v2))); - verifier.verifyAggregateProof(version, 10000, new bytes(0), bytes32(0)); - } -} diff --git a/contracts/src/test/ScrollChain.t.sol b/contracts/src/test/ScrollChain.t.sol deleted file mode 100644 index 35ad4a433..000000000 --- a/contracts/src/test/ScrollChain.t.sol +++ /dev/null @@ -1,789 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {DSTestPlus} from "solmate/test/utils/DSTestPlus.sol"; - -import {ProxyAdmin} from "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol"; -import {ITransparentUpgradeableProxy, TransparentUpgradeableProxy} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; - -import {L1MessageQueue} from "../L1/rollup/L1MessageQueue.sol"; -import {ScrollChain, IScrollChain} from "../L1/rollup/ScrollChain.sol"; -import {BatchHeaderV0Codec} from "../libraries/codec/BatchHeaderV0Codec.sol"; -import {ChunkCodecV0} from "../libraries/codec/ChunkCodecV0.sol"; -import {EmptyContract} from "../misc/EmptyContract.sol"; - -import {MockRollupVerifier} from "./mocks/MockRollupVerifier.sol"; - -// solhint-disable no-inline-assembly - -contract ScrollChainTest is DSTestPlus { - // from ScrollChain - event UpdateSequencer(address indexed account, bool status); - event UpdateProver(address indexed account, bool status); - event UpdateMaxNumTxInChunk(uint256 oldMaxNumTxInChunk, uint256 newMaxNumTxInChunk); - - event CommitBatch(uint256 indexed batchIndex, bytes32 indexed batchHash); - event FinalizeBatch(uint256 indexed batchIndex, bytes32 indexed batchHash, bytes32 stateRoot, bytes32 withdrawRoot); - event RevertBatch(uint256 indexed batchIndex, bytes32 indexed batchHash); - - ProxyAdmin internal admin; - EmptyContract private placeholder; - - ScrollChain private rollup; - L1MessageQueue internal messageQueue; - MockRollupVerifier internal verifier; - - function setUp() public { - placeholder = new EmptyContract(); - admin = new ProxyAdmin(); - messageQueue = L1MessageQueue(_deployProxy(address(0))); - rollup = ScrollChain(_deployProxy(address(0))); - verifier = new MockRollupVerifier(); - - // Upgrade the L1MessageQueue implementation and initialize - admin.upgrade( - ITransparentUpgradeableProxy(address(messageQueue)), - address(new L1MessageQueue(address(this), address(rollup), address(1))) - ); - messageQueue.initialize(address(this), address(rollup), address(0), address(0), 10000000); - // Upgrade the ScrollChain implementation and initialize - admin.upgrade( - ITransparentUpgradeableProxy(address(rollup)), - address(new ScrollChain(233, address(messageQueue), address(verifier))) - ); - rollup.initialize(address(messageQueue), address(verifier), 100); - } - - function testInitialized() external { - assertEq(address(this), rollup.owner()); - assertEq(rollup.layer2ChainId(), 233); - - hevm.expectRevert("Initializable: contract is already initialized"); - rollup.initialize(address(messageQueue), address(0), 100); - } - - function testCommitBatchV0() external { - bytes memory batchHeader0 = new bytes(89); - - // import 10 L1 messages - for (uint256 i = 0; i < 10; i++) { - messageQueue.appendCrossDomainMessage(address(this), 1000000, new bytes(0)); - } - - // import genesis batch first - assembly { - mstore(add(batchHeader0, add(0x20, 25)), 1) - } - rollup.importGenesisBatch(batchHeader0, bytes32(uint256(1))); - - // caller not sequencer, revert - hevm.expectRevert(ScrollChain.ErrorCallerIsNotSequencer.selector); - rollup.commitBatch(0, batchHeader0, new bytes[](0), new bytes(0)); - - rollup.addSequencer(address(0)); - - // batch is empty, revert - hevm.startPrank(address(0)); - hevm.expectRevert(ScrollChain.ErrorBatchIsEmpty.selector); - rollup.commitBatch(0, batchHeader0, new bytes[](0), new bytes(0)); - hevm.stopPrank(); - - // batch header length too small, revert - hevm.startPrank(address(0)); - hevm.expectRevert(BatchHeaderV0Codec.ErrorBatchHeaderLengthTooSmall.selector); - rollup.commitBatch(0, new bytes(88), new bytes[](1), new bytes(0)); - hevm.stopPrank(); - - // wrong bitmap length, revert - hevm.startPrank(address(0)); - hevm.expectRevert(BatchHeaderV0Codec.ErrorIncorrectBitmapLength.selector); - rollup.commitBatch(0, new bytes(90), new bytes[](1), new bytes(0)); - hevm.stopPrank(); - - // incorrect parent batch hash, revert - assembly { - mstore(add(batchHeader0, add(0x20, 25)), 2) // change data hash for batch0 - } - hevm.startPrank(address(0)); - hevm.expectRevert(ScrollChain.ErrorIncorrectBatchHash.selector); - rollup.commitBatch(0, batchHeader0, new bytes[](1), new bytes(0)); - hevm.stopPrank(); - assembly { - mstore(add(batchHeader0, add(0x20, 25)), 1) // change back - } - - bytes[] memory chunks = new bytes[](1); - bytes memory chunk0; - - // no block in chunk, revert - chunk0 = new bytes(1); - chunks[0] = chunk0; - hevm.startPrank(address(0)); - hevm.expectRevert(ChunkCodecV0.ErrorNoBlockInChunk.selector); - rollup.commitBatch(0, batchHeader0, chunks, new bytes(0)); - hevm.stopPrank(); - - // invalid chunk length, revert - chunk0 = new bytes(1); - chunk0[0] = bytes1(uint8(1)); // one block in this chunk - chunks[0] = chunk0; - hevm.startPrank(address(0)); - hevm.expectRevert(ChunkCodecV0.ErrorIncorrectChunkLength.selector); - rollup.commitBatch(0, batchHeader0, chunks, new bytes(0)); - hevm.stopPrank(); - - // cannot skip last L1 message, revert - chunk0 = new bytes(1 + 60); - bytes memory bitmap = new bytes(32); - chunk0[0] = bytes1(uint8(1)); // one block in this chunk - chunk0[58] = bytes1(uint8(1)); // numTransactions = 1 - chunk0[60] = bytes1(uint8(1)); // numL1Messages = 1 - bitmap[31] = bytes1(uint8(1)); - chunks[0] = chunk0; - hevm.startPrank(address(0)); - hevm.expectRevert(ScrollChain.ErrorLastL1MessageSkipped.selector); - rollup.commitBatch(0, batchHeader0, chunks, bitmap); - hevm.stopPrank(); - - // num txs less than num L1 msgs, revert - chunk0 = new bytes(1 + 60); - bitmap = new bytes(32); - chunk0[0] = bytes1(uint8(1)); // one block in this chunk - chunk0[58] = bytes1(uint8(1)); // numTransactions = 1 - chunk0[60] = bytes1(uint8(3)); // numL1Messages = 3 - bitmap[31] = bytes1(uint8(3)); - chunks[0] = chunk0; - hevm.startPrank(address(0)); - hevm.expectRevert(ScrollChain.ErrorNumTxsLessThanNumL1Msgs.selector); - rollup.commitBatch(0, batchHeader0, chunks, bitmap); - hevm.stopPrank(); - - // incomplete l2 transaction data, revert - chunk0 = new bytes(1 + 60 + 1); - chunk0[0] = bytes1(uint8(1)); // one block in this chunk - chunks[0] = chunk0; - hevm.startPrank(address(0)); - hevm.expectRevert(ScrollChain.ErrorIncompleteL2TransactionData.selector); - rollup.commitBatch(0, batchHeader0, chunks, new bytes(0)); - hevm.stopPrank(); - - // commit batch with one chunk, no tx, correctly - chunk0 = new bytes(1 + 60); - chunk0[0] = bytes1(uint8(1)); // one block in this chunk - chunks[0] = chunk0; - hevm.startPrank(address(0)); - rollup.commitBatch(0, batchHeader0, chunks, new bytes(0)); - hevm.stopPrank(); - assertGt(uint256(rollup.committedBatches(1)), 0); - - // batch is already committed, revert - hevm.startPrank(address(0)); - hevm.expectRevert(ScrollChain.ErrorBatchIsAlreadyCommitted.selector); - rollup.commitBatch(0, batchHeader0, chunks, new bytes(0)); - hevm.stopPrank(); - } - - function testFinalizeBatchWithProofV0() external { - // caller not prover, revert - hevm.expectRevert(ScrollChain.ErrorCallerIsNotProver.selector); - rollup.finalizeBatchWithProof(new bytes(0), bytes32(0), bytes32(0), bytes32(0), new bytes(0)); - - rollup.addProver(address(0)); - rollup.addSequencer(address(0)); - - bytes memory batchHeader0 = new bytes(89); - - // import genesis batch - assembly { - mstore(add(batchHeader0, add(0x20, 25)), 1) - } - rollup.importGenesisBatch(batchHeader0, bytes32(uint256(1))); - bytes32 batchHash0 = rollup.committedBatches(0); - - bytes[] memory chunks = new bytes[](1); - bytes memory chunk0; - - // commit one batch - chunk0 = new bytes(1 + 60); - chunk0[0] = bytes1(uint8(1)); // one block in this chunk - chunks[0] = chunk0; - hevm.startPrank(address(0)); - rollup.commitBatch(0, batchHeader0, chunks, new bytes(0)); - hevm.stopPrank(); - assertGt(uint256(rollup.committedBatches(1)), 0); - - bytes memory batchHeader1 = new bytes(89); - assembly { - mstore(add(batchHeader1, 0x20), 0) // version - mstore(add(batchHeader1, add(0x20, 1)), shl(192, 1)) // batchIndex - mstore(add(batchHeader1, add(0x20, 9)), 0) // l1MessagePopped - mstore(add(batchHeader1, add(0x20, 17)), 0) // totalL1MessagePopped - mstore(add(batchHeader1, add(0x20, 25)), 0x246394445f4fe64ed5598554d55d1682d6fb3fe04bf58eb54ef81d1189fafb51) // dataHash - mstore(add(batchHeader1, add(0x20, 57)), batchHash0) // parentBatchHash - } - - // incorrect batch hash, revert - batchHeader1[1] = bytes1(uint8(1)); // change random byte - hevm.startPrank(address(0)); - hevm.expectRevert(ScrollChain.ErrorIncorrectBatchHash.selector); - rollup.finalizeBatchWithProof(batchHeader1, bytes32(uint256(1)), bytes32(uint256(2)), bytes32(0), new bytes(0)); - hevm.stopPrank(); - batchHeader1[1] = bytes1(uint8(0)); // change back - - // batch header length too small, revert - hevm.startPrank(address(0)); - hevm.expectRevert(BatchHeaderV0Codec.ErrorBatchHeaderLengthTooSmall.selector); - rollup.finalizeBatchWithProof( - new bytes(88), - bytes32(uint256(1)), - bytes32(uint256(2)), - bytes32(0), - new bytes(0) - ); - hevm.stopPrank(); - - // wrong bitmap length, revert - hevm.startPrank(address(0)); - hevm.expectRevert(BatchHeaderV0Codec.ErrorIncorrectBitmapLength.selector); - rollup.finalizeBatchWithProof( - new bytes(90), - bytes32(uint256(1)), - bytes32(uint256(2)), - bytes32(0), - new bytes(0) - ); - hevm.stopPrank(); - - // incorrect previous state root, revert - hevm.startPrank(address(0)); - hevm.expectRevert(ScrollChain.ErrorIncorrectPreviousStateRoot.selector); - rollup.finalizeBatchWithProof(batchHeader1, bytes32(uint256(2)), bytes32(uint256(2)), bytes32(0), new bytes(0)); - hevm.stopPrank(); - - // verify success - assertBoolEq(rollup.isBatchFinalized(1), false); - hevm.startPrank(address(0)); - rollup.finalizeBatchWithProof( - batchHeader1, - bytes32(uint256(1)), - bytes32(uint256(2)), - bytes32(uint256(3)), - new bytes(0) - ); - hevm.stopPrank(); - assertBoolEq(rollup.isBatchFinalized(1), true); - assertEq(rollup.finalizedStateRoots(1), bytes32(uint256(2))); - assertEq(rollup.withdrawRoots(1), bytes32(uint256(3))); - assertEq(rollup.lastFinalizedBatchIndex(), 1); - - // batch already verified, revert - hevm.startPrank(address(0)); - hevm.expectRevert(ScrollChain.ErrorBatchIsAlreadyVerified.selector); - rollup.finalizeBatchWithProof( - batchHeader1, - bytes32(uint256(1)), - bytes32(uint256(2)), - bytes32(uint256(3)), - new bytes(0) - ); - hevm.stopPrank(); - } - - function testCommitAndFinalizeWithL1MessagesV0() external { - rollup.addSequencer(address(0)); - rollup.addProver(address(0)); - - // import 300 L1 messages - for (uint256 i = 0; i < 300; i++) { - messageQueue.appendCrossDomainMessage(address(this), 1000000, new bytes(0)); - } - - // import genesis batch first - bytes memory batchHeader0 = new bytes(89); - assembly { - mstore(add(batchHeader0, add(0x20, 25)), 1) - } - rollup.importGenesisBatch(batchHeader0, bytes32(uint256(1))); - bytes32 batchHash0 = rollup.committedBatches(0); - - bytes memory bitmap; - bytes[] memory chunks; - bytes memory chunk0; - bytes memory chunk1; - - // commit batch1, one chunk with one block, 1 tx, 1 L1 message, no skip - // => payload for data hash of chunk0 - // 0000000000000000 - // 0000000000000000 - // 0000000000000000000000000000000000000000000000000000000000000000 - // 0000000000000000 - // 0001 - // a2277fd30bbbe74323309023b56035b376d7768ad237ae4fc46ead7dc9591ae1 - // => data hash for chunk0 - // 9ef1e5694bdb014a1eea42be756a8f63bfd8781d6332e9ef3b5126d90c62f110 - // => data hash for all chunks - // d9cb6bf9264006fcea490d5c261f7453ab95b1b26033a3805996791b8e3a62f3 - // => payload for batch header - // 00 - // 0000000000000001 - // 0000000000000001 - // 0000000000000001 - // d9cb6bf9264006fcea490d5c261f7453ab95b1b26033a3805996791b8e3a62f3 - // 119b828c2a2798d2c957228ebeaff7e10bb099ae0d4e224f3eeb779ff61cba61 - // 0000000000000000000000000000000000000000000000000000000000000000 - // => hash for batch header - // 00847173b29b238cf319cde79512b7c213e5a8b4138daa7051914c4592b6dfc7 - bytes memory batchHeader1 = new bytes(89 + 32); - assembly { - mstore(add(batchHeader1, 0x20), 0) // version - mstore(add(batchHeader1, add(0x20, 1)), shl(192, 1)) // batchIndex = 1 - mstore(add(batchHeader1, add(0x20, 9)), shl(192, 1)) // l1MessagePopped = 1 - mstore(add(batchHeader1, add(0x20, 17)), shl(192, 1)) // totalL1MessagePopped = 1 - mstore(add(batchHeader1, add(0x20, 25)), 0xd9cb6bf9264006fcea490d5c261f7453ab95b1b26033a3805996791b8e3a62f3) // dataHash - mstore(add(batchHeader1, add(0x20, 57)), batchHash0) // parentBatchHash - mstore(add(batchHeader1, add(0x20, 89)), 0) // bitmap0 - } - chunk0 = new bytes(1 + 60); - assembly { - mstore(add(chunk0, 0x20), shl(248, 1)) // numBlocks = 1 - mstore(add(chunk0, add(0x21, 56)), shl(240, 1)) // numTransactions = 1 - mstore(add(chunk0, add(0x21, 58)), shl(240, 1)) // numL1Messages = 1 - } - chunks = new bytes[](1); - chunks[0] = chunk0; - bitmap = new bytes(32); - hevm.startPrank(address(0)); - hevm.expectEmit(true, true, false, true); - emit CommitBatch(1, bytes32(0x00847173b29b238cf319cde79512b7c213e5a8b4138daa7051914c4592b6dfc7)); - rollup.commitBatch(0, batchHeader0, chunks, bitmap); - hevm.stopPrank(); - assertBoolEq(rollup.isBatchFinalized(1), false); - bytes32 batchHash1 = rollup.committedBatches(1); - assertEq(batchHash1, bytes32(0x00847173b29b238cf319cde79512b7c213e5a8b4138daa7051914c4592b6dfc7)); - - // finalize batch1 - hevm.startPrank(address(0)); - hevm.expectEmit(true, true, false, true); - emit FinalizeBatch(1, batchHash1, bytes32(uint256(2)), bytes32(uint256(3))); - rollup.finalizeBatchWithProof( - batchHeader1, - bytes32(uint256(1)), - bytes32(uint256(2)), - bytes32(uint256(3)), - new bytes(0) - ); - hevm.stopPrank(); - assertBoolEq(rollup.isBatchFinalized(1), true); - assertEq(rollup.finalizedStateRoots(1), bytes32(uint256(2))); - assertEq(rollup.withdrawRoots(1), bytes32(uint256(3))); - assertEq(rollup.lastFinalizedBatchIndex(), 1); - assertBoolEq(messageQueue.isMessageSkipped(0), false); - assertEq(messageQueue.pendingQueueIndex(), 1); - - // commit batch2 with two chunks, correctly - // 1. chunk0 has one block, 3 tx, no L1 messages - // => payload for chunk0 - // 0000000000000000 - // 0000000000000000 - // 0000000000000000000000000000000000000000000000000000000000000000 - // 0000000000000000 - // 0003 - // ... (some tx hashes) - // => data hash for chunk0 - // 2ac1dad3f3696e5581dfc10f2c7a7a8fc5b344285f7d332c7895a8825fca609a - // 2. chunk1 has three blocks - // 2.1 block0 has 5 tx, 3 L1 messages, no skips - // 2.2 block1 has 10 tx, 5 L1 messages, even is skipped, last is not skipped - // 2.2 block1 has 300 tx, 256 L1 messages, odd position is skipped, last is not skipped - // => payload for chunk1 - // 0000000000000000 - // 0000000000000000 - // 0000000000000000000000000000000000000000000000000000000000000000 - // 0000000000000000 - // 0005 - // 0000000000000000 - // 0000000000000000 - // 0000000000000000000000000000000000000000000000000000000000000000 - // 0000000000000000 - // 000a - // 0000000000000000 - // 0000000000000000 - // 0000000000000000000000000000000000000000000000000000000000000000 - // 0000000000000000 - // 012c - // ... (some tx hashes) - // => data hash for chunk2 - // e1276f58354ab2372050bde30d8c970ccc3728c76e97f37deebeee83ecbf5705 - // => data hash for all chunks - // 3c71d155351642d15f1542a1543ce423abeca1f8939100a0a34cdc3127b95f69 - // => payload for batch header - // 00 - // 0000000000000002 - // 0000000000000108 - // 0000000000000109 - // 3c71d155351642d15f1542a1543ce423abeca1f8939100a0a34cdc3127b95f69 - // cef70bf80683c4d9b8b2813e90c314e8c56648e231300b8cfed9d666b0caf14e - // aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa800000000000000000000000000000000000000000000000000000000000000aa - // => hash for batch header - // 03a9cdcb9d582251acf60937db006ec99f3505fd4751b7c1f92c9a8ef413e873 - bytes memory batchHeader2 = new bytes(89 + 32 + 32); - assembly { - mstore(add(batchHeader2, 0x20), 0) // version - mstore(add(batchHeader2, add(0x20, 1)), shl(192, 2)) // batchIndex = 2 - mstore(add(batchHeader2, add(0x20, 9)), shl(192, 264)) // l1MessagePopped = 264 - mstore(add(batchHeader2, add(0x20, 17)), shl(192, 265)) // totalL1MessagePopped = 265 - mstore(add(batchHeader2, add(0x20, 25)), 0x3c71d155351642d15f1542a1543ce423abeca1f8939100a0a34cdc3127b95f69) // dataHash - mstore(add(batchHeader2, add(0x20, 57)), batchHash1) // parentBatchHash - mstore( - add(batchHeader2, add(0x20, 89)), - 77194726158210796949047323339125271902179989777093709359638389338608753093160 - ) // bitmap0 - mstore(add(batchHeader2, add(0x20, 121)), 42) // bitmap1 - } - chunk0 = new bytes(1 + 60 + 3 * 5); - assembly { - mstore(add(chunk0, 0x20), shl(248, 1)) // numBlocks = 1 - mstore(add(chunk0, add(0x21, 56)), shl(240, 3)) // numTransactions = 3 - mstore(add(chunk0, add(0x21, 58)), shl(240, 0)) // numL1Messages = 0 - } - for (uint256 i = 0; i < 3; i++) { - assembly { - mstore(add(chunk0, add(93, mul(i, 5))), shl(224, 1)) // tx = "0x00" - } - } - chunk1 = new bytes(1 + 60 * 3 + 51 * 5); - assembly { - mstore(add(chunk1, 0x20), shl(248, 3)) // numBlocks = 3 - mstore(add(chunk1, add(33, 56)), shl(240, 5)) // block0.numTransactions = 5 - mstore(add(chunk1, add(33, 58)), shl(240, 3)) // block0.numL1Messages = 3 - mstore(add(chunk1, add(93, 56)), shl(240, 10)) // block1.numTransactions = 10 - mstore(add(chunk1, add(93, 58)), shl(240, 5)) // block1.numL1Messages = 5 - mstore(add(chunk1, add(153, 56)), shl(240, 300)) // block1.numTransactions = 300 - mstore(add(chunk1, add(153, 58)), shl(240, 256)) // block1.numL1Messages = 256 - } - for (uint256 i = 0; i < 51; i++) { - assembly { - mstore(add(chunk1, add(213, mul(i, 5))), shl(224, 1)) // tx = "0x00" - } - } - chunks = new bytes[](2); - chunks[0] = chunk0; - chunks[1] = chunk1; - bitmap = new bytes(64); - assembly { - mstore( - add(bitmap, add(0x20, 0)), - 77194726158210796949047323339125271902179989777093709359638389338608753093160 - ) // bitmap0 - mstore(add(bitmap, add(0x20, 32)), 42) // bitmap1 - } - - // too many txs in one chunk, revert - rollup.updateMaxNumTxInChunk(2); // 3 - 1 - hevm.startPrank(address(0)); - hevm.expectRevert(ScrollChain.ErrorTooManyTxsInOneChunk.selector); - rollup.commitBatch(0, batchHeader1, chunks, bitmap); // first chunk with too many txs - hevm.stopPrank(); - rollup.updateMaxNumTxInChunk(185); // 5+10+300 - 2 - 127 - hevm.startPrank(address(0)); - hevm.expectRevert(ScrollChain.ErrorTooManyTxsInOneChunk.selector); - rollup.commitBatch(0, batchHeader1, chunks, bitmap); // second chunk with too many txs - hevm.stopPrank(); - - rollup.updateMaxNumTxInChunk(186); - hevm.startPrank(address(0)); - hevm.expectEmit(true, true, false, true); - emit CommitBatch(2, bytes32(0x03a9cdcb9d582251acf60937db006ec99f3505fd4751b7c1f92c9a8ef413e873)); - rollup.commitBatch(0, batchHeader1, chunks, bitmap); - hevm.stopPrank(); - assertBoolEq(rollup.isBatchFinalized(2), false); - bytes32 batchHash2 = rollup.committedBatches(2); - assertEq(batchHash2, bytes32(0x03a9cdcb9d582251acf60937db006ec99f3505fd4751b7c1f92c9a8ef413e873)); - - // verify committed batch correctly - hevm.startPrank(address(0)); - hevm.expectEmit(true, true, false, true); - emit FinalizeBatch(2, batchHash2, bytes32(uint256(4)), bytes32(uint256(5))); - rollup.finalizeBatchWithProof( - batchHeader2, - bytes32(uint256(2)), - bytes32(uint256(4)), - bytes32(uint256(5)), - new bytes(0) - ); - hevm.stopPrank(); - assertBoolEq(rollup.isBatchFinalized(2), true); - assertEq(rollup.finalizedStateRoots(2), bytes32(uint256(4))); - assertEq(rollup.withdrawRoots(2), bytes32(uint256(5))); - assertEq(rollup.lastFinalizedBatchIndex(), 2); - assertEq(messageQueue.pendingQueueIndex(), 265); - // 1 ~ 4, zero - for (uint256 i = 1; i < 4; i++) { - assertBoolEq(messageQueue.isMessageSkipped(i), false); - } - // 4 ~ 9, even is nonzero, odd is zero - for (uint256 i = 4; i < 9; i++) { - if (i % 2 == 1 || i == 8) { - assertBoolEq(messageQueue.isMessageSkipped(i), false); - } else { - assertBoolEq(messageQueue.isMessageSkipped(i), true); - } - } - // 9 ~ 265, even is nonzero, odd is zero - for (uint256 i = 9; i < 265; i++) { - if (i % 2 == 1 || i == 264) { - assertBoolEq(messageQueue.isMessageSkipped(i), false); - } else { - assertBoolEq(messageQueue.isMessageSkipped(i), true); - } - } - } - - function testRevertBatch() external { - // caller not owner, revert - hevm.startPrank(address(1)); - hevm.expectRevert("Ownable: caller is not the owner"); - rollup.revertBatch(new bytes(89), 1); - hevm.stopPrank(); - - rollup.addSequencer(address(0)); - - bytes memory batchHeader0 = new bytes(89); - - // import genesis batch - assembly { - mstore(add(batchHeader0, add(0x20, 25)), 1) - } - rollup.importGenesisBatch(batchHeader0, bytes32(uint256(1))); - bytes32 batchHash0 = rollup.committedBatches(0); - - bytes[] memory chunks = new bytes[](1); - bytes memory chunk0; - - // commit one batch - chunk0 = new bytes(1 + 60); - chunk0[0] = bytes1(uint8(1)); // one block in this chunk - chunks[0] = chunk0; - hevm.startPrank(address(0)); - rollup.commitBatch(0, batchHeader0, chunks, new bytes(0)); - hevm.stopPrank(); - - bytes memory batchHeader1 = new bytes(89); - assembly { - mstore(add(batchHeader1, 0x20), 0) // version - mstore(add(batchHeader1, add(0x20, 1)), shl(192, 1)) // batchIndex - mstore(add(batchHeader1, add(0x20, 9)), 0) // l1MessagePopped - mstore(add(batchHeader1, add(0x20, 17)), 0) // totalL1MessagePopped - mstore(add(batchHeader1, add(0x20, 25)), 0x246394445f4fe64ed5598554d55d1682d6fb3fe04bf58eb54ef81d1189fafb51) // dataHash - mstore(add(batchHeader1, add(0x20, 57)), batchHash0) // parentBatchHash - } - - // commit another batch - hevm.startPrank(address(0)); - rollup.commitBatch(0, batchHeader1, chunks, new bytes(0)); - hevm.stopPrank(); - - // count must be nonzero, revert - hevm.expectRevert(ScrollChain.ErrorRevertZeroBatches.selector); - rollup.revertBatch(batchHeader0, 0); - - // incorrect batch hash, revert - hevm.expectRevert(ScrollChain.ErrorIncorrectBatchHash.selector); - batchHeader1[1] = bytes1(uint8(1)); // change random byte - rollup.revertBatch(batchHeader1, 1); - batchHeader1[1] = bytes1(uint8(0)); // change back - - // revert middle batch, revert - hevm.expectRevert(ScrollChain.ErrorRevertNotStartFromEnd.selector); - rollup.revertBatch(batchHeader1, 1); - - // can only revert unfinalized batch, revert - hevm.expectRevert(ScrollChain.ErrorRevertFinalizedBatch.selector); - rollup.revertBatch(batchHeader0, 3); - - // succeed to revert next two pending batches. - - hevm.expectEmit(true, true, false, true); - emit RevertBatch(1, rollup.committedBatches(1)); - hevm.expectEmit(true, true, false, true); - emit RevertBatch(2, rollup.committedBatches(2)); - - assertGt(uint256(rollup.committedBatches(1)), 0); - assertGt(uint256(rollup.committedBatches(2)), 0); - rollup.revertBatch(batchHeader1, 2); - assertEq(uint256(rollup.committedBatches(1)), 0); - assertEq(uint256(rollup.committedBatches(2)), 0); - } - - function testAddAndRemoveSequencer(address _sequencer) external { - // set by non-owner, should revert - hevm.startPrank(address(1)); - hevm.expectRevert("Ownable: caller is not the owner"); - rollup.addSequencer(_sequencer); - hevm.expectRevert("Ownable: caller is not the owner"); - rollup.removeSequencer(_sequencer); - hevm.stopPrank(); - - hevm.expectRevert(ScrollChain.ErrorAccountIsNotEOA.selector); - rollup.addSequencer(address(this)); - hevm.assume(_sequencer.code.length == 0); - - // change to random EOA operator - hevm.expectEmit(true, false, false, true); - emit UpdateSequencer(_sequencer, true); - - assertBoolEq(rollup.isSequencer(_sequencer), false); - rollup.addSequencer(_sequencer); - assertBoolEq(rollup.isSequencer(_sequencer), true); - - hevm.expectEmit(true, false, false, true); - emit UpdateSequencer(_sequencer, false); - rollup.removeSequencer(_sequencer); - assertBoolEq(rollup.isSequencer(_sequencer), false); - } - - function testAddAndRemoveProver(address _prover) external { - // set by non-owner, should revert - hevm.startPrank(address(1)); - hevm.expectRevert("Ownable: caller is not the owner"); - rollup.addProver(_prover); - hevm.expectRevert("Ownable: caller is not the owner"); - rollup.removeProver(_prover); - hevm.stopPrank(); - - hevm.expectRevert(ScrollChain.ErrorAccountIsNotEOA.selector); - rollup.addProver(address(this)); - hevm.assume(_prover.code.length == 0); - - // change to random EOA operator - hevm.expectEmit(true, false, false, true); - emit UpdateProver(_prover, true); - - assertBoolEq(rollup.isProver(_prover), false); - rollup.addProver(_prover); - assertBoolEq(rollup.isProver(_prover), true); - - hevm.expectEmit(true, false, false, true); - emit UpdateProver(_prover, false); - rollup.removeProver(_prover); - assertBoolEq(rollup.isProver(_prover), false); - } - - function testSetPause() external { - rollup.addSequencer(address(0)); - rollup.addProver(address(0)); - - // not owner, revert - hevm.startPrank(address(1)); - hevm.expectRevert("Ownable: caller is not the owner"); - rollup.setPause(false); - hevm.stopPrank(); - - // pause - rollup.setPause(true); - assertBoolEq(true, rollup.paused()); - - hevm.startPrank(address(0)); - hevm.expectRevert("Pausable: paused"); - rollup.commitBatch(0, new bytes(0), new bytes[](0), new bytes(0)); - hevm.expectRevert("Pausable: paused"); - rollup.finalizeBatchWithProof(new bytes(0), bytes32(0), bytes32(0), bytes32(0), new bytes(0)); - hevm.stopPrank(); - - // unpause - rollup.setPause(false); - assertBoolEq(false, rollup.paused()); - } - - function testUpdateMaxNumTxInChunk(uint256 _maxNumTxInChunk) external { - // set by non-owner, should revert - hevm.startPrank(address(1)); - hevm.expectRevert("Ownable: caller is not the owner"); - rollup.updateMaxNumTxInChunk(_maxNumTxInChunk); - hevm.stopPrank(); - - // change to random operator - hevm.expectEmit(false, false, false, true); - emit UpdateMaxNumTxInChunk(100, _maxNumTxInChunk); - - assertEq(rollup.maxNumTxInChunk(), 100); - rollup.updateMaxNumTxInChunk(_maxNumTxInChunk); - assertEq(rollup.maxNumTxInChunk(), _maxNumTxInChunk); - } - - function testImportGenesisBlock() external { - bytes memory batchHeader; - - // zero state root, revert - batchHeader = new bytes(89); - hevm.expectRevert(ScrollChain.ErrorStateRootIsZero.selector); - rollup.importGenesisBatch(batchHeader, bytes32(0)); - - // batch header length too small, revert - batchHeader = new bytes(88); - hevm.expectRevert(BatchHeaderV0Codec.ErrorBatchHeaderLengthTooSmall.selector); - rollup.importGenesisBatch(batchHeader, bytes32(uint256(1))); - - // wrong bitmap length, revert - batchHeader = new bytes(90); - hevm.expectRevert(BatchHeaderV0Codec.ErrorIncorrectBitmapLength.selector); - rollup.importGenesisBatch(batchHeader, bytes32(uint256(1))); - - // not all fields are zero, revert - batchHeader = new bytes(121); - batchHeader[0] = bytes1(uint8(1)); // version not zero - hevm.expectRevert(ScrollChain.ErrorGenesisBatchHasNonZeroField.selector); - rollup.importGenesisBatch(batchHeader, bytes32(uint256(1))); - - batchHeader = new bytes(89); - batchHeader[1] = bytes1(uint8(1)); // batchIndex not zero - hevm.expectRevert(ScrollChain.ErrorGenesisBatchHasNonZeroField.selector); - rollup.importGenesisBatch(batchHeader, bytes32(uint256(1))); - - batchHeader = new bytes(89 + 32); - assembly { - mstore(add(batchHeader, add(0x20, 9)), shl(192, 1)) // l1MessagePopped not zero - } - hevm.expectRevert(ScrollChain.ErrorGenesisBatchHasNonZeroField.selector); - rollup.importGenesisBatch(batchHeader, bytes32(uint256(1))); - - batchHeader = new bytes(89); - batchHeader[17] = bytes1(uint8(1)); // totalL1MessagePopped not zero - hevm.expectRevert(ScrollChain.ErrorGenesisBatchHasNonZeroField.selector); - rollup.importGenesisBatch(batchHeader, bytes32(uint256(1))); - - // zero data hash, revert - batchHeader = new bytes(89); - hevm.expectRevert(ScrollChain.ErrorGenesisDataHashIsZero.selector); - rollup.importGenesisBatch(batchHeader, bytes32(uint256(1))); - - // nonzero parent batch hash, revert - batchHeader = new bytes(89); - batchHeader[25] = bytes1(uint8(1)); // dataHash not zero - batchHeader[57] = bytes1(uint8(1)); // parentBatchHash not zero - hevm.expectRevert(ScrollChain.ErrorGenesisParentBatchHashIsNonZero.selector); - rollup.importGenesisBatch(batchHeader, bytes32(uint256(1))); - - // import correctly - batchHeader = new bytes(89); - batchHeader[25] = bytes1(uint8(1)); // dataHash not zero - assertEq(rollup.finalizedStateRoots(0), bytes32(0)); - assertEq(rollup.withdrawRoots(0), bytes32(0)); - assertEq(rollup.committedBatches(0), bytes32(0)); - rollup.importGenesisBatch(batchHeader, bytes32(uint256(1))); - assertEq(rollup.finalizedStateRoots(0), bytes32(uint256(1))); - assertEq(rollup.withdrawRoots(0), bytes32(0)); - assertGt(uint256(rollup.committedBatches(0)), 0); - - // Genesis batch imported, revert - hevm.expectRevert(ScrollChain.ErrorGenesisBatchImported.selector); - rollup.importGenesisBatch(batchHeader, bytes32(uint256(1))); - } - - function _deployProxy(address _logic) internal returns (address) { - if (_logic == address(0)) _logic = address(placeholder); - TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy(_logic, address(admin), new bytes(0)); - return address(proxy); - } -} diff --git a/contracts/src/test/ScrollOwner.t.sol b/contracts/src/test/ScrollOwner.t.sol deleted file mode 100644 index bd4d745f9..000000000 --- a/contracts/src/test/ScrollOwner.t.sol +++ /dev/null @@ -1,97 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import {DSTestPlus} from "solmate/test/utils/DSTestPlus.sol"; - -import {ScrollOwner} from "../misc/ScrollOwner.sol"; - -contract ScrollOwnerTest is DSTestPlus { - event GrantAccess(bytes32 indexed role, address indexed target, bytes4[] selectors); - event RevokeAccess(bytes32 indexed role, address indexed target, bytes4[] selectors); - event Call(); - - ScrollOwner private owner; - - function setUp() public { - owner = new ScrollOwner(); - } - - function testUpdateAccess() external { - // not admin, evert - hevm.startPrank(address(1)); - hevm.expectRevert( - "AccessControl: account 0x0000000000000000000000000000000000000001 is missing role 0x0000000000000000000000000000000000000000000000000000000000000000" - ); - owner.updateAccess(address(0), new bytes4[](0), bytes32(0), true); - hevm.stopPrank(); - - bytes4[] memory _selectors; - bytes32[] memory _roles; - - // add access then remove access - _roles = owner.callableRoles(address(this), ScrollOwnerTest.revertOnCall.selector); - assertEq(0, _roles.length); - _selectors = new bytes4[](1); - _selectors[0] = ScrollOwnerTest.revertOnCall.selector; - - hevm.expectEmit(true, true, false, true); - emit GrantAccess(bytes32(uint256(1)), address(this), _selectors); - - owner.updateAccess(address(this), _selectors, bytes32(uint256(1)), true); - _roles = owner.callableRoles(address(this), ScrollOwnerTest.revertOnCall.selector); - assertEq(1, _roles.length); - assertEq(_roles[0], bytes32(uint256(1))); - - hevm.expectEmit(true, true, false, true); - emit RevokeAccess(bytes32(uint256(1)), address(this), _selectors); - - owner.updateAccess(address(this), _selectors, bytes32(uint256(1)), false); - _roles = owner.callableRoles(address(this), ScrollOwnerTest.revertOnCall.selector); - assertEq(0, _roles.length); - } - - function testAdminExecute() external { - // call with revert - hevm.expectRevert("Called"); - owner.execute(address(this), 0, abi.encodeWithSelector(ScrollOwnerTest.revertOnCall.selector), bytes32(0)); - - // call with emit - hevm.expectEmit(false, false, false, true); - emit Call(); - owner.execute(address(this), 0, abi.encodeWithSelector(ScrollOwnerTest.emitOnCall.selector), bytes32(0)); - } - - function testExecute(bytes32 _role) external { - hevm.assume(_role != bytes32(0)); - - bytes4[] memory _selectors = new bytes4[](2); - _selectors[0] = ScrollOwnerTest.revertOnCall.selector; - _selectors[1] = ScrollOwnerTest.emitOnCall.selector; - - owner.grantRole(_role, address(this)); - - // no access, revert - hevm.expectRevert("no access"); - owner.execute(address(this), 0, abi.encodeWithSelector(ScrollOwnerTest.revertOnCall.selector), _role); - - owner.updateAccess(address(this), _selectors, _role, true); - - // call with revert - hevm.expectRevert("Called"); - owner.execute(address(this), 0, abi.encodeWithSelector(ScrollOwnerTest.revertOnCall.selector), _role); - - // call with emit - hevm.expectEmit(false, false, false, true); - emit Call(); - owner.execute(address(this), 0, abi.encodeWithSelector(ScrollOwnerTest.emitOnCall.selector), _role); - } - - function revertOnCall() external pure { - revert("Called"); - } - - function emitOnCall() external { - emit Call(); - } -} diff --git a/contracts/src/test/ScrollStandardERC20Factory.t.sol b/contracts/src/test/ScrollStandardERC20Factory.t.sol deleted file mode 100644 index 9059f45f2..000000000 --- a/contracts/src/test/ScrollStandardERC20Factory.t.sol +++ /dev/null @@ -1,32 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {DSTestPlus} from "solmate/test/utils/DSTestPlus.sol"; -import {WETH} from "solmate/tokens/WETH.sol"; - -import {ScrollStandardERC20} from "../libraries/token/ScrollStandardERC20.sol"; -import {ScrollStandardERC20Factory} from "../libraries/token/ScrollStandardERC20Factory.sol"; - -contract ScrollStandardERC20FactoryTest is DSTestPlus { - ScrollStandardERC20 private impl; - ScrollStandardERC20Factory private factory; - - function setUp() public { - impl = new ScrollStandardERC20(); - factory = new ScrollStandardERC20Factory(address(impl)); - } - - function testDeployL2Token(address _gateway, address _l1Token) external { - // call by non-owner, should revert - hevm.startPrank(address(1)); - hevm.expectRevert("Ownable: caller is not the owner"); - factory.deployL2Token(_gateway, _l1Token); - hevm.stopPrank(); - - // call by owner, should succeed - address computed = factory.computeL2TokenAddress(_gateway, _l1Token); - address deployed = factory.deployL2Token(_gateway, _l1Token); - assertEq(computed, deployed); - } -} diff --git a/contracts/src/test/ScrollTestBase.t.sol b/contracts/src/test/ScrollTestBase.t.sol deleted file mode 100644 index 19a66f39d..000000000 --- a/contracts/src/test/ScrollTestBase.t.sol +++ /dev/null @@ -1,27 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {DSTestPlus} from "solmate/test/utils/DSTestPlus.sol"; - -import {ProxyAdmin} from "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol"; -import {ITransparentUpgradeableProxy, TransparentUpgradeableProxy} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; - -import {EmptyContract} from "../misc/EmptyContract.sol"; - -abstract contract ScrollTestBase is DSTestPlus { - ProxyAdmin internal admin; - - EmptyContract private placeholder; - - function __ScrollTestBase_setUp() internal { - admin = new ProxyAdmin(); - placeholder = new EmptyContract(); - } - - function _deployProxy(address _logic) internal returns (address) { - if (_logic == address(0)) _logic = address(placeholder); - TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy(_logic, address(admin), new bytes(0)); - return address(proxy); - } -} diff --git a/contracts/src/test/TokenRateLimiter.t.sol b/contracts/src/test/TokenRateLimiter.t.sol deleted file mode 100644 index 5eb44b14c..000000000 --- a/contracts/src/test/TokenRateLimiter.t.sol +++ /dev/null @@ -1,82 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {DSTestPlus} from "solmate/test/utils/DSTestPlus.sol"; - -import {TokenRateLimiter} from "../rate-limiter/TokenRateLimiter.sol"; -import {ITokenRateLimiter} from "../rate-limiter/ITokenRateLimiter.sol"; - -contract TokenRateLimiterTest is DSTestPlus { - event UpdateTotalLimit(address indexed token, uint256 oldTotalLimit, uint256 newTotalLimit); - - TokenRateLimiter private limiter; - - function setUp() public { - hevm.warp(86400); - limiter = new TokenRateLimiter(86400); - } - - function testUpdateTotalLimit(address _token, uint104 _newTotalLimit) external { - hevm.assume(_newTotalLimit > 0); - - // not admin, revert - hevm.startPrank(address(1)); - hevm.expectRevert( - "AccessControl: account 0x0000000000000000000000000000000000000001 is missing role 0x0000000000000000000000000000000000000000000000000000000000000000" - ); - limiter.updateTotalLimit(_token, _newTotalLimit); - hevm.stopPrank(); - - // zero revert - hevm.expectRevert(abi.encodeWithSelector(ITokenRateLimiter.TotalLimitIsZero.selector, _token)); - limiter.updateTotalLimit(_token, 0); - - // success - hevm.expectEmit(true, false, false, true); - emit UpdateTotalLimit(_token, 0 ether, _newTotalLimit); - limiter.updateTotalLimit(_token, _newTotalLimit); - (, uint104 _totalLimit, ) = limiter.currentPeriod(_token); - assertEq(_totalLimit, _newTotalLimit); - } - - function testAddUsedAmount(address _token) external { - // non-spender, revert - hevm.startPrank(address(1)); - hevm.expectRevert( - "AccessControl: account 0x0000000000000000000000000000000000000001 is missing role 0x267f05081a073059ae452e6ac77ec189636e43e41051d4c3ec760734b3d173cb" - ); - limiter.addUsedAmount(_token, 0); - hevm.stopPrank(); - - limiter.grantRole(bytes32(0x267f05081a073059ae452e6ac77ec189636e43e41051d4c3ec760734b3d173cb), address(this)); - limiter.updateTotalLimit(_token, 100 ether); - - // exceed total limit on first call - hevm.expectRevert(abi.encodeWithSelector(ITokenRateLimiter.ExceedTotalLimit.selector, _token)); - limiter.addUsedAmount(_token, 100 ether + 1); - _checkTotalCurrentPeriodAmountAmount(_token, 0); - - // exceed total limit on second call - limiter.addUsedAmount(_token, 50 ether); - _checkTotalCurrentPeriodAmountAmount(_token, 50 ether); - hevm.expectRevert(abi.encodeWithSelector(ITokenRateLimiter.ExceedTotalLimit.selector, _token)); - limiter.addUsedAmount(_token, 50 ether + 1); - _checkTotalCurrentPeriodAmountAmount(_token, 50 ether); - - // one period passed - hevm.warp(86400 * 2); - limiter.addUsedAmount(_token, 1 ether); - _checkTotalCurrentPeriodAmountAmount(_token, 1 ether); - - // exceed - hevm.expectRevert(abi.encodeWithSelector(ITokenRateLimiter.ExceedTotalLimit.selector, _token)); - limiter.addUsedAmount(_token, 99 ether + 1); - _checkTotalCurrentPeriodAmountAmount(_token, 1 ether); - } - - function _checkTotalCurrentPeriodAmountAmount(address token, uint256 expected) internal { - (, , uint256 totalAmount) = limiter.currentPeriod(token); - assertEq(totalAmount, expected); - } -} diff --git a/contracts/src/test/Whitelist.t.sol b/contracts/src/test/Whitelist.t.sol deleted file mode 100644 index 5c4a4a3e7..000000000 --- a/contracts/src/test/Whitelist.t.sol +++ /dev/null @@ -1,64 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {DSTestPlus} from "solmate/test/utils/DSTestPlus.sol"; -import {WETH} from "solmate/tokens/WETH.sol"; - -import {Whitelist} from "../L2/predeploys/Whitelist.sol"; - -contract WhitelistTest is DSTestPlus { - Whitelist private whitelist; - - function setUp() public { - whitelist = new Whitelist(address(this)); - } - - function testRenounceOwnership() external { - // call by non-owner, should revert - hevm.startPrank(address(1)); - hevm.expectRevert("caller is not the owner"); - whitelist.renounceOwnership(); - hevm.stopPrank(); - - // call by owner, should succeed - assertEq(whitelist.owner(), address(this)); - whitelist.renounceOwnership(); - assertEq(whitelist.owner(), address(0)); - } - - function testTransferOwnership(address _to) external { - // call by non-owner, should revert - hevm.startPrank(address(1)); - hevm.expectRevert("caller is not the owner"); - whitelist.transferOwnership(_to); - hevm.stopPrank(); - - // call by owner, should succeed - if (_to == address(0)) { - hevm.expectRevert("new owner is the zero address"); - whitelist.transferOwnership(_to); - } else { - assertEq(whitelist.owner(), address(this)); - whitelist.transferOwnership(_to); - assertEq(whitelist.owner(), _to); - } - } - - function testUpdateWhitelistStatus(address _to) external { - address[] memory _accounts = new address[](1); - _accounts[0] = _to; - // call by non-owner, should revert - hevm.startPrank(address(1)); - hevm.expectRevert("caller is not the owner"); - whitelist.updateWhitelistStatus(_accounts, true); - hevm.stopPrank(); - - // call by owner, should succeed - assertBoolEq(whitelist.isSenderAllowed(_to), false); - whitelist.updateWhitelistStatus(_accounts, true); - assertBoolEq(whitelist.isSenderAllowed(_to), true); - whitelist.updateWhitelistStatus(_accounts, false); - assertBoolEq(whitelist.isSenderAllowed(_to), false); - } -} diff --git a/contracts/src/test/WithdrawTrieVerifier.t.sol b/contracts/src/test/WithdrawTrieVerifier.t.sol deleted file mode 100644 index ddef16df2..000000000 --- a/contracts/src/test/WithdrawTrieVerifier.t.sol +++ /dev/null @@ -1,55 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {DSTestPlus} from "solmate/test/utils/DSTestPlus.sol"; - -import {WithdrawTrieVerifier} from "../libraries/verifier/WithdrawTrieVerifier.sol"; - -contract WithdrawTrieVerifierTest is DSTestPlus { - function testInvalidProof() public { - hevm.expectRevert("Invalid proof"); - WithdrawTrieVerifier.verifyMerkleProof(bytes32(uint256(1)), bytes32(uint256(1)), 1, hex"00"); - } - - function testMerkleProof() public { - bytes32[] memory roots = new bytes32[](4); - bytes32[] memory hashes = new bytes32[](4); - uint256[] memory nonces = new uint256[](4); - bytes[] memory proofs = new bytes[](4); - - // generated from bridge folder - // adding leaves one at a time (0x0..1, 0x0..2, 0x0..3, 0x0..4) - - roots[0] = hex"0000000000000000000000000000000000000000000000000000000000000001"; - hashes[0] = hex"0000000000000000000000000000000000000000000000000000000000000001"; - nonces[0] = 0; - proofs[0] = hex""; - - roots[1] = hex"e90b7bceb6e7df5418fb78d8ee546e97c83a08bbccc01a0644d599ccd2a7c2e0"; - hashes[1] = hex"0000000000000000000000000000000000000000000000000000000000000002"; - nonces[1] = 1; - proofs[1] = hex"0000000000000000000000000000000000000000000000000000000000000001"; - - roots[2] = hex"222ff5e0b5877792c2bc1670e2ccd0c2c97cd7bb1672a57d598db05092d3d72c"; - hashes[2] = hex"0000000000000000000000000000000000000000000000000000000000000003"; - nonces[2] = 2; - proofs[ - 2 - ] = hex"0000000000000000000000000000000000000000000000000000000000000000e90b7bceb6e7df5418fb78d8ee546e97c83a08bbccc01a0644d599ccd2a7c2e0"; - - roots[3] = hex"a9bb8c3f1f12e9aa903a50c47f314b57610a3ab32f2d463293f58836def38d36"; - hashes[3] = hex"0000000000000000000000000000000000000000000000000000000000000004"; - nonces[3] = 3; - proofs[ - 3 - ] = hex"0000000000000000000000000000000000000000000000000000000000000003e90b7bceb6e7df5418fb78d8ee546e97c83a08bbccc01a0644d599ccd2a7c2e0"; - - for (uint256 i = 0; i < 4; i++) { - require( - WithdrawTrieVerifier.verifyMerkleProof(roots[i], hashes[i], nonces[i], proofs[i]) == true, - "WithdrawTrieVerifier: verifyMerkleProof failed" - ); - } - } -} diff --git a/contracts/src/test/batch-bridge/L1BatchBridgeGateway.t.sol b/contracts/src/test/batch-bridge/L1BatchBridgeGateway.t.sol deleted file mode 100644 index 0f26de4f9..000000000 --- a/contracts/src/test/batch-bridge/L1BatchBridgeGateway.t.sol +++ /dev/null @@ -1,634 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {MockERC20} from "solmate/test/utils/mocks/MockERC20.sol"; - -import {ITransparentUpgradeableProxy} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; -import {Strings} from "@openzeppelin/contracts/utils/Strings.sol"; - -import {L1BatchBridgeGateway} from "../../batch-bridge/L1BatchBridgeGateway.sol"; -import {L2BatchBridgeGateway} from "../../batch-bridge/L2BatchBridgeGateway.sol"; -import {BatchBridgeCodec} from "../../batch-bridge/BatchBridgeCodec.sol"; -import {IL1ERC20Gateway, L1CustomERC20Gateway} from "../../L1/gateways/L1CustomERC20Gateway.sol"; -import {L1GatewayRouter} from "../../L1/gateways/L1GatewayRouter.sol"; -import {IL2ERC20Gateway, L2CustomERC20Gateway} from "../../L2/gateways/L2CustomERC20Gateway.sol"; -import {AddressAliasHelper} from "../../libraries/common/AddressAliasHelper.sol"; -import {ScrollConstants} from "../../libraries/constants/ScrollConstants.sol"; - -import {L1GatewayTestBase} from "../L1GatewayTestBase.t.sol"; - -contract L1BatchBridgeGatewayTest is L1GatewayTestBase { - event Deposit( - address indexed sender, - address indexed token, - uint256 indexed batchIndex, - uint256 amount, - uint256 fee - ); - event BatchDeposit(address indexed caller, address indexed l1Token, uint256 indexed batchIndex, address l2Token); - event DepositERC20( - address indexed _l1Token, - address indexed _l2Token, - address indexed _from, - address _to, - uint256 _amount, - bytes _data - ); - - uint24 private constant SAFE_BATCH_BRIDGE_GAS_LIMIT = 200000; - uint24 ETH_DEPOSIT_SAFE_GAS_LIMIT = 300000; - uint24 ERC20_DEPOSIT_SAFE_GAS_LIMIT = 200000; - - uint256 private constant L2_GAS_PRICE = 10; - - L1BatchBridgeGateway private batch; - L1CustomERC20Gateway private gateway; - L1GatewayRouter private router; - - L2CustomERC20Gateway private counterpartGateway; - L2BatchBridgeGateway private counterpartBatch; - - MockERC20 private l1Token; - MockERC20 private l2Token; - - address private batchFeeVault; - - function setUp() public { - __L1GatewayTestBase_setUp(); - - batchFeeVault = address(uint160(address(this)) - 2); - - // Deploy tokens - l1Token = new MockERC20("Mock L1", "ML1", 18); - l2Token = new MockERC20("Mock L2", "ML2", 18); - - // Deploy L2 contracts - counterpartGateway = new L2CustomERC20Gateway(address(1), address(1), address(1)); - counterpartBatch = new L2BatchBridgeGateway(address(1), address(1)); - - // Deploy L1 contracts - router = L1GatewayRouter(_deployProxy(address(new L1GatewayRouter()))); - gateway = L1CustomERC20Gateway(_deployProxy(address(0))); - batch = L1BatchBridgeGateway(payable(_deployProxy(address(0)))); - - // Initialize L1 contracts - admin.upgrade( - ITransparentUpgradeableProxy(address(gateway)), - address(new L1CustomERC20Gateway(address(counterpartGateway), address(router), address(l1Messenger))) - ); - gateway.initialize(address(counterpartGateway), address(router), address(l1Messenger)); - admin.upgrade( - ITransparentUpgradeableProxy(address(batch)), - address( - new L1BatchBridgeGateway( - address(counterpartBatch), - address(router), - address(l1Messenger), - address(messageQueue) - ) - ) - ); - batch.initialize(batchFeeVault); - router.initialize(address(0), address(gateway)); - messageQueue.setL2BaseFee(L2_GAS_PRICE); - - // Prepare token balances - l1Token.mint(address(this), type(uint128).max); - gateway.updateTokenMapping(address(l1Token), address(l2Token)); - hevm.warp(1000000); - } - - function testInitialized() external { - assertBoolEq(true, batch.hasRole(bytes32(0), address(this))); - assertEq(address(counterpartBatch), batch.counterpart()); - assertEq(address(router), batch.router()); - assertEq(address(l1Messenger), batch.messenger()); - assertEq(address(messageQueue), batch.queue()); - - hevm.expectRevert("Initializable: contract is already initialized"); - batch.initialize(address(0)); - } - - function testSetTokenSetting() external { - // revert not admin - hevm.startPrank(address(1)); - hevm.expectRevert( - "AccessControl: account 0x0000000000000000000000000000000000000001 is missing role 0x0000000000000000000000000000000000000000000000000000000000000000" - ); - batch.setBatchConfig(address(0), L1BatchBridgeGateway.BatchConfig(0, 0, 0, 0, 0)); - hevm.stopPrank(); - - // revert maxTxsPerBatch = 0 - hevm.expectRevert(L1BatchBridgeGateway.ErrorInvalidBatchConfig.selector); - batch.setBatchConfig(address(0), L1BatchBridgeGateway.BatchConfig(0, 0, 0, 0, 0)); - - // revert maxDelayPerBatch = 0 - hevm.expectRevert(L1BatchBridgeGateway.ErrorInvalidBatchConfig.selector); - batch.setBatchConfig(address(0), L1BatchBridgeGateway.BatchConfig(0, 0, 1, 0, 0)); - - // revert feeAmountPerTx > minAmountPerTx - hevm.expectRevert(L1BatchBridgeGateway.ErrorInvalidBatchConfig.selector); - batch.setBatchConfig(address(0), L1BatchBridgeGateway.BatchConfig(1, 0, 1, 1, 0)); - - // succeed - batch.setBatchConfig(address(0), L1BatchBridgeGateway.BatchConfig(1, 2, 3, 4, 5)); - ( - uint96 feeAmountPerTx, - uint96 minAmountPerTx, - uint16 maxTxsPerBatch, - uint24 maxDelayPerBatch, - uint24 safeBridgeGasLimit - ) = batch.configs(address(0)); - assertEq(feeAmountPerTx, 1); - assertEq(minAmountPerTx, 2); - assertEq(maxTxsPerBatch, 3); - assertEq(maxDelayPerBatch, 4); - assertEq(safeBridgeGasLimit, 5); - } - - function testSetTokenSettingFuzzing(address token, L1BatchBridgeGateway.BatchConfig memory config) external { - hevm.assume(config.maxTxsPerBatch > 0); - hevm.assume(config.maxDelayPerBatch > 0); - hevm.assume(config.feeAmountPerTx <= config.minAmountPerTx); - - ( - uint96 feeAmountPerTx, - uint96 minAmountPerTx, - uint16 maxTxsPerBatch, - uint24 maxDelayPerBatch, - uint24 safeBridgeGasLimit - ) = batch.configs(token); - assertEq(feeAmountPerTx, 0); - assertEq(minAmountPerTx, 0); - assertEq(maxTxsPerBatch, 0); - assertEq(maxDelayPerBatch, 0); - assertEq(safeBridgeGasLimit, 0); - batch.setBatchConfig(token, config); - (feeAmountPerTx, minAmountPerTx, maxTxsPerBatch, maxDelayPerBatch, safeBridgeGasLimit) = batch.configs(token); - assertEq(feeAmountPerTx, config.feeAmountPerTx); - assertEq(minAmountPerTx, config.minAmountPerTx); - assertEq(maxTxsPerBatch, config.maxTxsPerBatch); - assertEq(maxDelayPerBatch, config.maxDelayPerBatch); - assertEq(safeBridgeGasLimit, config.safeBridgeGasLimit); - } - - function checkBatchState( - address token, - uint256 phase, - L1BatchBridgeGateway.BatchState memory expected - ) private { - (uint128 amount, uint64 startTime, uint64 numDeposits, bytes32 hash) = batch.batches(token, phase); - assertEq(amount, expected.amount); - assertEq(startTime, expected.startTime); - assertEq(numDeposits, expected.numDeposits); - // assertEq(hash, expected.hash); - } - - function checkTokenState(address token, L1BatchBridgeGateway.TokenState memory expected) private { - (uint128 pending, uint64 currentBatchIndex, uint64 pendingBatchIndex) = batch.tokens(token); - assertEq(pending, expected.pending); - assertEq(currentBatchIndex, expected.currentBatchIndex); - assertEq(pendingBatchIndex, expected.pendingBatchIndex); - } - - function testDepositETH() external { - // revert token not supported - hevm.expectRevert(L1BatchBridgeGateway.ErrorTokenNotSupported.selector); - batch.depositETH(); - - // revert deposit amount too small - batch.setBatchConfig(address(0), L1BatchBridgeGateway.BatchConfig(0, 100, 2, 100, ETH_DEPOSIT_SAFE_GAS_LIMIT)); - hevm.expectRevert(L1BatchBridgeGateway.ErrorDepositAmountTooSmall.selector); - batch.depositETH{value: 10}(); - - // no fee - batch.setBatchConfig(address(0), L1BatchBridgeGateway.BatchConfig(0, 0, 2, 100, ETH_DEPOSIT_SAFE_GAS_LIMIT)); - assertEq(0, address(batch).balance); - checkBatchState(address(0), 0, L1BatchBridgeGateway.BatchState(0, 0, 0, bytes32(0))); - checkTokenState(address(0), L1BatchBridgeGateway.TokenState(0, 0, 0)); - - hevm.warp(1000001); - hevm.expectEmit(true, true, true, true); - emit Deposit(address(this), address(0), 0, 1000, 0); - batch.depositETH{value: 1000}(); - assertEq(1000, address(batch).balance); - checkBatchState(address(0), 0, L1BatchBridgeGateway.BatchState(1000, 1000001, 1, bytes32(0))); - checkTokenState(address(0), L1BatchBridgeGateway.TokenState(1000, 0, 0)); - - hevm.warp(1000002); - hevm.expectEmit(true, true, true, true); - emit Deposit(address(this), address(0), 0, 2000, 0); - batch.depositETH{value: 2000}(); - assertEq(3000, address(batch).balance); - checkBatchState(address(0), 0, L1BatchBridgeGateway.BatchState(3000, 1000001, 2, bytes32(0))); - checkTokenState(address(0), L1BatchBridgeGateway.TokenState(3000, 0, 0)); - - hevm.warp(1000003); - hevm.expectEmit(true, true, true, true); - emit Deposit(address(this), address(0), 1, 3000, 0); - batch.depositETH{value: 3000}(); - assertEq(6000, address(batch).balance); - checkBatchState(address(0), 1, L1BatchBridgeGateway.BatchState(3000, 1000003, 1, bytes32(0))); - checkTokenState(address(0), L1BatchBridgeGateway.TokenState(6000, 1, 0)); - - // with fee - batch.setBatchConfig( - address(0), - L1BatchBridgeGateway.BatchConfig(100, 1000, 2, 100, ETH_DEPOSIT_SAFE_GAS_LIMIT) - ); - - hevm.warp(1000004); - hevm.expectEmit(true, true, true, true); - emit Deposit(address(this), address(0), 1, 1000, 100); - batch.depositETH{value: 1000}(); - assertEq(7000, address(batch).balance); - checkBatchState(address(0), 1, L1BatchBridgeGateway.BatchState(3900, 1000003, 2, bytes32(0))); - checkTokenState(address(0), L1BatchBridgeGateway.TokenState(6900, 1, 0)); - - hevm.warp(1000005); - hevm.expectEmit(true, true, true, true); - emit Deposit(address(this), address(0), 2, 2000, 100); - batch.depositETH{value: 2000}(); - assertEq(9000, address(batch).balance); - checkBatchState(address(0), 2, L1BatchBridgeGateway.BatchState(1900, 1000005, 1, bytes32(0))); - checkTokenState(address(0), L1BatchBridgeGateway.TokenState(8800, 2, 0)); - - hevm.warp(1000006); - hevm.expectEmit(true, true, true, true); - emit Deposit(address(this), address(0), 2, 3000, 100); - batch.depositETH{value: 3000}(); - assertEq(12000, address(batch).balance); - checkBatchState(address(0), 2, L1BatchBridgeGateway.BatchState(4800, 1000005, 2, bytes32(0))); - checkTokenState(address(0), L1BatchBridgeGateway.TokenState(11700, 2, 0)); - - // switch phase by timestamp - batch.setBatchConfig(address(0), L1BatchBridgeGateway.BatchConfig(0, 0, 100, 100, ETH_DEPOSIT_SAFE_GAS_LIMIT)); - - hevm.expectEmit(true, true, true, true); - emit Deposit(address(this), address(0), 2, 1000, 0); - batch.depositETH{value: 1000}(); - assertEq(13000, address(batch).balance); - checkBatchState(address(0), 2, L1BatchBridgeGateway.BatchState(5800, 1000005, 3, bytes32(0))); - checkTokenState(address(0), L1BatchBridgeGateway.TokenState(12700, 2, 0)); - - hevm.warp(1000005 + 100 + 1); - hevm.expectEmit(true, true, true, true); - emit Deposit(address(this), address(0), 3, 1000, 0); - batch.depositETH{value: 1000}(); - assertEq(14000, address(batch).balance); - checkBatchState(address(0), 3, L1BatchBridgeGateway.BatchState(1000, 1000005 + 100 + 1, 1, bytes32(0))); - checkTokenState(address(0), L1BatchBridgeGateway.TokenState(13700, 3, 0)); - } - - function testDepositERC20() external { - // revert token is zero - hevm.expectRevert(L1BatchBridgeGateway.ErrorIncorrectMethodForETHDeposit.selector); - batch.depositERC20(address(0), 0); - - // revert token not supported - hevm.expectRevert(L1BatchBridgeGateway.ErrorTokenNotSupported.selector); - batch.depositERC20(address(l1Token), 0); - - // revert deposit amount too small - batch.setBatchConfig( - address(l1Token), - L1BatchBridgeGateway.BatchConfig(0, 100, 2, 100, ERC20_DEPOSIT_SAFE_GAS_LIMIT) - ); - l1Token.approve(address(batch), 10); - hevm.expectRevert(L1BatchBridgeGateway.ErrorDepositAmountTooSmall.selector); - batch.depositERC20(address(l1Token), 10); - - // no fee - batch.setBatchConfig( - address(l1Token), - L1BatchBridgeGateway.BatchConfig(0, 0, 2, 100, ERC20_DEPOSIT_SAFE_GAS_LIMIT) - ); - assertEq(0, l1Token.balanceOf(address(batch))); - checkBatchState(address(l1Token), 0, L1BatchBridgeGateway.BatchState(0, 0, 0, bytes32(0))); - checkTokenState(address(l1Token), L1BatchBridgeGateway.TokenState(0, 0, 0)); - - hevm.warp(1000001); - l1Token.approve(address(batch), 1000); - hevm.expectEmit(true, true, true, true); - emit Deposit(address(this), address(l1Token), 0, 1000, 0); - batch.depositERC20(address(l1Token), 1000); - assertEq(1000, l1Token.balanceOf(address(batch))); - checkBatchState(address(l1Token), 0, L1BatchBridgeGateway.BatchState(1000, 1000001, 1, bytes32(0))); - checkTokenState(address(l1Token), L1BatchBridgeGateway.TokenState(1000, 0, 0)); - - hevm.warp(1000002); - l1Token.approve(address(batch), 2000); - hevm.expectEmit(true, true, true, true); - emit Deposit(address(this), address(l1Token), 0, 2000, 0); - batch.depositERC20(address(l1Token), 2000); - assertEq(3000, l1Token.balanceOf(address(batch))); - checkBatchState(address(l1Token), 0, L1BatchBridgeGateway.BatchState(3000, 1000001, 2, bytes32(0))); - checkTokenState(address(l1Token), L1BatchBridgeGateway.TokenState(3000, 0, 0)); - - hevm.warp(1000003); - l1Token.approve(address(batch), 3000); - hevm.expectEmit(true, true, true, true); - emit Deposit(address(this), address(l1Token), 1, 3000, 0); - batch.depositERC20(address(l1Token), 3000); - assertEq(6000, l1Token.balanceOf(address(batch))); - checkBatchState(address(l1Token), 1, L1BatchBridgeGateway.BatchState(3000, 1000003, 1, bytes32(0))); - checkTokenState(address(l1Token), L1BatchBridgeGateway.TokenState(6000, 1, 0)); - - // with fee - batch.setBatchConfig( - address(l1Token), - L1BatchBridgeGateway.BatchConfig(100, 1000, 2, 100, ERC20_DEPOSIT_SAFE_GAS_LIMIT) - ); - - hevm.warp(1000004); - l1Token.approve(address(batch), 1000); - hevm.expectEmit(true, true, true, true); - emit Deposit(address(this), address(l1Token), 1, 1000, 100); - batch.depositERC20(address(l1Token), 1000); - assertEq(7000, l1Token.balanceOf(address(batch))); - checkBatchState(address(l1Token), 1, L1BatchBridgeGateway.BatchState(3900, 1000003, 2, bytes32(0))); - checkTokenState(address(l1Token), L1BatchBridgeGateway.TokenState(6900, 1, 0)); - - hevm.warp(1000005); - l1Token.approve(address(batch), 2000); - hevm.expectEmit(true, true, true, true); - emit Deposit(address(this), address(l1Token), 2, 2000, 100); - batch.depositERC20(address(l1Token), 2000); - assertEq(9000, l1Token.balanceOf(address(batch))); - checkBatchState(address(l1Token), 2, L1BatchBridgeGateway.BatchState(1900, 1000005, 1, bytes32(0))); - checkTokenState(address(l1Token), L1BatchBridgeGateway.TokenState(8800, 2, 0)); - - hevm.warp(1000006); - l1Token.approve(address(batch), 3000); - hevm.expectEmit(true, true, true, true); - emit Deposit(address(this), address(l1Token), 2, 3000, 100); - batch.depositERC20(address(l1Token), 3000); - assertEq(12000, l1Token.balanceOf(address(batch))); - checkBatchState(address(l1Token), 2, L1BatchBridgeGateway.BatchState(4800, 1000005, 2, bytes32(0))); - checkTokenState(address(l1Token), L1BatchBridgeGateway.TokenState(11700, 2, 0)); - - // switch phase by timestamp - batch.setBatchConfig( - address(l1Token), - L1BatchBridgeGateway.BatchConfig(0, 0, 100, 100, ERC20_DEPOSIT_SAFE_GAS_LIMIT) - ); - - l1Token.approve(address(batch), 1000); - hevm.expectEmit(true, true, true, true); - emit Deposit(address(this), address(l1Token), 2, 1000, 0); - batch.depositERC20(address(l1Token), 1000); - assertEq(13000, l1Token.balanceOf(address(batch))); - checkBatchState(address(l1Token), 2, L1BatchBridgeGateway.BatchState(5800, 1000005, 3, bytes32(0))); - checkTokenState(address(l1Token), L1BatchBridgeGateway.TokenState(12700, 2, 0)); - - hevm.warp(1000005 + 100 + 1); - l1Token.approve(address(batch), 1000); - hevm.expectEmit(true, true, true, true); - emit Deposit(address(this), address(l1Token), 3, 1000, 0); - batch.depositERC20(address(l1Token), 1000); - assertEq(14000, l1Token.balanceOf(address(batch))); - checkBatchState(address(l1Token), 3, L1BatchBridgeGateway.BatchState(1000, 1000005 + 100 + 1, 1, bytes32(0))); - checkTokenState(address(l1Token), L1BatchBridgeGateway.TokenState(13700, 3, 0)); - } - - function testBatchBridgeFailure() external { - // revert not keeper - hevm.startPrank(address(1)); - hevm.expectRevert( - "AccessControl: account 0x0000000000000000000000000000000000000001 is missing role 0xfc8737ab85eb45125971625a9ebdb75cc78e01d5c1fa80c4c6e5203f47bc4fab" - ); - batch.executeBatchDeposit(address(0)); - hevm.stopPrank(); - - batch.grantRole(batch.KEEPER_ROLE(), address(this)); - - // revert token not supported - hevm.expectRevert(L1BatchBridgeGateway.ErrorTokenNotSupported.selector); - batch.executeBatchDeposit(address(0)); - - batch.setBatchConfig(address(0), L1BatchBridgeGateway.BatchConfig(0, 0, 1, 1, ETH_DEPOSIT_SAFE_GAS_LIMIT)); - - // revert no pending - hevm.expectRevert(L1BatchBridgeGateway.ErrorNoPendingBatch.selector); - batch.executeBatchDeposit(address(0)); - - // revert insufficient msg.value - batch.depositETH{value: 1000}(); - hevm.expectRevert(L1BatchBridgeGateway.ErrorInsufficientMsgValueForBatchDepositFee.selector); - batch.executeBatchDeposit(address(0)); - - hevm.expectRevert(L1BatchBridgeGateway.ErrorInsufficientMsgValueForBatchDepositFee.selector); - batch.executeBatchDeposit{value: L2_GAS_PRICE * ETH_DEPOSIT_SAFE_GAS_LIMIT}(address(0)); - - hevm.expectRevert(L1BatchBridgeGateway.ErrorInsufficientMsgValueForBatchDepositFee.selector); - batch.executeBatchDeposit{value: L2_GAS_PRICE * (SAFE_BATCH_BRIDGE_GAS_LIMIT + ETH_DEPOSIT_SAFE_GAS_LIMIT) - 1}( - address(0) - ); - - // succeed - batch.executeBatchDeposit{value: L2_GAS_PRICE * (SAFE_BATCH_BRIDGE_GAS_LIMIT + ETH_DEPOSIT_SAFE_GAS_LIMIT)}( - address(0) - ); - } - - function testBatchBridgeETH() external { - batch.grantRole(batch.KEEPER_ROLE(), address(this)); - - // no deposit fee - batch.setBatchConfig(address(0), L1BatchBridgeGateway.BatchConfig(0, 0, 1, 1, ETH_DEPOSIT_SAFE_GAS_LIMIT)); - batch.depositETH{value: 1000}(); - checkTokenState(address(0), L1BatchBridgeGateway.TokenState(1000, 0, 0)); - - // emit SentMessage by deposit ETH - hevm.expectEmit(true, true, false, true); - emit SentMessage(address(batch), address(counterpartBatch), 1000, 0, ETH_DEPOSIT_SAFE_GAS_LIMIT, ""); - - // emit SentMessage by batchBridge - hevm.expectEmit(true, true, false, true); - emit SentMessage( - address(batch), - address(counterpartBatch), - 0, - 1, - SAFE_BATCH_BRIDGE_GAS_LIMIT, - abi.encodeCall( - L2BatchBridgeGateway.finalizeBatchDeposit, - ( - address(0), - address(0), - 0, - BatchBridgeCodec.hash( - BatchBridgeCodec.encodeInitialNode(address(0), 0), - BatchBridgeCodec.encodeNode(address(this), 1000) - ) - ) - ) - ); - - // emit BatchBridge - hevm.expectEmit(true, true, true, true); - emit BatchDeposit(address(this), address(0), 0, address(0)); - - uint256 batchFeeVaultBefore = batchFeeVault.balance; - uint256 messengerBefore = address(l1Messenger).balance; - batch.executeBatchDeposit{value: 1 ether}(address(0)); - checkTokenState(address(0), L1BatchBridgeGateway.TokenState(0, 1, 1)); - assertEq(batchFeeVaultBefore, batchFeeVault.balance); - assertEq(messengerBefore + 1000, address(l1Messenger).balance); - - // has deposit fee = 100 - batch.setBatchConfig(address(0), L1BatchBridgeGateway.BatchConfig(100, 1000, 1, 1, ETH_DEPOSIT_SAFE_GAS_LIMIT)); - - batch.depositETH{value: 1000}(); - checkTokenState(address(0), L1BatchBridgeGateway.TokenState(900, 1, 1)); - - // emit SentMessage by deposit ETH - hevm.expectEmit(true, true, false, true); - emit SentMessage(address(batch), address(counterpartBatch), 900, 2, ETH_DEPOSIT_SAFE_GAS_LIMIT, ""); - - // emit SentMessage by batchBridge - hevm.expectEmit(true, true, false, true); - emit SentMessage( - address(batch), - address(counterpartBatch), - 0, - 3, - SAFE_BATCH_BRIDGE_GAS_LIMIT, - abi.encodeCall( - L2BatchBridgeGateway.finalizeBatchDeposit, - ( - address(0), - address(0), - 1, - BatchBridgeCodec.hash( - BatchBridgeCodec.encodeInitialNode(address(0), 1), - BatchBridgeCodec.encodeNode(address(this), 900) - ) - ) - ) - ); - - // emit BatchBridge - hevm.expectEmit(true, true, true, true); - emit BatchDeposit(address(this), address(0), 1, address(0)); - - batchFeeVaultBefore = batchFeeVault.balance; - messengerBefore = address(l1Messenger).balance; - batch.executeBatchDeposit{value: 1 ether}(address(0)); - checkTokenState(address(0), L1BatchBridgeGateway.TokenState(0, 2, 2)); - assertEq(batchFeeVaultBefore + 100, batchFeeVault.balance); - assertEq(messengerBefore + 900, address(l1Messenger).balance); - } - - function testBatchBridgeERC20() external { - batch.grantRole(batch.KEEPER_ROLE(), address(this)); - - // no deposit fee - batch.setBatchConfig( - address(l1Token), - L1BatchBridgeGateway.BatchConfig(0, 0, 1, 1, ERC20_DEPOSIT_SAFE_GAS_LIMIT) - ); - l1Token.approve(address(batch), 1000); - batch.depositERC20(address(l1Token), 1000); - checkTokenState(address(l1Token), L1BatchBridgeGateway.TokenState(1000, 0, 0)); - - bytes memory message = abi.encodeWithSelector( - IL2ERC20Gateway.finalizeDepositERC20.selector, - address(l1Token), - address(l2Token), - address(batch), - address(counterpartBatch), - 1000, - new bytes(0) - ); - // emit SentMessage by deposit ERC20 - hevm.expectEmit(true, true, false, true); - emit SentMessage(address(gateway), address(counterpartGateway), 0, 0, ERC20_DEPOSIT_SAFE_GAS_LIMIT, message); - // emit SentMessage by batchBridge - hevm.expectEmit(true, true, false, true); - emit SentMessage( - address(batch), - address(counterpartBatch), - 0, - 1, - SAFE_BATCH_BRIDGE_GAS_LIMIT, - abi.encodeCall( - L2BatchBridgeGateway.finalizeBatchDeposit, - ( - address(l1Token), - address(l2Token), - 0, - BatchBridgeCodec.hash( - BatchBridgeCodec.encodeInitialNode(address(l1Token), 0), - BatchBridgeCodec.encodeNode(address(this), 1000) - ) - ) - ) - ); - // emit BatchBridge - hevm.expectEmit(true, true, true, true); - emit BatchDeposit(address(this), address(l1Token), 0, address(l2Token)); - - uint256 batchFeeVaultBefore = l1Token.balanceOf(batchFeeVault); - uint256 gatewayBefore = l1Token.balanceOf(address(gateway)); - batch.executeBatchDeposit{value: 1 ether}(address(l1Token)); - checkTokenState(address(l1Token), L1BatchBridgeGateway.TokenState(0, 1, 1)); - assertEq(batchFeeVaultBefore, l1Token.balanceOf(batchFeeVault)); - assertEq(gatewayBefore + 1000, l1Token.balanceOf(address(gateway))); - - // has deposit fee = 100 - batch.setBatchConfig( - address(l1Token), - L1BatchBridgeGateway.BatchConfig(100, 1000, 1, 1, ERC20_DEPOSIT_SAFE_GAS_LIMIT) - ); - - l1Token.approve(address(batch), 1000); - batch.depositERC20(address(l1Token), 1000); - checkTokenState(address(l1Token), L1BatchBridgeGateway.TokenState(900, 1, 1)); - - message = abi.encodeWithSelector( - IL2ERC20Gateway.finalizeDepositERC20.selector, - address(l1Token), - address(l2Token), - address(batch), - address(counterpartBatch), - 900, - new bytes(0) - ); - // emit SentMessage by deposit ERC20 - hevm.expectEmit(true, true, false, true); - emit SentMessage(address(gateway), address(counterpartGateway), 0, 2, ERC20_DEPOSIT_SAFE_GAS_LIMIT, message); - // emit SentMessage by batchBridge - hevm.expectEmit(true, true, false, true); - emit SentMessage( - address(batch), - address(counterpartBatch), - 0, - 3, - SAFE_BATCH_BRIDGE_GAS_LIMIT, - abi.encodeCall( - L2BatchBridgeGateway.finalizeBatchDeposit, - ( - address(l1Token), - address(l2Token), - 1, - BatchBridgeCodec.hash( - BatchBridgeCodec.encodeInitialNode(address(l1Token), 1), - BatchBridgeCodec.encodeNode(address(this), 900) - ) - ) - ) - ); - // emit BatchBridge - hevm.expectEmit(true, true, true, true); - emit BatchDeposit(address(this), address(l1Token), 1, address(l2Token)); - - batchFeeVaultBefore = l1Token.balanceOf(batchFeeVault); - gatewayBefore = l1Token.balanceOf(address(gateway)); - batch.executeBatchDeposit{value: 1 ether}(address(l1Token)); - checkTokenState(address(l1Token), L1BatchBridgeGateway.TokenState(0, 2, 2)); - assertEq(batchFeeVaultBefore + 100, l1Token.balanceOf(batchFeeVault)); - assertEq(gatewayBefore + 900, l1Token.balanceOf(address(gateway))); - } -} diff --git a/contracts/src/test/batch-bridge/L2BatchBridgeGateway.t.sol b/contracts/src/test/batch-bridge/L2BatchBridgeGateway.t.sol deleted file mode 100644 index b30e1148d..000000000 --- a/contracts/src/test/batch-bridge/L2BatchBridgeGateway.t.sol +++ /dev/null @@ -1,454 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {MockERC20} from "solmate/test/utils/mocks/MockERC20.sol"; - -import {ITransparentUpgradeableProxy} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; -import {Strings} from "@openzeppelin/contracts/utils/Strings.sol"; - -import {L1BatchBridgeGateway} from "../../batch-bridge/L1BatchBridgeGateway.sol"; -import {L2BatchBridgeGateway} from "../../batch-bridge/L2BatchBridgeGateway.sol"; -import {BatchBridgeCodec} from "../../batch-bridge/BatchBridgeCodec.sol"; - -import {RevertOnTransferToken} from "../mocks/tokens/RevertOnTransferToken.sol"; -import {MockScrollMessenger} from "../mocks/MockScrollMessenger.sol"; -import {ScrollTestBase} from "../ScrollTestBase.t.sol"; - -contract L2BatchBridgeGatewayTest is ScrollTestBase { - event UpdateTokenMapping(address indexed l2Token, address indexed oldL1Token, address indexed newL1Token); - event FinalizeBatchDeposit(address indexed l1Token, address indexed l2Token, uint256 indexed batchIndex); - event BatchDistribute(address indexed l1Token, address indexed l2Token, uint256 indexed batchIndex); - event DistributeFailed(address indexed l2Token, uint256 indexed batchIndex, address receiver, uint256 amount); - - L1BatchBridgeGateway private counterpartBatch; - L2BatchBridgeGateway private batch; - - MockScrollMessenger messenger; - - MockERC20 private l1Token; - MockERC20 private l2Token; - RevertOnTransferToken private maliciousL2Token; - - bool revertOnReceive; - bool loopOnReceive; - - // two safe EOAs to receive ETH - address private recipient1; - address private recipient2; - - receive() external payable { - if (revertOnReceive) revert(); - if (loopOnReceive) { - for (uint256 i = 0; i < 1000000000; i++) { - recipient1 = address(uint160(address(this)) - 1); - } - } - } - - function setUp() public { - __ScrollTestBase_setUp(); - - recipient1 = address(uint160(address(this)) - 1); - recipient2 = address(uint160(address(this)) - 2); - - // Deploy tokens - l1Token = new MockERC20("Mock L1", "ML1", 18); - l2Token = new MockERC20("Mock L2", "ML2", 18); - maliciousL2Token = new RevertOnTransferToken("X", "Y", 18); - - messenger = new MockScrollMessenger(); - counterpartBatch = new L1BatchBridgeGateway(address(1), address(1), address(1), address(1)); - batch = L2BatchBridgeGateway(payable(_deployProxy(address(0)))); - - // Initialize L2 contracts - admin.upgrade( - ITransparentUpgradeableProxy(address(batch)), - address(new L2BatchBridgeGateway(address(counterpartBatch), address(messenger))) - ); - batch.initialize(); - } - - function testInitialized() external { - assertBoolEq(true, batch.hasRole(bytes32(0), address(this))); - assertEq(address(counterpartBatch), batch.counterpart()); - assertEq(address(messenger), batch.messenger()); - - hevm.expectRevert("Initializable: contract is already initialized"); - batch.initialize(); - } - - function testFinalizeBatchDeposit() external { - // revert caller not messenger - hevm.expectRevert(L2BatchBridgeGateway.ErrorCallerNotMessenger.selector); - batch.finalizeBatchDeposit(address(0), address(0), 0, bytes32(0)); - - // revert xDomainMessageSender not counterpart - hevm.expectRevert(L2BatchBridgeGateway.ErrorMessageSenderNotCounterpart.selector); - messenger.callTarget( - address(batch), - abi.encodeCall( - L2BatchBridgeGateway.finalizeBatchDeposit, - (address(l1Token), address(l2Token), 0, bytes32(0)) - ) - ); - - messenger.setXDomainMessageSender(address(counterpartBatch)); - - // emit FinalizeBatchDeposit - assertEq(address(0), batch.tokenMapping(address(l2Token))); - hevm.expectEmit(true, true, true, true); - emit FinalizeBatchDeposit(address(l1Token), address(l2Token), 1); - messenger.callTarget( - address(batch), - abi.encodeCall( - L2BatchBridgeGateway.finalizeBatchDeposit, - (address(l1Token), address(l2Token), 1, bytes32(uint256(1))) - ) - ); - assertEq(address(l1Token), batch.tokenMapping(address(l2Token))); - assertEq(batch.batchHashes(address(l2Token), 1), bytes32(uint256(1))); - - // revert token not match - hevm.expectRevert(L2BatchBridgeGateway.ErrorL1TokenMismatched.selector); - messenger.callTarget( - address(batch), - abi.encodeCall(L2BatchBridgeGateway.finalizeBatchDeposit, (address(0), address(l2Token), 0, bytes32(0))) - ); - } - - function testFinalizeBatchDepositFuzzing( - address token1, - address token2, - uint256 batchIndex, - bytes32 hash - ) external { - messenger.setXDomainMessageSender(address(counterpartBatch)); - - assertEq(address(0), batch.tokenMapping(token2)); - hevm.expectEmit(true, true, true, true); - emit FinalizeBatchDeposit(token1, token2, batchIndex); - messenger.callTarget( - address(batch), - abi.encodeCall(L2BatchBridgeGateway.finalizeBatchDeposit, (token1, token2, batchIndex, hash)) - ); - - assertEq(token1, batch.tokenMapping(token2)); - assertEq(batch.batchHashes(token2, batchIndex), hash); - } - - function testDistributeETH() external { - // revert not keeper - hevm.startPrank(address(1)); - hevm.expectRevert( - "AccessControl: account 0x0000000000000000000000000000000000000001 is missing role 0xfc8737ab85eb45125971625a9ebdb75cc78e01d5c1fa80c4c6e5203f47bc4fab" - ); - batch.distribute(address(0), 0, new bytes32[](0)); - hevm.stopPrank(); - - batch.grantRole(batch.KEEPER_ROLE(), address(this)); - - // revert ErrorBatchHashMismatch - hevm.expectRevert(L2BatchBridgeGateway.ErrorBatchHashMismatch.selector); - batch.distribute(address(0), 1, new bytes32[](0)); - - // send some ETH to `L2BatchBridgeGateway`. - messenger.setXDomainMessageSender(address(counterpartBatch)); - messenger.callTarget{value: 1 ether}(address(batch), ""); - - address[] memory receivers = new address[](2); - uint256[] memory amounts = new uint256[](2); - receivers[0] = recipient1; - receivers[1] = recipient2; - amounts[0] = 100; - amounts[1] = 200; - - // all success - (bytes32[] memory nodes, bytes32 batchHash) = _encodeNodes(address(0), 0, receivers, amounts); - messenger.callTarget( - address(batch), - abi.encodeCall(L2BatchBridgeGateway.finalizeBatchDeposit, (address(0), address(0), 0, batchHash)) - ); - assertEq(0, recipient1.balance); - assertEq(0, recipient2.balance); - uint256 batchBalanceBefore = address(batch).balance; - hevm.expectEmit(true, true, true, true); - emit BatchDistribute(address(0), address(0), 0); - batch.distribute(address(0), 0, nodes); - assertEq(100, recipient1.balance); - assertEq(200, recipient2.balance); - assertEq(batchBalanceBefore - 300, address(batch).balance); - assertBoolEq(true, batch.isDistributed(batchHash)); - - // revert ErrorBatchDistributed - hevm.expectRevert(L2BatchBridgeGateway.ErrorBatchDistributed.selector); - batch.distribute(address(0), 0, nodes); - - // all failed due to revert - revertOnReceive = true; - loopOnReceive = false; - receivers[0] = address(this); - receivers[1] = address(this); - (nodes, batchHash) = _encodeNodes(address(0), 1, receivers, amounts); - messenger.callTarget( - address(batch), - abi.encodeCall(L2BatchBridgeGateway.finalizeBatchDeposit, (address(0), address(0), 1, batchHash)) - ); - uint256 thisBalanceBefore = address(this).balance; - batchBalanceBefore = address(batch).balance; - hevm.expectEmit(true, true, false, true); - emit DistributeFailed(address(0), 1, address(this), 100); - hevm.expectEmit(true, true, false, true); - emit DistributeFailed(address(0), 1, address(this), 200); - hevm.expectEmit(true, true, true, true); - emit BatchDistribute(address(0), address(0), 1); - batch.distribute(address(0), 1, nodes); - assertEq(batchBalanceBefore, address(batch).balance); - assertEq(thisBalanceBefore, address(this).balance); - assertBoolEq(true, batch.isDistributed(batchHash)); - assertEq(300, batch.failedAmount(address(0))); - - // all failed due to out of gas - revertOnReceive = false; - loopOnReceive = true; - (nodes, batchHash) = _encodeNodes(address(0), 2, receivers, amounts); - messenger.callTarget( - address(batch), - abi.encodeCall(L2BatchBridgeGateway.finalizeBatchDeposit, (address(0), address(0), 2, batchHash)) - ); - thisBalanceBefore = address(this).balance; - batchBalanceBefore = address(batch).balance; - hevm.expectEmit(true, true, false, true); - emit DistributeFailed(address(0), 2, address(this), 100); - hevm.expectEmit(true, true, false, true); - emit DistributeFailed(address(0), 2, address(this), 200); - hevm.expectEmit(true, true, true, true); - emit BatchDistribute(address(0), address(0), 2); - batch.distribute(address(0), 2, nodes); - assertEq(batchBalanceBefore, address(batch).balance); - assertEq(thisBalanceBefore, address(this).balance); - assertBoolEq(true, batch.isDistributed(batchHash)); - assertEq(600, batch.failedAmount(address(0))); - } - - function testDistributeERC20() external { - // revert not keeper - hevm.startPrank(address(1)); - hevm.expectRevert( - "AccessControl: account 0x0000000000000000000000000000000000000001 is missing role 0xfc8737ab85eb45125971625a9ebdb75cc78e01d5c1fa80c4c6e5203f47bc4fab" - ); - batch.distribute(address(l2Token), 0, new bytes32[](0)); - hevm.stopPrank(); - - batch.grantRole(batch.KEEPER_ROLE(), address(this)); - - // revert ErrorBatchHashMismatch - hevm.expectRevert(L2BatchBridgeGateway.ErrorBatchHashMismatch.selector); - batch.distribute(address(l2Token), 1, new bytes32[](0)); - - // mint some ERC20 to `L2BatchBridgeGateway`. - messenger.setXDomainMessageSender(address(counterpartBatch)); - l2Token.mint(address(batch), 1 ether); - - address[] memory receivers = new address[](2); - uint256[] memory amounts = new uint256[](2); - receivers[0] = recipient1; - receivers[1] = recipient2; - amounts[0] = 100; - amounts[1] = 200; - - // all success - (bytes32[] memory nodes, bytes32 batchHash) = _encodeNodes(address(l1Token), 0, receivers, amounts); - messenger.callTarget( - address(batch), - abi.encodeCall( - L2BatchBridgeGateway.finalizeBatchDeposit, - (address(l1Token), address(l2Token), 0, batchHash) - ) - ); - assertEq(0, recipient1.balance); - assertEq(0, recipient2.balance); - uint256 batchBalanceBefore = l2Token.balanceOf(address(batch)); - hevm.expectEmit(true, true, true, true); - emit BatchDistribute(address(l1Token), address(l2Token), 0); - batch.distribute(address(l2Token), 0, nodes); - assertEq(100, l2Token.balanceOf(recipient1)); - assertEq(200, l2Token.balanceOf(recipient2)); - assertEq(batchBalanceBefore - 300, l2Token.balanceOf(address(batch))); - assertBoolEq(true, batch.isDistributed(batchHash)); - - // revert ErrorBatchDistributed - hevm.expectRevert(L2BatchBridgeGateway.ErrorBatchDistributed.selector); - batch.distribute(address(l2Token), 0, nodes); - - maliciousL2Token.mint(address(batch), 1 ether); - - // all failed due to revert - maliciousL2Token.setRevertOnTransfer(true); - receivers[0] = address(this); - receivers[1] = address(this); - (nodes, batchHash) = _encodeNodes(address(l1Token), 1, receivers, amounts); - messenger.callTarget( - address(batch), - abi.encodeCall( - L2BatchBridgeGateway.finalizeBatchDeposit, - (address(l1Token), address(maliciousL2Token), 1, batchHash) - ) - ); - uint256 thisBalanceBefore = maliciousL2Token.balanceOf(address(this)); - batchBalanceBefore = maliciousL2Token.balanceOf(address(batch)); - hevm.expectEmit(true, true, false, true); - emit DistributeFailed(address(maliciousL2Token), 1, address(this), 100); - hevm.expectEmit(true, true, false, true); - emit DistributeFailed(address(maliciousL2Token), 1, address(this), 200); - hevm.expectEmit(true, true, true, true); - emit BatchDistribute(address(l1Token), address(maliciousL2Token), 1); - batch.distribute(address(maliciousL2Token), 1, nodes); - assertEq(batchBalanceBefore, maliciousL2Token.balanceOf(address(batch))); - assertEq(thisBalanceBefore, maliciousL2Token.balanceOf(address(this))); - assertBoolEq(true, batch.isDistributed(batchHash)); - assertEq(300, batch.failedAmount(address(maliciousL2Token))); - - // all failed due to transfer return false - maliciousL2Token.setRevertOnTransfer(false); - maliciousL2Token.setTransferReturn(false); - (nodes, batchHash) = _encodeNodes(address(l1Token), 2, receivers, amounts); - messenger.callTarget( - address(batch), - abi.encodeCall( - L2BatchBridgeGateway.finalizeBatchDeposit, - (address(l1Token), address(maliciousL2Token), 2, batchHash) - ) - ); - thisBalanceBefore = maliciousL2Token.balanceOf(address(this)); - batchBalanceBefore = maliciousL2Token.balanceOf(address(batch)); - hevm.expectEmit(true, true, false, true); - emit DistributeFailed(address(maliciousL2Token), 2, address(this), 100); - hevm.expectEmit(true, true, false, true); - emit DistributeFailed(address(maliciousL2Token), 2, address(this), 200); - hevm.expectEmit(true, true, true, true); - emit BatchDistribute(address(l1Token), address(maliciousL2Token), 2); - batch.distribute(address(maliciousL2Token), 2, nodes); - assertEq(batchBalanceBefore, maliciousL2Token.balanceOf(address(batch))); - assertEq(thisBalanceBefore, maliciousL2Token.balanceOf(address(this))); - assertBoolEq(true, batch.isDistributed(batchHash)); - assertEq(600, batch.failedAmount(address(maliciousL2Token))); - } - - function testWithdrawFailedAmountETH() external { - batch.grantRole(batch.KEEPER_ROLE(), address(this)); - - // revert not admin - hevm.startPrank(address(1)); - hevm.expectRevert( - "AccessControl: account 0x0000000000000000000000000000000000000001 is missing role 0x0000000000000000000000000000000000000000000000000000000000000000" - ); - batch.withdrawFailedAmount(address(0), address(this)); - hevm.stopPrank(); - - // revert no failed - hevm.expectRevert(L2BatchBridgeGateway.ErrorNoFailedDistribution.selector); - batch.withdrawFailedAmount(address(0), address(this)); - - // send some ETH to `L2BatchBridgeGateway`. - messenger.setXDomainMessageSender(address(counterpartBatch)); - messenger.callTarget{value: 1 ether}(address(batch), ""); - - // make a failed distribution - address[] memory receivers = new address[](2); - uint256[] memory amounts = new uint256[](2); - receivers[0] = address(this); - receivers[1] = address(this); - amounts[0] = 100; - amounts[1] = 200; - revertOnReceive = true; - (bytes32[] memory nodes, bytes32 batchHash) = _encodeNodes(address(0), 1, receivers, amounts); - messenger.callTarget( - address(batch), - abi.encodeCall(L2BatchBridgeGateway.finalizeBatchDeposit, (address(0), address(0), 1, batchHash)) - ); - assertEq(0, batch.failedAmount(address(0))); - batch.distribute(address(0), 1, nodes); - assertEq(300, batch.failedAmount(address(0))); - - // withdraw failed - uint256 thisBalance = recipient1.balance; - uint256 batchBalance = address(batch).balance; - batch.withdrawFailedAmount(address(0), recipient1); - assertEq(0, batch.failedAmount(address(0))); - assertEq(thisBalance + 300, recipient1.balance); - assertEq(batchBalance - 300, address(batch).balance); - - // revert no failed - hevm.expectRevert(L2BatchBridgeGateway.ErrorNoFailedDistribution.selector); - batch.withdrawFailedAmount(address(0), recipient1); - } - - function testWithdrawFailedAmountERC20() external { - batch.grantRole(batch.KEEPER_ROLE(), address(this)); - - // revert not admin - hevm.startPrank(address(1)); - hevm.expectRevert( - "AccessControl: account 0x0000000000000000000000000000000000000001 is missing role 0x0000000000000000000000000000000000000000000000000000000000000000" - ); - batch.withdrawFailedAmount(address(0), address(this)); - hevm.stopPrank(); - - // revert no failed - hevm.expectRevert(L2BatchBridgeGateway.ErrorNoFailedDistribution.selector); - batch.withdrawFailedAmount(address(0), address(this)); - - // send some ETH to `L2BatchBridgeGateway`. - messenger.setXDomainMessageSender(address(counterpartBatch)); - maliciousL2Token.mint(address(batch), 1 ether); - - // make a failed distribution - address[] memory receivers = new address[](2); - uint256[] memory amounts = new uint256[](2); - receivers[0] = address(this); - receivers[1] = address(this); - amounts[0] = 100; - amounts[1] = 200; - maliciousL2Token.setRevertOnTransfer(true); - (bytes32[] memory nodes, bytes32 batchHash) = _encodeNodes(address(l1Token), 1, receivers, amounts); - messenger.callTarget( - address(batch), - abi.encodeCall( - L2BatchBridgeGateway.finalizeBatchDeposit, - (address(l1Token), address(maliciousL2Token), 1, batchHash) - ) - ); - assertEq(0, batch.failedAmount(address(maliciousL2Token))); - batch.distribute(address(maliciousL2Token), 1, nodes); - assertEq(300, batch.failedAmount(address(maliciousL2Token))); - - // withdraw failed - maliciousL2Token.setRevertOnTransfer(false); - maliciousL2Token.setTransferReturn(true); - uint256 thisBalance = maliciousL2Token.balanceOf(recipient1); - uint256 batchBalance = maliciousL2Token.balanceOf(address(batch)); - batch.withdrawFailedAmount(address(maliciousL2Token), recipient1); - assertEq(0, batch.failedAmount(address(maliciousL2Token))); - assertEq(thisBalance + 300, maliciousL2Token.balanceOf(recipient1)); - assertEq(batchBalance - 300, maliciousL2Token.balanceOf(address(batch))); - - // revert no failed - hevm.expectRevert(L2BatchBridgeGateway.ErrorNoFailedDistribution.selector); - batch.withdrawFailedAmount(address(maliciousL2Token), recipient1); - } - - function _encodeNodes( - address token, - uint256 batchIndex, - address[] memory receivers, - uint256[] memory amounts - ) private returns (bytes32[] memory nodes, bytes32 hash) { - nodes = new bytes32[](receivers.length); - hash = BatchBridgeCodec.encodeInitialNode(token, uint64(batchIndex)); - for (uint256 i = 0; i < receivers.length; i++) { - nodes[i] = BatchBridgeCodec.encodeNode(receivers[i], uint96(amounts[i])); - hash = BatchBridgeCodec.hash(hash, nodes[i]); - } - } -} diff --git a/contracts/src/test/integration/Domain.t.sol b/contracts/src/test/integration/Domain.t.sol deleted file mode 100644 index b5e81cde4..000000000 --- a/contracts/src/test/integration/Domain.t.sol +++ /dev/null @@ -1,40 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-or-later -pragma solidity >=0.8.0; - -import {console2} from "forge-std/console2.sol"; -import {StdChains} from "forge-std/StdChains.sol"; -import {Vm} from "forge-std/Vm.sol"; - -// code from: https://github.com/marsfoundation/xchain-helpers/blob/master/src/testing/Domain.sol - -contract Domain { - // solhint-disable-next-line const-name-snakecase - Vm internal constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code"))))); - - StdChains.Chain private _details; - uint256 public forkId; - - constructor(StdChains.Chain memory _chain) { - _details = _chain; - forkId = vm.createFork(_chain.rpcUrl); - vm.makePersistent(address(this)); - } - - function details() public view returns (StdChains.Chain memory) { - return _details; - } - - function selectFork() public { - vm.selectFork(forkId); - require( - block.chainid == _details.chainId, - string( - abi.encodePacked(_details.chainAlias, " is pointing to the wrong RPC endpoint '", _details.rpcUrl, "'") - ) - ); - } - - function rollFork(uint256 blocknum) public { - vm.rollFork(forkId, blocknum); - } -} diff --git a/contracts/src/test/integration/GatewayIntegrationBase.t.sol b/contracts/src/test/integration/GatewayIntegrationBase.t.sol deleted file mode 100644 index 41fa99f76..000000000 --- a/contracts/src/test/integration/GatewayIntegrationBase.t.sol +++ /dev/null @@ -1,129 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {Test} from "forge-std/Test.sol"; -import {Vm} from "forge-std/Vm.sol"; - -import {ProxyAdmin} from "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol"; -import {ITransparentUpgradeableProxy} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; - -import {Domain} from "./Domain.t.sol"; - -import {IL2ScrollMessenger} from "../../L2/IL2ScrollMessenger.sol"; -import {AddressAliasHelper} from "../../libraries/common/AddressAliasHelper.sol"; - -abstract contract GatewayIntegrationBase is Test { - bytes32 private constant SENT_MESSAGE_TOPIC = - keccak256("SentMessage(address,address,uint256,uint256,uint256,bytes)"); - - address internal constant L1_SCROLL_MESSENGER = 0x6774Bcbd5ceCeF1336b5300fb5186a12DDD8b367; - - address internal constant L1_SCROLL_CHAIN = 0xa13BAF47339d63B743e7Da8741db5456DAc1E556; - - address internal constant L1_MESSAGE_QUEUE = 0x0d7E906BD9cAFa154b048cFa766Cc1E54E39AF9B; - - address internal constant L1_GATEWAY_ROUTER = 0xF8B1378579659D8F7EE5f3C929c2f3E332E41Fd6; - - address internal constant L2_SCROLL_MESSENGER = 0x781e90f1c8Fc4611c9b7497C3B47F99Ef6969CbC; - - address internal constant L2_MESSAGE_QUEUE = 0x5300000000000000000000000000000000000000; - - address internal constant L2_GATEWAY_ROUTER = 0x4C0926FF5252A435FD19e10ED15e5a249Ba19d79; - - Domain internal mainnet; - - Domain internal scroll; - - uint256 internal lastFromMainnetLogIndex; - - uint256 internal lastFromScrollLogIndex; - - receive() external payable {} - - // solhint-disable-next-line func-name-mixedcase - function __GatewayIntegrationBase_setUp() internal { - setChain("scroll", ChainData("Scroll Chain", 534352, "https://rpc.scroll.io")); - setChain("mainnet", ChainData("Mainnet", 1, "https://rpc.ankr.com/eth")); - - mainnet = new Domain(getChain("mainnet")); - scroll = new Domain(getChain("scroll")); - } - - function relayFromMainnet() internal { - scroll.selectFork(); - - address malias = AddressAliasHelper.applyL1ToL2Alias(L1_SCROLL_MESSENGER); - - // Read all L1 -> L2 messages and relay them under Scroll fork - Vm.Log[] memory allLogs = vm.getRecordedLogs(); - for (; lastFromMainnetLogIndex < allLogs.length; lastFromMainnetLogIndex++) { - Vm.Log memory _log = allLogs[lastFromMainnetLogIndex]; - if (_log.topics[0] == SENT_MESSAGE_TOPIC && _log.emitter == address(L1_SCROLL_MESSENGER)) { - address sender = address(uint160(uint256(_log.topics[1]))); - address target = address(uint160(uint256(_log.topics[2]))); - (uint256 value, uint256 nonce, uint256 gasLimit, bytes memory message) = abi.decode( - _log.data, - (uint256, uint256, uint256, bytes) - ); - vm.prank(malias); - IL2ScrollMessenger(L2_SCROLL_MESSENGER).relayMessage{gas: gasLimit}( - sender, - target, - value, - nonce, - message - ); - } - } - } - - function relayFromScroll() internal { - mainnet.selectFork(); - - // Read all L2 -> L1 messages and relay them under Primary fork - // Note: We bypass the L1 messenger relay here because it's easier to not have to generate valid state roots / merkle proofs - Vm.Log[] memory allLogs = vm.getRecordedLogs(); - for (; lastFromScrollLogIndex < allLogs.length; lastFromScrollLogIndex++) { - Vm.Log memory _log = allLogs[lastFromScrollLogIndex]; - if (_log.topics[0] == SENT_MESSAGE_TOPIC && _log.emitter == address(L2_SCROLL_MESSENGER)) { - address sender = address(uint160(uint256(_log.topics[1]))); - address target = address(uint160(uint256(_log.topics[2]))); - (uint256 value, , , bytes memory message) = abi.decode(_log.data, (uint256, uint256, uint256, bytes)); - // Set xDomainMessageSender - vm.store(address(L1_SCROLL_MESSENGER), bytes32(uint256(201)), bytes32(uint256(uint160(sender)))); - vm.startPrank(address(L1_SCROLL_MESSENGER)); - (bool success, bytes memory response) = target.call{value: value}(message); - vm.stopPrank(); - vm.store(address(L1_SCROLL_MESSENGER), bytes32(uint256(201)), bytes32(uint256(1))); - if (!success) { - assembly { - revert(add(response, 32), mload(response)) - } - } - } - } - } - - function upgrade( - bool isMainnet, - address proxy, - address implementation - ) internal { - address admin; - address owner; - if (isMainnet) { - mainnet.selectFork(); - admin = 0xEB803eb3F501998126bf37bB823646Ed3D59d072; - owner = 0x798576400F7D662961BA15C6b3F3d813447a26a6; - } else { - scroll.selectFork(); - admin = 0xA76acF000C890b0DD7AEEf57627d9899F955d026; - owner = 0x13D24a7Ff6F5ec5ff0e9C40Fc3B8C9c01c65437B; - } - - vm.startPrank(owner); - ProxyAdmin(admin).upgrade(ITransparentUpgradeableProxy(proxy), implementation); - vm.stopPrank(); - } -} diff --git a/contracts/src/test/integration/LidoGatewayIntegration.t.sol b/contracts/src/test/integration/LidoGatewayIntegration.t.sol deleted file mode 100644 index 7710f2874..000000000 --- a/contracts/src/test/integration/LidoGatewayIntegration.t.sol +++ /dev/null @@ -1,122 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {MockERC20} from "solmate/test/utils/mocks/MockERC20.sol"; - -import {GatewayIntegrationBase} from "./GatewayIntegrationBase.t.sol"; - -import {IL1ERC20Gateway} from "../../L1/gateways/IL1ERC20Gateway.sol"; -import {IL2ERC20Gateway} from "../../L2/gateways/IL2ERC20Gateway.sol"; -import {L1LidoGateway} from "../../lido/L1LidoGateway.sol"; -import {L2LidoGateway} from "../../lido/L2LidoGateway.sol"; - -interface IWstETH { - function wrap(uint256 _stETHAmount) external returns (uint256); - - function unwrap(uint256 _wstETHAmount) external returns (uint256); - - function getStETHByWstETH(uint256 _wstETHAmount) external view returns (uint256); - - function getWstETHByStETH(uint256 _stETHAmount) external view returns (uint256); - - function stEthPerToken() external view returns (uint256); - - function tokensPerStEth() external view returns (uint256); -} - -contract LidoGatewayIntegrationTest is GatewayIntegrationBase { - address private constant L1_LIDO_GATEWAY = 0x6625C6332c9F91F2D27c304E729B86db87A3f504; - - address private constant L1_STETH = 0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84; - - address private constant L1_WSTETH = 0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0; - - address private constant L2_LIDO_GATEWAY = 0x8aE8f22226B9d789A36AC81474e633f8bE2856c9; - - address private constant L2_WSTETH = 0xf610A9dfB7C89644979b4A0f27063E9e7d7Cda32; - - function setUp() public { - __GatewayIntegrationBase_setUp(); - - mainnet.selectFork(); - upgrade( - true, - L1_LIDO_GATEWAY, - address(new L1LidoGateway(L1_WSTETH, L2_WSTETH, L2_LIDO_GATEWAY, L1_GATEWAY_ROUTER, L1_SCROLL_MESSENGER)) - ); - L1LidoGateway(L1_LIDO_GATEWAY).initializeV2(address(0), address(0), address(0), address(0)); - - scroll.selectFork(); - upgrade( - false, - L2_LIDO_GATEWAY, - address(new L2LidoGateway(L1_WSTETH, L2_WSTETH, L1_LIDO_GATEWAY, L2_GATEWAY_ROUTER, L2_SCROLL_MESSENGER)) - ); - L2LidoGateway(L2_LIDO_GATEWAY).initializeV2(address(0), address(0), address(0), address(0)); - } - - function testWithoutRouter() private { - depositAndWithdraw(false); - } - - function testWithRouter() private { - depositAndWithdraw(true); - } - - function depositAndWithdraw(bool useRouter) private { - vm.recordLogs(); - - mainnet.selectFork(); - uint256 rate = IWstETH(L1_WSTETH).stEthPerToken(); - - // deposit to get some stETH - (bool succeed, ) = L1_STETH.call{value: 11 * rate}(""); - assertEq(true, succeed); - assertApproxEqAbs(MockERC20(L1_STETH).balanceOf(address(this)), 11 * rate, 10); - - // wrap stETH to wstETH - MockERC20(L1_STETH).approve(L1_WSTETH, 10 * rate); - IWstETH(L1_WSTETH).wrap(10 * rate); - assertApproxEqAbs(MockERC20(L1_WSTETH).balanceOf(address(this)), 10 ether, 10); - - // deposit 1 wstETH - uint256 l1GatewayBalance = MockERC20(L1_WSTETH).balanceOf(L1_LIDO_GATEWAY); - uint256 l1Balance = MockERC20(L1_WSTETH).balanceOf(address(this)); - if (useRouter) { - MockERC20(L1_WSTETH).approve(L1_GATEWAY_ROUTER, 1 ether); - IL1ERC20Gateway(L1_GATEWAY_ROUTER).depositERC20{value: 1 ether}(L1_WSTETH, 1 ether, 400000); - } else { - MockERC20(L1_WSTETH).approve(L1_LIDO_GATEWAY, 1 ether); - IL1ERC20Gateway(L1_LIDO_GATEWAY).depositERC20{value: 1 ether}(L1_WSTETH, 1 ether, 400000); - } - assertEq(l1Balance - 1 ether, MockERC20(L1_WSTETH).balanceOf(address(this))); - assertEq(l1GatewayBalance + 1 ether, MockERC20(L1_WSTETH).balanceOf(L1_LIDO_GATEWAY)); - - // relay message to Scroll and check balance - scroll.selectFork(); - uint256 l2Balance = MockERC20(L2_WSTETH).balanceOf(address(this)); - relayFromMainnet(); - - // withdraw wstETH - scroll.selectFork(); - assertEq(l2Balance + 1 ether, MockERC20(L2_WSTETH).balanceOf(address(this))); - assertEq(0, MockERC20(L2_WSTETH).balanceOf(L2_LIDO_GATEWAY)); - if (useRouter) { - IL2ERC20Gateway(L2_GATEWAY_ROUTER).withdrawERC20(L2_WSTETH, 1 ether, 0); - } else { - IL2ERC20Gateway(L2_LIDO_GATEWAY).withdrawERC20(L2_WSTETH, 1 ether, 0); - } - assertEq(l2Balance, MockERC20(L2_WSTETH).balanceOf(address(this))); - assertEq(0, MockERC20(L2_WSTETH).balanceOf(L2_LIDO_GATEWAY)); - - // relay message to Mainnet and check balance - mainnet.selectFork(); - l1GatewayBalance = MockERC20(L1_WSTETH).balanceOf(L1_LIDO_GATEWAY); - l1Balance = MockERC20(L1_WSTETH).balanceOf(address(this)); - relayFromScroll(); - mainnet.selectFork(); - assertEq(l1Balance + 1 ether, MockERC20(L1_WSTETH).balanceOf(address(this))); - assertEq(l1GatewayBalance - 1 ether, MockERC20(L1_WSTETH).balanceOf(L1_LIDO_GATEWAY)); - } -} diff --git a/contracts/src/test/lido/L1LidoGateway.t.sol b/contracts/src/test/lido/L1LidoGateway.t.sol deleted file mode 100644 index 533ba0f1d..000000000 --- a/contracts/src/test/lido/L1LidoGateway.t.sol +++ /dev/null @@ -1,709 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {MockERC20} from "solmate/test/utils/mocks/MockERC20.sol"; - -import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; -import {ITransparentUpgradeableProxy} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; - -import {IL1ERC20Gateway} from "../../L1/gateways/IL1ERC20Gateway.sol"; -import {L1GatewayRouter} from "../../L1/gateways/L1GatewayRouter.sol"; -import {IL1ScrollMessenger} from "../../L1/IL1ScrollMessenger.sol"; -import {IL2ERC20Gateway} from "../../L2/gateways/IL2ERC20Gateway.sol"; -import {AddressAliasHelper} from "../../libraries/common/AddressAliasHelper.sol"; -import {ScrollConstants} from "../../libraries/constants/ScrollConstants.sol"; -import {L2LidoGateway} from "../../lido/L2LidoGateway.sol"; - -import {L1GatewayTestBase} from "../L1GatewayTestBase.t.sol"; -import {MockL1LidoGateway} from "../mocks/MockL1LidoGateway.sol"; -import {MockScrollMessenger} from "../mocks/MockScrollMessenger.sol"; -import {MockGatewayRecipient} from "../mocks/MockGatewayRecipient.sol"; - -contract L1LidoGatewayTest is L1GatewayTestBase { - // events from L1LidoGateway - event FinalizeWithdrawERC20( - address indexed _l1Token, - address indexed _l2Token, - address indexed _from, - address _to, - uint256 _amount, - bytes _data - ); - event DepositERC20( - address indexed _l1Token, - address indexed _l2Token, - address indexed _from, - address _to, - uint256 _amount, - bytes _data - ); - event RefundERC20(address indexed token, address indexed recipient, uint256 amount); - event DepositsEnabled(address indexed enabler); - event DepositsDisabled(address indexed disabler); - event WithdrawalsEnabled(address indexed enabler); - event WithdrawalsDisabled(address indexed disabler); - event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); - event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); - - // errors from L1LidoGateway - error ErrorDepositsEnabled(); - error ErrorDepositsDisabled(); - error ErrorWithdrawalsEnabled(); - error ErrorWithdrawalsDisabled(); - error ErrorCallerIsNotDepositsEnabler(); - error ErrorCallerIsNotDepositsDisabler(); - error ErrorCallerIsNotWithdrawalsEnabler(); - error ErrorCallerIsNotWithdrawalsDisabler(); - error ErrorUnsupportedL1Token(); - error ErrorUnsupportedL2Token(); - error ErrorAccountIsZeroAddress(); - error ErrorNonZeroMsgValue(); - error ErrorDepositZeroAmount(); - error DepositAndCallIsNotAllowed(); - - MockL1LidoGateway private gateway; - L1GatewayRouter private router; - - L2LidoGateway private counterpartGateway; - - MockERC20 private l1Token; - MockERC20 private l2Token; - - function setUp() public { - __L1GatewayTestBase_setUp(); - - // Deploy tokens - l1Token = new MockERC20("Mock L1", "ML1", 18); - l2Token = new MockERC20("Mock L2", "ML2", 18); - - // Deploy L2 contracts - counterpartGateway = new L2LidoGateway(address(l1Token), address(l2Token), address(1), address(1), address(1)); - - // Deploy L1 contracts - router = L1GatewayRouter(_deployProxy(address(new L1GatewayRouter()))); - gateway = _deployGateway(address(l1Messenger)); - - // Initialize L1 contracts - gateway.initialize(address(counterpartGateway), address(router), address(l1Messenger)); - gateway.initializeV2(address(0), address(0), address(0), address(0)); - router.initialize(address(0), address(gateway)); - - // Prepare token balances - l1Token.mint(address(this), type(uint128).max); - l1Token.approve(address(gateway), type(uint256).max); - l1Token.approve(address(router), type(uint256).max); - } - - function testInitialized() public { - // state in ScrollGatewayBase - assertEq(address(this), gateway.owner()); - assertEq(address(counterpartGateway), gateway.counterpart()); - assertEq(address(router), gateway.router()); - assertEq(address(l1Messenger), gateway.messenger()); - - // state in LidoBridgeableTokens - assertEq(address(l1Token), gateway.l1Token()); - assertEq(address(l2Token), gateway.l2Token()); - - // state in LidoGatewayManager - assertBoolEq(true, gateway.isDepositsEnabled()); - assertBoolEq(true, gateway.isWithdrawalsEnabled()); - - // state in L1LidoGateway - assertEq(address(l2Token), gateway.getL2ERC20Address(address(l1Token))); - - hevm.expectRevert("Initializable: contract is already initialized"); - gateway.initialize(address(counterpartGateway), address(router), address(l1Messenger)); - - hevm.expectRevert("Initializable: contract is already initialized"); - gateway.initializeV2(address(0), address(0), address(0), address(0)); - - gateway.revokeRole(gateway.DEPOSITS_ENABLER_ROLE(), address(0)); - gateway.revokeRole(gateway.DEPOSITS_DISABLER_ROLE(), address(0)); - gateway.revokeRole(gateway.WITHDRAWALS_ENABLER_ROLE(), address(0)); - gateway.revokeRole(gateway.WITHDRAWALS_DISABLER_ROLE(), address(0)); - } - - /************************************* - * Functions from LidoGatewayManager * - *************************************/ - - function testEnableDeposits() external { - // revert when already enabled - hevm.expectRevert(ErrorDepositsEnabled.selector); - gateway.enableDeposits(); - - // revert when caller is not deposits enabler - gateway.grantRole(gateway.DEPOSITS_DISABLER_ROLE(), address(this)); - gateway.disableDeposits(); - hevm.expectRevert(ErrorCallerIsNotDepositsEnabler.selector); - gateway.enableDeposits(); - - // succeed - gateway.grantRole(gateway.DEPOSITS_ENABLER_ROLE(), address(this)); - assertBoolEq(false, gateway.isDepositsEnabled()); - hevm.expectEmit(true, false, false, true); - emit DepositsEnabled(address(this)); - gateway.enableDeposits(); - assertBoolEq(true, gateway.isDepositsEnabled()); - } - - function testDisableDeposits() external { - // revert when already disabled - gateway.grantRole(gateway.DEPOSITS_DISABLER_ROLE(), address(this)); - gateway.disableDeposits(); - assertBoolEq(false, gateway.isDepositsEnabled()); - hevm.expectRevert(ErrorDepositsDisabled.selector); - gateway.disableDeposits(); - - // revert when caller is not deposits disabler - gateway.grantRole(gateway.DEPOSITS_ENABLER_ROLE(), address(this)); - gateway.enableDeposits(); - assertBoolEq(true, gateway.isDepositsEnabled()); - gateway.revokeRole(gateway.DEPOSITS_DISABLER_ROLE(), address(this)); - hevm.expectRevert(ErrorCallerIsNotDepositsDisabler.selector); - gateway.disableDeposits(); - - // succeed - gateway.grantRole(gateway.DEPOSITS_DISABLER_ROLE(), address(this)); - assertBoolEq(true, gateway.isDepositsEnabled()); - hevm.expectEmit(true, false, false, true); - emit DepositsDisabled(address(this)); - gateway.disableDeposits(); - assertBoolEq(false, gateway.isDepositsEnabled()); - } - - function testEnableWithdrawals() external { - // revert when already enabled - hevm.expectRevert(ErrorWithdrawalsEnabled.selector); - gateway.enableWithdrawals(); - - // revert when caller is not deposits enabler - gateway.grantRole(gateway.WITHDRAWALS_DISABLER_ROLE(), address(this)); - gateway.disableWithdrawals(); - hevm.expectRevert(ErrorCallerIsNotWithdrawalsEnabler.selector); - gateway.enableWithdrawals(); - - // succeed - gateway.grantRole(gateway.WITHDRAWALS_ENABLER_ROLE(), address(this)); - assertBoolEq(false, gateway.isWithdrawalsEnabled()); - hevm.expectEmit(true, false, false, true); - emit WithdrawalsEnabled(address(this)); - gateway.enableWithdrawals(); - assertBoolEq(true, gateway.isWithdrawalsEnabled()); - } - - function testDisableWithdrawals() external { - // revert when already disabled - gateway.grantRole(gateway.WITHDRAWALS_DISABLER_ROLE(), address(this)); - gateway.disableWithdrawals(); - assertBoolEq(false, gateway.isWithdrawalsEnabled()); - hevm.expectRevert(ErrorWithdrawalsDisabled.selector); - gateway.disableWithdrawals(); - - // revert when caller is not deposits disabler - gateway.grantRole(gateway.WITHDRAWALS_ENABLER_ROLE(), address(this)); - gateway.enableWithdrawals(); - assertBoolEq(true, gateway.isWithdrawalsEnabled()); - gateway.revokeRole(gateway.WITHDRAWALS_DISABLER_ROLE(), address(this)); - hevm.expectRevert(ErrorCallerIsNotWithdrawalsDisabler.selector); - gateway.disableWithdrawals(); - - // succeed - gateway.grantRole(gateway.WITHDRAWALS_DISABLER_ROLE(), address(this)); - assertBoolEq(true, gateway.isWithdrawalsEnabled()); - hevm.expectEmit(true, false, false, true); - emit WithdrawalsDisabled(address(this)); - gateway.disableWithdrawals(); - assertBoolEq(false, gateway.isWithdrawalsEnabled()); - } - - function testGrantRole(bytes32 _role, address _account) external { - hevm.assume(gateway.getRoleMemberCount(_role) == 0); - - // revert not owner - hevm.startPrank(address(1)); - hevm.expectRevert("Ownable: caller is not the owner"); - gateway.grantRole(_role, _account); - hevm.stopPrank(); - - // succeed - assertBoolEq(gateway.hasRole(_role, _account), false); - hevm.expectEmit(true, true, true, true); - emit RoleGranted(_role, _account, address(this)); - gateway.grantRole(_role, _account); - assertBoolEq(gateway.hasRole(_role, _account), true); - assertEq(gateway.getRoleMemberCount(_role), 1); - assertEq(gateway.getRoleMember(_role, 0), _account); - - // do nothing regrant - gateway.grantRole(_role, _account); - assertBoolEq(gateway.hasRole(_role, _account), true); - assertEq(gateway.getRoleMemberCount(_role), 1); - assertEq(gateway.getRoleMember(_role, 0), _account); - } - - function testRevokeRole(bytes32 _role, address _account) external { - hevm.assume(gateway.getRoleMemberCount(_role) == 0); - - // revert not owner - hevm.startPrank(address(1)); - hevm.expectRevert("Ownable: caller is not the owner"); - gateway.revokeRole(_role, _account); - hevm.stopPrank(); - - // grant first - gateway.grantRole(_role, _account); - assertBoolEq(gateway.hasRole(_role, _account), true); - assertEq(gateway.getRoleMemberCount(_role), 1); - assertEq(gateway.getRoleMember(_role, 0), _account); - - // revoke - hevm.expectEmit(true, true, true, true); - emit RoleRevoked(_role, _account, address(this)); - gateway.revokeRole(_role, _account); - assertBoolEq(gateway.hasRole(_role, _account), false); - assertEq(gateway.getRoleMemberCount(_role), 0); - - // revoke again - gateway.revokeRole(_role, _account); - assertBoolEq(gateway.hasRole(_role, _account), false); - assertEq(gateway.getRoleMemberCount(_role), 0); - } - - /******************************** - * Functions from L1LidoGateway * - ********************************/ - - function testDepositERC20( - uint256 amount, - uint256 gasLimit, - uint256 feePerGas - ) external { - _depositERC20(false, 0, amount, address(this), new bytes(0), gasLimit, feePerGas); - } - - function testDepositERC20WithRecipient( - uint256 amount, - address recipient, - uint256 gasLimit, - uint256 feePerGas - ) external { - _depositERC20(false, 1, amount, recipient, new bytes(0), gasLimit, feePerGas); - } - - function testDepositERC20WithRecipientAndCalldata( - uint256 amount, - address recipient, - bytes memory dataToCall, - uint256 gasLimit, - uint256 feePerGas - ) external { - _depositERC20(false, 2, amount, recipient, dataToCall, gasLimit, feePerGas); - } - - function testDepositERC20ByRouter( - uint256 amount, - uint256 gasLimit, - uint256 feePerGas - ) external { - _depositERC20(true, 0, amount, address(this), new bytes(0), gasLimit, feePerGas); - } - - function testDepositERC20WithRecipientByRouter( - uint256 amount, - address recipient, - uint256 gasLimit, - uint256 feePerGas - ) external { - _depositERC20(true, 1, amount, recipient, new bytes(0), gasLimit, feePerGas); - } - - function testDepositERC20WithRecipientAndCalldataByRouter( - uint256 amount, - address recipient, - bytes memory dataToCall, - uint256 gasLimit, - uint256 feePerGas - ) external { - _depositERC20(true, 2, amount, recipient, dataToCall, gasLimit, feePerGas); - } - - function testDropMessage(uint256 amount, address recipient) public { - hevm.assume(recipient != address(0)); - - amount = bound(amount, 1, l1Token.balanceOf(address(this))); - bytes memory message = abi.encodeCall( - IL2ERC20Gateway.finalizeDepositERC20, - (address(l1Token), address(l2Token), address(this), recipient, amount, new bytes(0)) - ); - gateway.depositERC20AndCall(address(l1Token), recipient, amount, new bytes(0), defaultGasLimit); - - MockScrollMessenger mockMessenger = new MockScrollMessenger(); - MockL1LidoGateway mockGateway = _deployGateway(address(mockMessenger)); - mockGateway.initialize(address(counterpartGateway), address(router), address(mockMessenger)); - mockGateway.initializeV2(address(0), address(0), address(0), address(0)); - - // revert caller is not messenger - hevm.expectRevert(ErrorCallerIsNotMessenger.selector); - mockGateway.onDropMessage(new bytes(0)); - - // revert not in drop context - hevm.expectRevert(ErrorNotInDropMessageContext.selector); - mockMessenger.callTarget(address(mockGateway), abi.encodeCall(mockGateway.onDropMessage, (new bytes(0)))); - - // revert when reentrant - mockMessenger.setXDomainMessageSender(ScrollConstants.DROP_XDOMAIN_MESSAGE_SENDER); - hevm.expectRevert("ReentrancyGuard: reentrant call"); - mockGateway.reentrantCall( - address(mockMessenger), - abi.encodeCall( - mockMessenger.callTarget, - (address(mockGateway), abi.encodeCall(mockGateway.onDropMessage, (message))) - ) - ); - - // revert when invalid selector - hevm.expectRevert("invalid selector"); - mockMessenger.callTarget(address(mockGateway), abi.encodeCall(mockGateway.onDropMessage, (new bytes(4)))); - - // revert when l1 token not supported - hevm.expectRevert(ErrorUnsupportedL1Token.selector); - mockMessenger.callTarget( - address(mockGateway), - abi.encodeCall( - mockGateway.onDropMessage, - ( - abi.encodeCall( - IL2ERC20Gateway.finalizeDepositERC20, - (address(l2Token), address(l2Token), address(this), recipient, amount, new bytes(0)) - ) - ) - ) - ); - - // revert when nonzero msg.value - hevm.expectRevert(ErrorNonZeroMsgValue.selector); - mockMessenger.callTarget{value: 1}( - address(mockGateway), - abi.encodeWithSelector(mockGateway.onDropMessage.selector, message) - ); - - // succeed on drop - // skip message 0 - hevm.startPrank(address(rollup)); - messageQueue.popCrossDomainMessage(0, 1, 0x1); - assertEq(messageQueue.pendingQueueIndex(), 1); - hevm.stopPrank(); - - // should emit RefundERC20 - hevm.expectEmit(true, true, false, true); - emit RefundERC20(address(l1Token), address(this), amount); - - uint256 balance = l1Token.balanceOf(address(this)); - uint256 gatewayBalance = l1Token.balanceOf(address(gateway)); - l1Messenger.dropMessage(address(gateway), address(counterpartGateway), 0, 0, message); - assertEq(gatewayBalance - amount, l1Token.balanceOf(address(gateway))); - assertEq(balance + amount, l1Token.balanceOf(address(this))); - } - - function testFinalizeWithdrawERC20( - address sender, - uint256 amount, - bytes memory dataToCall - ) external { - amount = bound(amount, 1, l1Token.balanceOf(address(this))); - MockGatewayRecipient recipient = new MockGatewayRecipient(); - bytes memory message = abi.encodeCall( - IL1ERC20Gateway.finalizeWithdrawERC20, - (address(l1Token), address(l2Token), sender, address(recipient), amount, dataToCall) - ); - gateway.depositERC20(address(l1Token), amount, defaultGasLimit); // deposit some token to L1LidoGateway - - MockScrollMessenger mockMessenger = new MockScrollMessenger(); - MockL1LidoGateway mockGateway = _deployGateway(address(mockMessenger)); - mockGateway.initialize(address(counterpartGateway), address(router), address(mockMessenger)); - mockGateway.initializeV2(address(0), address(0), address(0), address(0)); - - // revert caller is not messenger - hevm.expectRevert(ErrorCallerIsNotMessenger.selector); - mockGateway.finalizeWithdrawERC20( - address(l1Token), - address(l2Token), - sender, - address(recipient), - amount, - dataToCall - ); - - // revert not called by counterpart - hevm.expectRevert(ErrorCallerIsNotCounterpartGateway.selector); - mockMessenger.callTarget(address(mockGateway), message); - - // revert when reentrant - mockMessenger.setXDomainMessageSender(address(counterpartGateway)); - hevm.expectRevert("ReentrancyGuard: reentrant call"); - mockGateway.reentrantCall( - address(mockMessenger), - abi.encodeCall(mockMessenger.callTarget, (address(mockGateway), message)) - ); - - // revert when l1 token not supported - hevm.expectRevert(ErrorUnsupportedL1Token.selector); - mockMessenger.callTarget( - address(mockGateway), - abi.encodeCall( - IL1ERC20Gateway.finalizeWithdrawERC20, - (address(l2Token), address(l2Token), sender, address(recipient), amount, dataToCall) - ) - ); - - // revert when l2 token not supported - hevm.expectRevert(ErrorUnsupportedL2Token.selector); - mockMessenger.callTarget( - address(mockGateway), - abi.encodeCall( - IL1ERC20Gateway.finalizeWithdrawERC20, - (address(l1Token), address(l1Token), sender, address(recipient), amount, dataToCall) - ) - ); - - // revert when withdrawals disabled - mockGateway.grantRole(gateway.WITHDRAWALS_DISABLER_ROLE(), address(this)); - mockGateway.disableWithdrawals(); - hevm.expectRevert(ErrorWithdrawalsDisabled.selector); - mockMessenger.callTarget(address(mockGateway), message); - - // revert when nonzero msg.value - mockGateway.grantRole(gateway.WITHDRAWALS_ENABLER_ROLE(), address(this)); - mockGateway.enableWithdrawals(); - hevm.expectRevert(ErrorNonZeroMsgValue.selector); - mockMessenger.callTarget{value: 1}(address(mockGateway), message); - - // succeed when finialize - bytes memory xDomainCalldata = abi.encodeCall( - l2Messenger.relayMessage, - (address(counterpartGateway), address(gateway), 0, 0, message) - ); - prepareL2MessageRoot(keccak256(xDomainCalldata)); - IL1ScrollMessenger.L2MessageProof memory proof; - proof.batchIndex = rollup.lastFinalizedBatchIndex(); - - // should emit FinalizeWithdrawERC20 from L1StandardERC20Gateway - hevm.expectEmit(true, true, true, true); - emit FinalizeWithdrawERC20(address(l1Token), address(l2Token), sender, address(recipient), amount, dataToCall); - - // should emit RelayedMessage from L1ScrollMessenger - hevm.expectEmit(true, false, false, true); - emit RelayedMessage(keccak256(xDomainCalldata)); - - uint256 gatewayBalance = l1Token.balanceOf(address(gateway)); - uint256 recipientBalance = l1Token.balanceOf(address(recipient)); - assertBoolEq(false, l1Messenger.isL2MessageExecuted(keccak256(xDomainCalldata))); - l1Messenger.relayMessageWithProof(address(counterpartGateway), address(gateway), 0, 0, message, proof); - assertBoolEq(true, l1Messenger.isL2MessageExecuted(keccak256(xDomainCalldata))); - assertEq(recipientBalance + amount, l1Token.balanceOf(address(recipient))); - assertEq(gatewayBalance - amount, l1Token.balanceOf(address(gateway))); - } - - function _depositERC20( - bool useRouter, - uint256 methodType, - uint256 amount, - address recipient, - bytes memory dataToCall, - uint256 gasLimit, - uint256 feePerGas - ) private { - hevm.assume(recipient != address(0)); - amount = bound(amount, 1, l1Token.balanceOf(address(this))); - gasLimit = bound(gasLimit, defaultGasLimit / 2, defaultGasLimit); - feePerGas = bound(feePerGas, 0, 1000); - messageQueue.setL2BaseFee(feePerGas); - feePerGas = feePerGas * gasLimit; - - // revert when reentrant - hevm.expectRevert("ReentrancyGuard: reentrant call"); - { - bytes memory reentrantData; - if (methodType == 0) { - reentrantData = abi.encodeWithSignature( - "depositERC20(address,uint256,uint256)", - address(l1Token), - amount, - gasLimit - ); - } else if (methodType == 1) { - reentrantData = abi.encodeWithSignature( - "depositERC20(address,address,uint256,uint256)", - address(l1Token), - recipient, - amount, - gasLimit - ); - } else if (methodType == 2) { - reentrantData = abi.encodeCall( - IL1ERC20Gateway.depositERC20AndCall, - (address(l1Token), recipient, amount, dataToCall, gasLimit) - ); - } - gateway.reentrantCall(useRouter ? address(router) : address(gateway), reentrantData); - } - - // revert when l1 token not support - hevm.expectRevert(ErrorUnsupportedL1Token.selector); - _invokeDepositERC20Call( - useRouter, - methodType, - address(l2Token), - amount, - recipient, - dataToCall, - gasLimit, - feePerGas - ); - - // revert when to is zero address - if (methodType != 0) { - hevm.expectRevert(ErrorAccountIsZeroAddress.selector); - _invokeDepositERC20Call( - useRouter, - methodType, - address(l1Token), - amount, - address(0), - dataToCall, - gasLimit, - feePerGas - ); - } - - // revert when deposits disabled - gateway.grantRole(gateway.DEPOSITS_DISABLER_ROLE(), address(this)); - gateway.disableDeposits(); - hevm.expectRevert(ErrorDepositsDisabled.selector); - _invokeDepositERC20Call( - useRouter, - methodType, - address(l1Token), - amount, - recipient, - dataToCall, - gasLimit, - feePerGas - ); - - // revert when deposit zero amount - gateway.grantRole(gateway.DEPOSITS_ENABLER_ROLE(), address(this)); - gateway.enableDeposits(); - hevm.expectRevert(ErrorDepositZeroAmount.selector); - _invokeDepositERC20Call(useRouter, methodType, address(l1Token), 0, recipient, dataToCall, gasLimit, feePerGas); - - // revert when data is not empty - if (dataToCall.length != 0) { - hevm.expectRevert(DepositAndCallIsNotAllowed.selector); - _invokeDepositERC20Call( - useRouter, - methodType, - address(l1Token), - amount, - recipient, - dataToCall, - gasLimit, - feePerGas - ); - return; - } - - // succeed to deposit - bytes memory message = abi.encodeCall( - IL2ERC20Gateway.finalizeDepositERC20, - (address(l1Token), address(l2Token), address(this), recipient, amount, dataToCall) - ); - bytes memory xDomainCalldata = abi.encodeCall( - l2Messenger.relayMessage, - (address(gateway), address(counterpartGateway), 0, 0, message) - ); - // should emit QueueTransaction from L1MessageQueue - hevm.expectEmit(true, true, false, true); - address sender = AddressAliasHelper.applyL1ToL2Alias(address(l1Messenger)); - emit QueueTransaction(sender, address(l2Messenger), 0, 0, gasLimit, xDomainCalldata); - - // should emit SentMessage from L1ScrollMessenger - hevm.expectEmit(true, true, false, true); - emit SentMessage(address(gateway), address(counterpartGateway), 0, 0, gasLimit, message); - - // should emit DepositERC20 from L1CustomERC20Gateway - hevm.expectEmit(true, true, true, true); - emit DepositERC20(address(l1Token), address(l2Token), address(this), recipient, amount, dataToCall); - - uint256 gatewayBalance = l1Token.balanceOf(address(gateway)); - uint256 feeVaultBalance = address(feeVault).balance; - uint256 thisBalance = l1Token.balanceOf(address(this)); - assertEq(l1Messenger.messageSendTimestamp(keccak256(xDomainCalldata)), 0); - uint256 balance = address(this).balance; - _invokeDepositERC20Call( - useRouter, - methodType, - address(l1Token), - amount, - recipient, - dataToCall, - gasLimit, - feePerGas - ); - assertEq(balance - feePerGas, address(this).balance); // extra value is transferred back - assertGt(l1Messenger.messageSendTimestamp(keccak256(xDomainCalldata)), 0); - assertEq(thisBalance - amount, l1Token.balanceOf(address(this))); - assertEq(feeVaultBalance + feePerGas, address(feeVault).balance); - assertEq(gatewayBalance + amount, l1Token.balanceOf(address(gateway))); - } - - function _invokeDepositERC20Call( - bool useRouter, - uint256 methodType, - address token, - uint256 amount, - address recipient, - bytes memory dataToCall, - uint256 gasLimit, - uint256 feeToPay - ) private { - uint256 value = feeToPay + extraValue; - if (useRouter) { - if (methodType == 0) { - router.depositERC20{value: value}(token, amount, gasLimit); - } else if (methodType == 1) { - router.depositERC20{value: value}(token, recipient, amount, gasLimit); - } else if (methodType == 2) { - router.depositERC20AndCall{value: value}(token, recipient, amount, dataToCall, gasLimit); - } - } else { - if (methodType == 0) { - gateway.depositERC20{value: value}(token, amount, gasLimit); - } else if (methodType == 1) { - gateway.depositERC20{value: value}(token, recipient, amount, gasLimit); - } else if (methodType == 2) { - gateway.depositERC20AndCall{value: value}(token, recipient, amount, dataToCall, gasLimit); - } - } - } - - function _deployGateway(address messenger) internal returns (MockL1LidoGateway _gateway) { - _gateway = MockL1LidoGateway(_deployProxy(address(0))); - - admin.upgrade( - ITransparentUpgradeableProxy(address(_gateway)), - address( - new MockL1LidoGateway( - address(l1Token), - address(l2Token), - address(counterpartGateway), - address(router), - address(messenger) - ) - ) - ); - } -} diff --git a/contracts/src/test/lido/L2LidoGateway.t.sol b/contracts/src/test/lido/L2LidoGateway.t.sol deleted file mode 100644 index c69c246c6..000000000 --- a/contracts/src/test/lido/L2LidoGateway.t.sol +++ /dev/null @@ -1,569 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {MockERC20} from "solmate/test/utils/mocks/MockERC20.sol"; - -import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; -import {ITransparentUpgradeableProxy} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; - -import {IL1ERC20Gateway} from "../../L1/gateways/IL1ERC20Gateway.sol"; -import {IL2ERC20Gateway} from "../../L2/gateways/IL2ERC20Gateway.sol"; -import {L2GatewayRouter} from "../../L2/gateways/L2GatewayRouter.sol"; -import {AddressAliasHelper} from "../../libraries/common/AddressAliasHelper.sol"; -import {ScrollStandardERC20} from "../../libraries/token/ScrollStandardERC20.sol"; -import {L1LidoGateway} from "../../lido/L1LidoGateway.sol"; - -import {L2GatewayTestBase} from "../L2GatewayTestBase.t.sol"; -import {MockGatewayRecipient} from "../mocks/MockGatewayRecipient.sol"; -import {MockL2LidoGateway} from "../mocks/MockL2LidoGateway.sol"; -import {MockScrollMessenger} from "../mocks/MockScrollMessenger.sol"; - -contract L2LidoGatewayTest is L2GatewayTestBase { - // events from L2LidoGateway - event WithdrawERC20( - address indexed _l1Token, - address indexed _l2Token, - address indexed _from, - address _to, - uint256 _amount, - bytes _data - ); - event FinalizeDepositERC20( - address indexed _l1Token, - address indexed _l2Token, - address indexed _from, - address _to, - uint256 _amount, - bytes _data - ); - event DepositsEnabled(address indexed enabler); - event DepositsDisabled(address indexed disabler); - event WithdrawalsEnabled(address indexed enabler); - event WithdrawalsDisabled(address indexed disabler); - event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); - event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); - - // errors from L2LidoGateway - error ErrorDepositsEnabled(); - error ErrorDepositsDisabled(); - error ErrorWithdrawalsEnabled(); - error ErrorWithdrawalsDisabled(); - error ErrorCallerIsNotDepositsEnabler(); - error ErrorCallerIsNotDepositsDisabler(); - error ErrorCallerIsNotWithdrawalsEnabler(); - error ErrorCallerIsNotWithdrawalsDisabler(); - error ErrorUnsupportedL1Token(); - error ErrorUnsupportedL2Token(); - error ErrorAccountIsZeroAddress(); - error ErrorNonZeroMsgValue(); - error ErrorWithdrawZeroAmount(); - error WithdrawAndCallIsNotAllowed(); - - MockL2LidoGateway private gateway; - L2GatewayRouter private router; - - L1LidoGateway private counterpartGateway; - - MockERC20 private l1Token; - ScrollStandardERC20 private l2Token; - - function setUp() public { - setUpBase(); - // Deploy tokens - l1Token = new MockERC20("Mock L1", "ML1", 18); - l2Token = ScrollStandardERC20(address(new ERC1967Proxy(address(new ScrollStandardERC20()), new bytes(0)))); - - // Deploy L1 contracts - counterpartGateway = new L1LidoGateway(address(l1Token), address(l2Token), address(1), address(1), address(1)); - - // Deploy L2 contracts - router = L2GatewayRouter(_deployProxy(address(new L2GatewayRouter()))); - gateway = _deployGateway(address(l2Messenger)); - - // Initialize L2 contracts - gateway.initialize(address(counterpartGateway), address(router), address(l2Messenger)); - gateway.initializeV2(address(0), address(0), address(0), address(0)); - router.initialize(address(0), address(gateway)); - l2Token.initialize("Mock L2", "ML2", 18, address(gateway), address(l1Token)); - - // Prepare token balances - hevm.startPrank(address(gateway)); - l2Token.mint(address(this), type(uint128).max); - hevm.stopPrank(); - - gateway.revokeRole(gateway.DEPOSITS_ENABLER_ROLE(), address(0)); - gateway.revokeRole(gateway.DEPOSITS_DISABLER_ROLE(), address(0)); - gateway.revokeRole(gateway.WITHDRAWALS_ENABLER_ROLE(), address(0)); - gateway.revokeRole(gateway.WITHDRAWALS_DISABLER_ROLE(), address(0)); - } - - function testInitialized() external { - // state in ScrollGatewayBase - assertEq(address(this), gateway.owner()); - assertEq(address(counterpartGateway), gateway.counterpart()); - assertEq(address(router), gateway.router()); - assertEq(address(l2Messenger), gateway.messenger()); - - // state in LidoBridgeableTokens - assertEq(address(l1Token), gateway.l1Token()); - assertEq(address(l2Token), gateway.l2Token()); - - // state in LidoGatewayManager - assertBoolEq(true, gateway.isDepositsEnabled()); - assertBoolEq(true, gateway.isWithdrawalsEnabled()); - - // state in L2LidoGateway - assertEq(address(l1Token), gateway.getL1ERC20Address(address(l2Token))); - assertEq(address(l2Token), gateway.getL2ERC20Address(address(l1Token))); - - hevm.expectRevert("Initializable: contract is already initialized"); - gateway.initialize(address(counterpartGateway), address(router), address(l2Messenger)); - - hevm.expectRevert("Initializable: contract is already initialized"); - gateway.initializeV2(address(0), address(0), address(0), address(0)); - } - - /************************************* - * Functions from LidoGatewayManager * - *************************************/ - - function testEnableDeposits() external { - // revert when already enabled - hevm.expectRevert(ErrorDepositsEnabled.selector); - gateway.enableDeposits(); - - // revert when caller is not deposits enabler - gateway.grantRole(gateway.DEPOSITS_DISABLER_ROLE(), address(this)); - gateway.disableDeposits(); - hevm.expectRevert(ErrorCallerIsNotDepositsEnabler.selector); - gateway.enableDeposits(); - - // succeed - gateway.grantRole(gateway.DEPOSITS_ENABLER_ROLE(), address(this)); - assertBoolEq(false, gateway.isDepositsEnabled()); - hevm.expectEmit(true, false, false, true); - emit DepositsEnabled(address(this)); - gateway.enableDeposits(); - assertBoolEq(true, gateway.isDepositsEnabled()); - } - - function testDisableDeposits() external { - // revert when already disabled - gateway.grantRole(gateway.DEPOSITS_DISABLER_ROLE(), address(this)); - gateway.disableDeposits(); - assertBoolEq(false, gateway.isDepositsEnabled()); - hevm.expectRevert(ErrorDepositsDisabled.selector); - gateway.disableDeposits(); - - // revert when caller is not deposits disabler - gateway.grantRole(gateway.DEPOSITS_ENABLER_ROLE(), address(this)); - gateway.enableDeposits(); - assertBoolEq(true, gateway.isDepositsEnabled()); - gateway.revokeRole(gateway.DEPOSITS_DISABLER_ROLE(), address(this)); - hevm.expectRevert(ErrorCallerIsNotDepositsDisabler.selector); - gateway.disableDeposits(); - - // succeed - gateway.grantRole(gateway.DEPOSITS_DISABLER_ROLE(), address(this)); - assertBoolEq(true, gateway.isDepositsEnabled()); - hevm.expectEmit(true, false, false, true); - emit DepositsDisabled(address(this)); - gateway.disableDeposits(); - assertBoolEq(false, gateway.isDepositsEnabled()); - } - - function testEnableWithdrawals() external { - // revert when already enabled - hevm.expectRevert(ErrorWithdrawalsEnabled.selector); - gateway.enableWithdrawals(); - - // revert when caller is not deposits enabler - gateway.grantRole(gateway.WITHDRAWALS_DISABLER_ROLE(), address(this)); - gateway.disableWithdrawals(); - hevm.expectRevert(ErrorCallerIsNotWithdrawalsEnabler.selector); - gateway.enableWithdrawals(); - - // succeed - gateway.grantRole(gateway.WITHDRAWALS_ENABLER_ROLE(), address(this)); - assertBoolEq(false, gateway.isWithdrawalsEnabled()); - hevm.expectEmit(true, false, false, true); - emit WithdrawalsEnabled(address(this)); - gateway.enableWithdrawals(); - assertBoolEq(true, gateway.isWithdrawalsEnabled()); - } - - function testDisableWithdrawals() external { - // revert when already disabled - gateway.grantRole(gateway.WITHDRAWALS_DISABLER_ROLE(), address(this)); - gateway.disableWithdrawals(); - assertBoolEq(false, gateway.isWithdrawalsEnabled()); - hevm.expectRevert(ErrorWithdrawalsDisabled.selector); - gateway.disableWithdrawals(); - - // revert when caller is not deposits disabler - gateway.grantRole(gateway.WITHDRAWALS_ENABLER_ROLE(), address(this)); - gateway.enableWithdrawals(); - assertBoolEq(true, gateway.isWithdrawalsEnabled()); - gateway.revokeRole(gateway.WITHDRAWALS_DISABLER_ROLE(), address(this)); - hevm.expectRevert(ErrorCallerIsNotWithdrawalsDisabler.selector); - gateway.disableWithdrawals(); - - // succeed - gateway.grantRole(gateway.WITHDRAWALS_DISABLER_ROLE(), address(this)); - assertBoolEq(true, gateway.isWithdrawalsEnabled()); - hevm.expectEmit(true, false, false, true); - emit WithdrawalsDisabled(address(this)); - gateway.disableWithdrawals(); - assertBoolEq(false, gateway.isWithdrawalsEnabled()); - } - - function testGrantRole(bytes32 _role, address _account) external { - hevm.assume(gateway.getRoleMemberCount(_role) == 0); - - // revert not owner - hevm.startPrank(address(1)); - hevm.expectRevert("Ownable: caller is not the owner"); - gateway.grantRole(_role, _account); - hevm.stopPrank(); - - // succeed - assertBoolEq(gateway.hasRole(_role, _account), false); - hevm.expectEmit(true, true, true, true); - emit RoleGranted(_role, _account, address(this)); - gateway.grantRole(_role, _account); - assertBoolEq(gateway.hasRole(_role, _account), true); - assertEq(gateway.getRoleMemberCount(_role), 1); - assertEq(gateway.getRoleMember(_role, 0), _account); - - // do nothing regrant - gateway.grantRole(_role, _account); - assertBoolEq(gateway.hasRole(_role, _account), true); - assertEq(gateway.getRoleMemberCount(_role), 1); - assertEq(gateway.getRoleMember(_role, 0), _account); - } - - function testRevokeRole(bytes32 _role, address _account) external { - hevm.assume(gateway.getRoleMemberCount(_role) == 0); - - // revert not owner - hevm.startPrank(address(1)); - hevm.expectRevert("Ownable: caller is not the owner"); - gateway.revokeRole(_role, _account); - hevm.stopPrank(); - - // grant first - gateway.grantRole(_role, _account); - assertBoolEq(gateway.hasRole(_role, _account), true); - assertEq(gateway.getRoleMemberCount(_role), 1); - assertEq(gateway.getRoleMember(_role, 0), _account); - - // revoke - hevm.expectEmit(true, true, true, true); - emit RoleRevoked(_role, _account, address(this)); - gateway.revokeRole(_role, _account); - assertBoolEq(gateway.hasRole(_role, _account), false); - assertEq(gateway.getRoleMemberCount(_role), 0); - - // revoke again - gateway.revokeRole(_role, _account); - assertBoolEq(gateway.hasRole(_role, _account), false); - assertEq(gateway.getRoleMemberCount(_role), 0); - } - - /******************************** - * Functions from L2LidoGateway * - ********************************/ - - function testGetL1ERC20Address(address token) external { - hevm.assume(token != address(l2Token)); - hevm.expectRevert(ErrorUnsupportedL2Token.selector); - gateway.getL1ERC20Address(token); - } - - function testGetL2ERC20Address(address token) external { - hevm.assume(token != address(l1Token)); - hevm.expectRevert(ErrorUnsupportedL1Token.selector); - gateway.getL2ERC20Address(token); - } - - function testWithdrawERC20(uint256 amount, uint256 gasLimit) external { - _withdrawERC20(false, 0, amount, address(this), new bytes(0), gasLimit); - } - - function testWithdrawERC20WithRecipient( - uint256 amount, - address recipient, - uint256 gasLimit - ) external { - _withdrawERC20(false, 1, amount, recipient, new bytes(0), gasLimit); - } - - function testWithdrawERC20WithRecipientAndCalldata( - uint256 amount, - address recipient, - bytes memory dataToCall, - uint256 gasLimit - ) external { - _withdrawERC20(false, 2, amount, recipient, dataToCall, gasLimit); - } - - function testWithdrawERC20ByRouter(uint256 amount, uint256 gasLimit) external { - _withdrawERC20(true, 0, amount, address(this), new bytes(0), gasLimit); - } - - function testWithdrawERC20WithRecipientByRouter( - uint256 amount, - address recipient, - uint256 gasLimit - ) external { - _withdrawERC20(true, 1, amount, recipient, new bytes(0), gasLimit); - } - - function testWithdrawERC20WithRecipientAndCalldataByRouter( - uint256 amount, - address recipient, - bytes memory dataToCall, - uint256 gasLimit - ) external { - _withdrawERC20(true, 2, amount, recipient, dataToCall, gasLimit); - } - - function testFinalizeDepositERC20( - address sender, - uint256 amount, - bytes memory dataToCall - ) external { - amount = bound(amount, 1, l2Token.balanceOf(address(this))); - MockGatewayRecipient recipient = new MockGatewayRecipient(); - bytes memory message = abi.encodeCall( - IL2ERC20Gateway.finalizeDepositERC20, - (address(l1Token), address(l2Token), sender, address(recipient), amount, dataToCall) - ); - - MockScrollMessenger mockMessenger = new MockScrollMessenger(); - MockL2LidoGateway mockGateway = _deployGateway(address(mockMessenger)); - mockGateway.initialize(address(counterpartGateway), address(router), address(mockMessenger)); - mockGateway.initializeV2(address(0), address(0), address(0), address(0)); - - // revert caller is not messenger - hevm.expectRevert(ErrorCallerIsNotMessenger.selector); - mockGateway.finalizeDepositERC20( - address(l1Token), - address(l2Token), - sender, - address(recipient), - amount, - dataToCall - ); - - // revert not called by counterpart - hevm.expectRevert(ErrorCallerIsNotCounterpartGateway.selector); - mockMessenger.callTarget(address(mockGateway), message); - - // revert when reentrant - mockMessenger.setXDomainMessageSender(address(counterpartGateway)); - hevm.expectRevert("ReentrancyGuard: reentrant call"); - mockGateway.reentrantCall( - address(mockMessenger), - abi.encodeCall(mockMessenger.callTarget, (address(mockGateway), message)) - ); - - // revert when l1 token not supported - hevm.expectRevert(ErrorUnsupportedL1Token.selector); - mockMessenger.callTarget( - address(mockGateway), - abi.encodeCall( - IL2ERC20Gateway.finalizeDepositERC20, - (address(l2Token), address(l2Token), sender, address(recipient), amount, dataToCall) - ) - ); - - // revert when l2 token not supported - hevm.expectRevert(ErrorUnsupportedL2Token.selector); - mockMessenger.callTarget( - address(mockGateway), - abi.encodeCall( - IL2ERC20Gateway.finalizeDepositERC20, - (address(l1Token), address(l1Token), sender, address(recipient), amount, dataToCall) - ) - ); - - // revert when deposits disabled - mockGateway.grantRole(gateway.DEPOSITS_DISABLER_ROLE(), address(this)); - mockGateway.disableDeposits(); - hevm.expectRevert(ErrorDepositsDisabled.selector); - mockMessenger.callTarget(address(mockGateway), message); - - // revert when nonzero msg.value - mockGateway.grantRole(gateway.DEPOSITS_ENABLER_ROLE(), address(this)); - mockGateway.enableDeposits(); - hevm.expectRevert(ErrorNonZeroMsgValue.selector); - mockMessenger.callTarget{value: 1}(address(mockGateway), message); - - // succeed when finialize - bytes memory xDomainCalldata = abi.encodeCall( - l2Messenger.relayMessage, - (address(counterpartGateway), address(gateway), 0, 0, message) - ); - - // should emit FinalizeDepositERC20 from L2LidoGateway - hevm.expectEmit(true, true, true, true); - emit FinalizeDepositERC20(address(l1Token), address(l2Token), sender, address(recipient), amount, dataToCall); - - // should emit RelayedMessage from L2ScrollMessenger - hevm.expectEmit(true, false, false, true); - emit RelayedMessage(keccak256(xDomainCalldata)); - - uint256 gatewayBalance = l2Token.balanceOf(address(gateway)); - uint256 recipientBalance = l2Token.balanceOf(address(recipient)); - assertBoolEq(false, l2Messenger.isL1MessageExecuted(keccak256(xDomainCalldata))); - hevm.startPrank(AddressAliasHelper.applyL1ToL2Alias(address(l1Messenger))); - l2Messenger.relayMessage(address(counterpartGateway), address(gateway), 0, 0, message); - hevm.stopPrank(); - assertBoolEq(true, l2Messenger.isL1MessageExecuted(keccak256(xDomainCalldata))); // executed - assertEq(recipientBalance + amount, l2Token.balanceOf(address(recipient))); // mint token - assertEq(gatewayBalance, l2Token.balanceOf(address(gateway))); // gateway balance unchanged - } - - function _withdrawERC20( - bool useRouter, - uint256 methodType, - uint256 amount, - address recipient, - bytes memory dataToCall, - uint256 gasLimit - ) private { - hevm.assume(recipient != address(0)); - amount = bound(amount, 1, l2Token.balanceOf(address(this))); - - // revert when reentrant - hevm.expectRevert("ReentrancyGuard: reentrant call"); - bytes memory reentrantData; - if (methodType == 0) { - reentrantData = abi.encodeWithSignature( - "withdrawERC20(address,uint256,uint256)", - address(l2Token), - amount, - gasLimit - ); - } else if (methodType == 1) { - reentrantData = abi.encodeWithSignature( - "withdrawERC20(address,address,uint256,uint256)", - address(l2Token), - recipient, - amount, - gasLimit - ); - } else if (methodType == 2) { - reentrantData = abi.encodeCall( - IL2ERC20Gateway.withdrawERC20AndCall, - (address(l2Token), recipient, amount, dataToCall, gasLimit) - ); - } - gateway.reentrantCall(useRouter ? address(router) : address(gateway), reentrantData); - - // revert when l2 token not support - hevm.expectRevert(ErrorUnsupportedL2Token.selector); - _invokeWithdrawERC20Call(useRouter, methodType, address(l1Token), amount, recipient, dataToCall, gasLimit); - - // revert when to is zero address - if (methodType != 0) { - hevm.expectRevert(ErrorAccountIsZeroAddress.selector); - _invokeWithdrawERC20Call(useRouter, methodType, address(l2Token), amount, address(0), dataToCall, gasLimit); - } - - // revert when withdrawals disabled - gateway.grantRole(gateway.WITHDRAWALS_DISABLER_ROLE(), address(this)); - gateway.disableWithdrawals(); - hevm.expectRevert(ErrorWithdrawalsDisabled.selector); - _invokeWithdrawERC20Call(useRouter, methodType, address(l2Token), amount, recipient, dataToCall, gasLimit); - - // revert when withdraw zero amount - gateway.grantRole(gateway.WITHDRAWALS_ENABLER_ROLE(), address(this)); - gateway.enableWithdrawals(); - hevm.expectRevert(ErrorWithdrawZeroAmount.selector); - _invokeWithdrawERC20Call(useRouter, methodType, address(l2Token), 0, recipient, dataToCall, gasLimit); - - // revert when data is not empty - if (dataToCall.length != 0) { - hevm.expectRevert(WithdrawAndCallIsNotAllowed.selector); - _invokeWithdrawERC20Call(useRouter, methodType, address(l2Token), amount, recipient, dataToCall, gasLimit); - return; - } - - // succeed to withdraw - bytes memory message = abi.encodeCall( - IL1ERC20Gateway.finalizeWithdrawERC20, - (address(l1Token), address(l2Token), address(this), recipient, amount, dataToCall) - ); - bytes memory xDomainCalldata = abi.encodeCall( - l2Messenger.relayMessage, - (address(gateway), address(counterpartGateway), 0, 0, message) - ); - // should emit AppendMessage from L2MessageQueue - hevm.expectEmit(false, false, false, true); - emit AppendMessage(0, keccak256(xDomainCalldata)); - - // should emit SentMessage from L2ScrollMessenger - hevm.expectEmit(true, true, false, true); - emit SentMessage(address(gateway), address(counterpartGateway), 0, 0, gasLimit, message); - - // should emit WithdrawERC20 from L2LidoGateway - hevm.expectEmit(true, true, true, true); - emit WithdrawERC20(address(l1Token), address(l2Token), address(this), recipient, amount, dataToCall); - - uint256 gatewayBalance = l2Token.balanceOf(address(gateway)); - uint256 thisBalance = l2Token.balanceOf(address(this)); - assertEq(l2Messenger.messageSendTimestamp(keccak256(xDomainCalldata)), 0); - _invokeWithdrawERC20Call(useRouter, methodType, address(l2Token), amount, recipient, dataToCall, gasLimit); - assertGt(l2Messenger.messageSendTimestamp(keccak256(xDomainCalldata)), 0); - assertEq(thisBalance - amount, l2Token.balanceOf(address(this))); - assertEq(gatewayBalance, l2Token.balanceOf(address(gateway))); - } - - function _invokeWithdrawERC20Call( - bool useRouter, - uint256 methodType, - address token, - uint256 amount, - address recipient, - bytes memory dataToCall, - uint256 gasLimit - ) private { - if (useRouter) { - if (methodType == 0) { - router.withdrawERC20(token, amount, gasLimit); - } else if (methodType == 1) { - router.withdrawERC20(token, recipient, amount, gasLimit); - } else if (methodType == 2) { - router.withdrawERC20AndCall(token, recipient, amount, dataToCall, gasLimit); - } - } else { - if (methodType == 0) { - gateway.withdrawERC20(token, amount, gasLimit); - } else if (methodType == 1) { - gateway.withdrawERC20(token, recipient, amount, gasLimit); - } else if (methodType == 2) { - gateway.withdrawERC20AndCall(token, recipient, amount, dataToCall, gasLimit); - } - } - } - - function _deployGateway(address messenger) internal returns (MockL2LidoGateway _gateway) { - _gateway = MockL2LidoGateway(_deployProxy(address(0))); - - admin.upgrade( - ITransparentUpgradeableProxy(address(_gateway)), - address( - new MockL2LidoGateway( - address(l1Token), - address(l2Token), - address(counterpartGateway), - address(router), - address(messenger) - ) - ) - ); - } -} diff --git a/contracts/src/test/lido/L2WstETHToken.t.sol b/contracts/src/test/lido/L2WstETHToken.t.sol deleted file mode 100644 index 0fa302f86..000000000 --- a/contracts/src/test/lido/L2WstETHToken.t.sol +++ /dev/null @@ -1,69 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {DSTestPlus} from "solmate/test/utils/DSTestPlus.sol"; - -import {IERC1271Upgradeable} from "@openzeppelin/contracts-upgradeable/interfaces/IERC1271Upgradeable.sol"; -import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; - -import {L2WstETHToken} from "../../lido/L2WstETHToken.sol"; - -contract L2WstETHTokenTest is DSTestPlus { - L2WstETHToken private counterpart; - L2WstETHToken private token; - - bytes4 private _magicValue; - bool private revertOnSignature; - - function setUp() public { - hevm.warp(1000); // make block timestamp nonzero - - counterpart = new L2WstETHToken(); - token = L2WstETHToken(address(new ERC1967Proxy(address(new L2WstETHToken()), new bytes(0)))); - - token.initialize("Wrapped liquid staked Ether 2.0", "wstETH", 18, address(this), address(counterpart)); - } - - function testInitialize() external { - assertEq(token.name(), "Wrapped liquid staked Ether 2.0"); - assertEq(token.symbol(), "wstETH"); - assertEq(token.decimals(), 18); - assertEq(token.gateway(), address(this)); - assertEq(token.counterpart(), address(counterpart)); - } - - function testPermit(uint256 amount) external { - uint256 timestamp = block.timestamp; - // revert when expire - hevm.expectRevert("ERC20Permit: expired deadline"); - token.permit(address(this), address(counterpart), 1, timestamp - 1, 0, 0, 0); - - // revert when invalid contract signature - hevm.expectRevert("ERC20Permit: invalid signature"); - _magicValue = bytes4(0); - revertOnSignature = false; - token.permit(address(this), address(counterpart), 1, timestamp, 0, 0, 0); - - // revert when invalid contract signature - hevm.expectRevert("ERC20Permit: invalid signature"); - _magicValue = IERC1271Upgradeable.isValidSignature.selector; - revertOnSignature = true; - token.permit(address(this), address(counterpart), 1, timestamp, 0, 0, 0); - - // succeed on contract signer - _magicValue = IERC1271Upgradeable.isValidSignature.selector; - revertOnSignature = false; - assertEq(token.allowance(address(this), address(counterpart)), 0); - token.permit(address(this), address(counterpart), amount, timestamp, 0, 0, 0); - assertEq(token.allowance(address(this), address(counterpart)), amount); - } - - function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue) { - if (revertOnSignature) { - revert("revert"); - } - - magicValue = _magicValue; - } -} diff --git a/contracts/src/test/mocks/MockERC1155Recipient.sol b/contracts/src/test/mocks/MockERC1155Recipient.sol deleted file mode 100644 index 489b0ebe5..000000000 --- a/contracts/src/test/mocks/MockERC1155Recipient.sol +++ /dev/null @@ -1,63 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {ERC1155TokenReceiver} from "solmate/tokens/ERC1155.sol"; - -contract MockERC1155Recipient is ERC1155TokenReceiver { - address private target; - uint256 private value; - bytes private data; - - function setCall( - address _target, - uint256 _value, - bytes calldata _data - ) external payable { - target = _target; - value = _value; - data = _data; - } - - function onERC1155Received( - address, - address, - uint256, - uint256, - bytes calldata - ) external override returns (bytes4) { - // solhint-disable-next-line avoid-low-level-calls - (bool success, ) = target.call{value: value}(data); - if (!success) { - // solhint-disable-next-line no-inline-assembly - assembly { - let ptr := mload(0x40) - let size := returndatasize() - returndatacopy(ptr, 0, size) - revert(ptr, size) - } - } - return ERC1155TokenReceiver.onERC1155Received.selector; - } - - function onERC1155BatchReceived( - address, - address, - uint256[] calldata, - uint256[] calldata, - bytes calldata - ) external override returns (bytes4) { - // solhint-disable-next-line avoid-low-level-calls - (bool success, ) = target.call{value: value}(data); - if (!success) { - // solhint-disable-next-line no-inline-assembly - assembly { - let ptr := mload(0x40) - let size := returndatasize() - returndatacopy(ptr, 0, size) - revert(ptr, size) - } - } - return ERC1155TokenReceiver.onERC1155BatchReceived.selector; - } -} diff --git a/contracts/src/test/mocks/MockERC721Recipient.sol b/contracts/src/test/mocks/MockERC721Recipient.sol deleted file mode 100644 index 2b56527cc..000000000 --- a/contracts/src/test/mocks/MockERC721Recipient.sol +++ /dev/null @@ -1,41 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {ERC721TokenReceiver} from "solmate/tokens/ERC721.sol"; - -contract MockERC721Recipient is ERC721TokenReceiver { - address private target; - uint256 private value; - bytes private data; - - function setCall( - address _target, - uint256 _value, - bytes calldata _data - ) external payable { - target = _target; - value = _value; - data = _data; - } - - function onERC721Received( - address, - address, - uint256, - bytes calldata - ) external override returns (bytes4) { - // solhint-disable-next-line avoid-low-level-calls - (bool success, ) = target.call{value: value}(data); - if (!success) { - // solhint-disable-next-line no-inline-assembly - assembly { - let ptr := mload(0x40) - let size := returndatasize() - returndatacopy(ptr, 0, size) - revert(ptr, size) - } - } - return ERC721TokenReceiver.onERC721Received.selector; - } -} diff --git a/contracts/src/test/mocks/MockGatewayRecipient.sol b/contracts/src/test/mocks/MockGatewayRecipient.sol deleted file mode 100644 index 53b4a560d..000000000 --- a/contracts/src/test/mocks/MockGatewayRecipient.sol +++ /dev/null @@ -1,15 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {IScrollGatewayCallback} from "../../libraries/callbacks/IScrollGatewayCallback.sol"; - -contract MockGatewayRecipient is IScrollGatewayCallback { - event ReceiveCall(bytes data); - - function onScrollGatewayCallback(bytes memory data) external { - emit ReceiveCall(data); - } - - receive() external payable {} -} diff --git a/contracts/src/test/mocks/MockL1LidoGateway.sol b/contracts/src/test/mocks/MockL1LidoGateway.sol deleted file mode 100644 index 76a21346b..000000000 --- a/contracts/src/test/mocks/MockL1LidoGateway.sol +++ /dev/null @@ -1,28 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {L1LidoGateway} from "../../lido/L1LidoGateway.sol"; - -contract MockL1LidoGateway is L1LidoGateway { - constructor( - address _l1Token, - address _l2Token, - address _counterpart, - address _router, - address _messenger - ) L1LidoGateway(_l1Token, _l2Token, _counterpart, _router, _messenger) {} - - function reentrantCall(address target, bytes calldata data) external payable nonReentrant { - (bool success, ) = target.call{value: msg.value}(data); - if (!success) { - // solhint-disable-next-line no-inline-assembly - assembly { - let ptr := mload(0x40) - let size := returndatasize() - returndatacopy(ptr, 0, size) - revert(ptr, size) - } - } - } -} diff --git a/contracts/src/test/mocks/MockL2LidoGateway.sol b/contracts/src/test/mocks/MockL2LidoGateway.sol deleted file mode 100644 index 77a696a5d..000000000 --- a/contracts/src/test/mocks/MockL2LidoGateway.sol +++ /dev/null @@ -1,28 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {L2LidoGateway} from "../../lido/L2LidoGateway.sol"; - -contract MockL2LidoGateway is L2LidoGateway { - constructor( - address _l1Token, - address _l2Token, - address _counterpart, - address _router, - address _messenger - ) L2LidoGateway(_l1Token, _l2Token, _counterpart, _router, _messenger) {} - - function reentrantCall(address target, bytes calldata data) external payable nonReentrant { - (bool success, ) = target.call{value: msg.value}(data); - if (!success) { - // solhint-disable-next-line no-inline-assembly - assembly { - let ptr := mload(0x40) - let size := returndatasize() - returndatacopy(ptr, 0, size) - revert(ptr, size) - } - } - } -} diff --git a/contracts/src/test/mocks/MockRollupVerifier.sol b/contracts/src/test/mocks/MockRollupVerifier.sol deleted file mode 100644 index 783b7ce8d..000000000 --- a/contracts/src/test/mocks/MockRollupVerifier.sol +++ /dev/null @@ -1,22 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {IRollupVerifier} from "../../libraries/verifier/IRollupVerifier.sol"; - -contract MockRollupVerifier is IRollupVerifier { - /// @inheritdoc IRollupVerifier - function verifyAggregateProof( - uint256, - bytes calldata, - bytes32 - ) external view {} - - /// @inheritdoc IRollupVerifier - function verifyAggregateProof( - uint256, - uint256, - bytes calldata, - bytes32 - ) external view {} -} diff --git a/contracts/src/test/mocks/MockScrollChain.sol b/contracts/src/test/mocks/MockScrollChain.sol deleted file mode 100644 index da6efa627..000000000 --- a/contracts/src/test/mocks/MockScrollChain.sol +++ /dev/null @@ -1,13 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {ScrollChain} from "../../L1/rollup/ScrollChain.sol"; - -contract MockScrollChain is ScrollChain { - constructor(address _messageQueue, address _verifier) ScrollChain(0, _messageQueue, _verifier) {} - - function setLastFinalizedBatchIndex(uint256 _lastFinalizedBatchIndex) external { - lastFinalizedBatchIndex = _lastFinalizedBatchIndex; - } -} diff --git a/contracts/src/test/mocks/MockScrollMessenger.sol b/contracts/src/test/mocks/MockScrollMessenger.sol deleted file mode 100644 index bd558eaa2..000000000 --- a/contracts/src/test/mocks/MockScrollMessenger.sol +++ /dev/null @@ -1,48 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {IScrollMessenger} from "../../libraries/IScrollMessenger.sol"; - -// solhint-disable no-empty-blocks - -contract MockScrollMessenger is IScrollMessenger { - address public override xDomainMessageSender; - - /***************************** - * Public Mutating Functions * - *****************************/ - - function setXDomainMessageSender(address _xDomainMessageSender) external { - xDomainMessageSender = _xDomainMessageSender; - } - - function callTarget(address to, bytes calldata data) external payable { - // solhint-disable-next-line avoid-low-level-calls - (bool success, ) = address(to).call{value: msg.value}(data); - if (!success) { - // solhint-disable-next-line no-inline-assembly - assembly { - let ptr := mload(0x40) - let size := returndatasize() - returndatacopy(ptr, 0, size) - revert(ptr, size) - } - } - } - - function sendMessage( - address _to, - uint256 _value, - bytes memory _message, - uint256 _gasLimit - ) external payable {} - - function sendMessage( - address _to, - uint256 _value, - bytes memory _message, - uint256 _gasLimit, - address _refundAddress - ) external payable {} -} diff --git a/contracts/src/test/mocks/MockZkEvmVerifier.sol b/contracts/src/test/mocks/MockZkEvmVerifier.sol deleted file mode 100644 index 33cbd2aaa..000000000 --- a/contracts/src/test/mocks/MockZkEvmVerifier.sol +++ /dev/null @@ -1,14 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {IZkEvmVerifier} from "../../libraries/verifier/IZkEvmVerifier.sol"; - -contract MockZkEvmVerifier is IZkEvmVerifier { - event Called(address); - - /// @inheritdoc IZkEvmVerifier - function verify(bytes calldata, bytes32) external view { - revert(string(abi.encode(address(this)))); - } -} diff --git a/contracts/src/test/mocks/tokens/FeeOnTransferToken.sol b/contracts/src/test/mocks/tokens/FeeOnTransferToken.sol deleted file mode 100644 index 1e0db22ba..000000000 --- a/contracts/src/test/mocks/tokens/FeeOnTransferToken.sol +++ /dev/null @@ -1,63 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {MockERC20} from "solmate/test/utils/mocks/MockERC20.sol"; - -// solhint-disable no-empty-blocks - -contract FeeOnTransferToken is MockERC20 { - uint256 private feeRate; - - constructor( - string memory _name, - string memory _symbol, - uint8 _decimals - ) MockERC20(_name, _symbol, _decimals) {} - - function setFeeRate(uint256 _feeRate) external payable { - feeRate = _feeRate; - } - - function transfer(address to, uint256 amount) public virtual override returns (bool) { - balanceOf[msg.sender] -= amount; - - uint256 fee = (amount * feeRate) / 1e9; - amount -= fee; - - // Cannot overflow because the sum of all user - // balances can't exceed the max uint256 value. - unchecked { - balanceOf[to] += amount; - } - - emit Transfer(msg.sender, to, amount); - - return true; - } - - function transferFrom( - address from, - address to, - uint256 amount - ) public virtual override returns (bool) { - uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals. - - if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount; - - balanceOf[from] -= amount; - - uint256 fee = (amount * feeRate) / 1e9; - amount -= fee; - - // Cannot overflow because the sum of all user - // balances can't exceed the max uint256 value. - unchecked { - balanceOf[to] += amount; - } - - emit Transfer(from, to, amount); - - return true; - } -} diff --git a/contracts/src/test/mocks/tokens/RevertOnTransferToken.sol b/contracts/src/test/mocks/tokens/RevertOnTransferToken.sol deleted file mode 100644 index 7983abfb5..000000000 --- a/contracts/src/test/mocks/tokens/RevertOnTransferToken.sol +++ /dev/null @@ -1,45 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {MockERC20} from "solmate/test/utils/mocks/MockERC20.sol"; - -// solhint-disable no-empty-blocks - -contract RevertOnTransferToken is MockERC20 { - bool private revertOnTransfer; - bool private transferReturn; - - constructor( - string memory _name, - string memory _symbol, - uint8 _decimals - ) MockERC20(_name, _symbol, _decimals) { - transferReturn = true; - } - - function setRevertOnTransfer(bool _revertOnTransfer) external payable { - revertOnTransfer = _revertOnTransfer; - } - - function setTransferReturn(bool _transferReturn) external payable { - transferReturn = _transferReturn; - } - - function transfer(address to, uint256 amount) public virtual override returns (bool) { - if (revertOnTransfer) revert(); - if (!transferReturn) return false; - - balanceOf[msg.sender] -= amount; - - // Cannot overflow because the sum of all user - // balances can't exceed the max uint256 value. - unchecked { - balanceOf[to] += amount; - } - - emit Transfer(msg.sender, to, amount); - - return true; - } -} diff --git a/contracts/src/test/mocks/tokens/TransferReentrantToken.sol b/contracts/src/test/mocks/tokens/TransferReentrantToken.sol deleted file mode 100644 index 9001dda54..000000000 --- a/contracts/src/test/mocks/tokens/TransferReentrantToken.sol +++ /dev/null @@ -1,70 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity =0.8.24; - -import {MockERC20} from "solmate/test/utils/mocks/MockERC20.sol"; - -// solhint-disable no-empty-blocks - -contract TransferReentrantToken is MockERC20 { - address private target; - uint256 private value; - bytes private data; - bool private isBeforeCall; - - constructor( - string memory _name, - string memory _symbol, - uint8 _decimals - ) MockERC20(_name, _symbol, _decimals) {} - - function setReentrantCall( - address _target, - uint256 _value, - bytes calldata _data, - bool _isBeforeCall - ) external payable { - target = _target; - value = _value; - data = _data; - isBeforeCall = _isBeforeCall; - } - - function transferFrom( - address from, - address to, - uint256 amount - ) public virtual override returns (bool) { - if (isBeforeCall && target != address(0)) { - // solhint-disable-next-line avoid-low-level-calls - (bool success, ) = target.call{value: value}(data); - if (!success) { - // solhint-disable-next-line no-inline-assembly - assembly { - let ptr := mload(0x40) - let size := returndatasize() - returndatacopy(ptr, 0, size) - revert(ptr, size) - } - } - } - - super.transferFrom(from, to, amount); - - if (!isBeforeCall && target != address(0)) { - // solhint-disable-next-line avoid-low-level-calls - (bool success, ) = target.call{value: value}(data); - if (!success) { - // solhint-disable-next-line no-inline-assembly - assembly { - let ptr := mload(0x40) - let size := returndatasize() - returndatacopy(ptr, 0, size) - revert(ptr, size) - } - } - } - - return true; - } -} diff --git a/contracts/tsconfig.json b/contracts/tsconfig.json deleted file mode 100644 index d77c214cd..000000000 --- a/contracts/tsconfig.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "compilerOptions": { - "target": "es2020", - "module": "commonjs", - "strict": true, - "esModuleInterop": true, - "outDir": "dist", - "declaration": true - }, - "include": ["./scripts", "integration-test", "./typechain"], - "files": ["./hardhat.config.ts", "./circomlib.d.ts"] -} diff --git a/contracts/yarn.lock b/contracts/yarn.lock deleted file mode 100644 index 8373cc0b3..000000000 --- a/contracts/yarn.lock +++ /dev/null @@ -1,11454 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@aashutoshrathi/word-wrap@^1.2.3": - version "1.2.6" - resolved "https://registry.yarnpkg.com/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz#bd9154aec9983f77b3a034ecaa015c2e4201f6cf" - integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA== - -"@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== - -"@babel/code-frame@^7.0.0": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.16.7.tgz#44416b6bd7624b998f5b1af5d470856c40138789" - integrity sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg== - dependencies: - "@babel/highlight" "^7.16.7" - -"@babel/helper-validator-identifier@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz#e8c602438c4a8195751243da9031d1607d247cad" - integrity sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw== - -"@babel/highlight@^7.16.7": - version "7.17.9" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.17.9.tgz#61b2ee7f32ea0454612def4fccdae0de232b73e3" - integrity sha512-J9PfEKCbFIv2X5bjTMiZu6Vf341N05QIY+d6FvVKynkG1S7G0j3I0QoRtWIrXhZ+/Nlb5Q0MzqL7TokEJ5BNHg== - dependencies: - "@babel/helper-validator-identifier" "^7.16.7" - chalk "^2.0.0" - js-tokens "^4.0.0" - -"@cspotcode/source-map-consumer@0.8.0": - version "0.8.0" - resolved "https://registry.yarnpkg.com/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz#33bf4b7b39c178821606f669bbc447a6a629786b" - integrity sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg== - -"@cspotcode/source-map-support@0.7.0": - version "0.7.0" - resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz#4789840aa859e46d2f3173727ab707c66bf344f5" - integrity sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA== - dependencies: - "@cspotcode/source-map-consumer" "0.8.0" - -"@ensdomains/ens@^0.4.4": - version "0.4.5" - resolved "https://registry.yarnpkg.com/@ensdomains/ens/-/ens-0.4.5.tgz#e0aebc005afdc066447c6e22feb4eda89a5edbfc" - integrity sha512-JSvpj1iNMFjK6K+uVl4unqMoa9rf5jopb8cya5UGBWz23Nw8hSNT7efgUx4BTlAPAgpNlEioUfeTyQ6J9ZvTVw== - dependencies: - bluebird "^3.5.2" - eth-ens-namehash "^2.0.8" - solc "^0.4.20" - testrpc "0.0.1" - web3-utils "^1.0.0-beta.31" - -"@ensdomains/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== - -"@eslint-community/eslint-utils@^4.1.2", "@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0": - version "4.4.0" - resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" - integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA== - dependencies: - eslint-visitor-keys "^3.3.0" - -"@eslint-community/regexpp@^4.5.1", "@eslint-community/regexpp@^4.6.0", "@eslint-community/regexpp@^4.6.1": - version "4.10.0" - resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.10.0.tgz#548f6de556857c8bb73bbee70c35dc82a2e74d63" - integrity sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA== - -"@eslint/eslintrc@^2.1.4": - version "2.1.4" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.1.4.tgz#388a269f0f25c1b6adc317b5a2c55714894c70ad" - integrity sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ== - dependencies: - ajv "^6.12.4" - debug "^4.3.2" - espree "^9.6.0" - globals "^13.19.0" - ignore "^5.2.0" - import-fresh "^3.2.1" - js-yaml "^4.1.0" - minimatch "^3.1.2" - strip-json-comments "^3.1.1" - -"@eslint/js@8.57.0": - version "8.57.0" - resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.57.0.tgz#a5417ae8427873f1dd08b70b3574b453e67b5f7f" - integrity sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g== - -"@ethereum-waffle/chai@^3.4.4": - version "3.4.4" - resolved "https://registry.yarnpkg.com/@ethereum-waffle/chai/-/chai-3.4.4.tgz#16c4cc877df31b035d6d92486dfdf983df9138ff" - integrity sha512-/K8czydBtXXkcM9X6q29EqEkc5dN3oYenyH2a9hF7rGAApAJUpH8QBtojxOY/xQ2up5W332jqgxwp0yPiYug1g== - dependencies: - "@ethereum-waffle/provider" "^3.4.4" - ethers "^5.5.2" - -"@ethereum-waffle/compiler@^3.4.4": - version "3.4.4" - resolved "https://registry.yarnpkg.com/@ethereum-waffle/compiler/-/compiler-3.4.4.tgz#d568ee0f6029e68b5c645506079fbf67d0dfcf19" - integrity sha512-RUK3axJ8IkD5xpWjWoJgyHclOeEzDLQFga6gKpeGxiS/zBu+HB0W2FvsrrLalTFIaPw/CGYACRBSIxqiCqwqTQ== - dependencies: - "@resolver-engine/imports" "^0.3.3" - "@resolver-engine/imports-fs" "^0.3.3" - "@typechain/ethers-v5" "^2.0.0" - "@types/mkdirp" "^0.5.2" - "@types/node-fetch" "^2.5.5" - ethers "^5.0.1" - mkdirp "^0.5.1" - node-fetch "^2.6.1" - solc "^0.6.3" - ts-generator "^0.1.1" - typechain "^3.0.0" - -"@ethereum-waffle/ens@^3.4.4": - version "3.4.4" - resolved "https://registry.yarnpkg.com/@ethereum-waffle/ens/-/ens-3.4.4.tgz#db97ea2c9decbb70b9205d53de2ccbd6f3182ba1" - integrity sha512-0m4NdwWxliy3heBYva1Wr4WbJKLnwXizmy5FfSSr5PMbjI7SIGCdCB59U7/ZzY773/hY3bLnzLwvG5mggVjJWg== - dependencies: - "@ensdomains/ens" "^0.4.4" - "@ensdomains/resolver" "^0.2.4" - ethers "^5.5.2" - -"@ethereum-waffle/mock-contract@^3.4.4": - version "3.4.4" - resolved "https://registry.yarnpkg.com/@ethereum-waffle/mock-contract/-/mock-contract-3.4.4.tgz#fc6ffa18813546f4950a69f5892d4dd54b2c685a" - integrity sha512-Mp0iB2YNWYGUV+VMl5tjPsaXKbKo8MDH9wSJ702l9EBjdxFf/vBvnMBAC1Fub1lLtmD0JHtp1pq+mWzg/xlLnA== - dependencies: - "@ethersproject/abi" "^5.5.0" - ethers "^5.5.2" - -"@ethereum-waffle/provider@^3.4.4": - version "3.4.4" - resolved "https://registry.yarnpkg.com/@ethereum-waffle/provider/-/provider-3.4.4.tgz#398fc1f7eb91cc2df7d011272eacba8af0c7fffb" - integrity sha512-GK8oKJAM8+PKy2nK08yDgl4A80mFuI8zBkE0C9GqTRYQqvuxIyXoLmJ5NZU9lIwyWVv5/KsoA11BgAv2jXE82g== - dependencies: - "@ethereum-waffle/ens" "^3.4.4" - ethers "^5.5.2" - ganache-core "^2.13.2" - patch-package "^6.2.2" - postinstall-postinstall "^2.1.0" - -"@ethereumjs/rlp@^4.0.1": - version "4.0.1" - resolved "https://registry.yarnpkg.com/@ethereumjs/rlp/-/rlp-4.0.1.tgz#626fabfd9081baab3d0a3074b0c7ecaf674aaa41" - integrity sha512-tqsQiBQDQdmPWE1xkkBq4rlSW5QZpLOUJ5RJh2/9fug+q9tnUhuZoVLk7s0scUIKTOzEtR72DFBXI4WiZcMpvw== - -"@ethereumjs/util@^8.1.0": - version "8.1.0" - resolved "https://registry.yarnpkg.com/@ethereumjs/util/-/util-8.1.0.tgz#299df97fb6b034e0577ce9f94c7d9d1004409ed4" - integrity sha512-zQ0IqbdX8FZ9aw11vP+dZkKDkS+kgIvQPHnSAXzP9pLu+Rfu3D3XEeLbicvoXJTYnhZiPmsZUxgdzXwNKxRPbA== - dependencies: - "@ethereumjs/rlp" "^4.0.1" - ethereum-cryptography "^2.0.0" - micro-ftch "^0.3.1" - -"@ethersproject/abi@5.0.0-beta.153": - version "5.0.0-beta.153" - resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.0.0-beta.153.tgz#43a37172b33794e4562999f6e2d555b7599a8eee" - 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/abi@5.6.1", "@ethersproject/abi@^5.0.0-beta.146", "@ethersproject/abi@^5.1.2", "@ethersproject/abi@^5.5.0", "@ethersproject/abi@^5.6.0": - version "5.6.1" - resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.6.1.tgz#f7de888edeb56b0a657b672bdd1b3a1135cd14f7" - integrity sha512-0cqssYh6FXjlwKWBmLm3+zH2BNARoS5u/hxbz+LpQmcDB3w0W553h2btWui1/uZp2GBM/SI3KniTuMcYyHpA5w== - dependencies: - "@ethersproject/address" "^5.6.0" - "@ethersproject/bignumber" "^5.6.0" - "@ethersproject/bytes" "^5.6.0" - "@ethersproject/constants" "^5.6.0" - "@ethersproject/hash" "^5.6.0" - "@ethersproject/keccak256" "^5.6.0" - "@ethersproject/logger" "^5.6.0" - "@ethersproject/properties" "^5.6.0" - "@ethersproject/strings" "^5.6.0" - -"@ethersproject/abi@^5.0.9": - 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.6.0", "@ethersproject/abstract-provider@^5.6.0": - version "5.6.0" - resolved "https://registry.yarnpkg.com/@ethersproject/abstract-provider/-/abstract-provider-5.6.0.tgz#0c4ac7054650dbd9c476cf5907f588bbb6ef3061" - integrity sha512-oPMFlKLN+g+y7a79cLK3WiLcjWFnZQtXWgnLAbHZcN3s7L4v90UHpTOrLk+m3yr0gt+/h9STTM6zrr7PM8uoRw== - dependencies: - "@ethersproject/bignumber" "^5.6.0" - "@ethersproject/bytes" "^5.6.0" - "@ethersproject/logger" "^5.6.0" - "@ethersproject/networks" "^5.6.0" - "@ethersproject/properties" "^5.6.0" - "@ethersproject/transactions" "^5.6.0" - "@ethersproject/web" "^5.6.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.6.0", "@ethersproject/abstract-signer@^5.6.0": - version "5.6.0" - resolved "https://registry.yarnpkg.com/@ethersproject/abstract-signer/-/abstract-signer-5.6.0.tgz#9cd7ae9211c2b123a3b29bf47aab17d4d016e3e7" - integrity sha512-WOqnG0NJKtI8n0wWZPReHtaLkDByPL67tn4nBaDAhmVq8sjHTPbCdz4DRhVu/cfTOvfy9w3iq5QZ7BX7zw56BQ== - dependencies: - "@ethersproject/abstract-provider" "^5.6.0" - "@ethersproject/bignumber" "^5.6.0" - "@ethersproject/bytes" "^5.6.0" - "@ethersproject/logger" "^5.6.0" - "@ethersproject/properties" "^5.6.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.6.0", "@ethersproject/address@>=5.0.0-beta.128", "@ethersproject/address@^5.0.2", "@ethersproject/address@^5.6.0": - version "5.6.0" - resolved "https://registry.yarnpkg.com/@ethersproject/address/-/address-5.6.0.tgz#13c49836d73e7885fc148ad633afad729da25012" - integrity sha512-6nvhYXjbXsHPS+30sHZ+U4VMagFC/9zAk6Gd/h3S21YW4+yfb0WfRtaAIZ4kfM4rrVwqiy284LP0GtL5HXGLxQ== - dependencies: - "@ethersproject/bignumber" "^5.6.0" - "@ethersproject/bytes" "^5.6.0" - "@ethersproject/keccak256" "^5.6.0" - "@ethersproject/logger" "^5.6.0" - "@ethersproject/rlp" "^5.6.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.6.0", "@ethersproject/base64@^5.6.0": - version "5.6.0" - resolved "https://registry.yarnpkg.com/@ethersproject/base64/-/base64-5.6.0.tgz#a12c4da2a6fb86d88563216b0282308fc15907c9" - integrity sha512-2Neq8wxJ9xHxCF9TUgmKeSh9BXJ6OAxWfeGWvbauPh8FuHEjamgHilllx8KkSd5ErxyHIX7Xv3Fkcud2kY9ezw== - dependencies: - "@ethersproject/bytes" "^5.6.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.6.0", "@ethersproject/basex@^5.6.0": - version "5.6.0" - resolved "https://registry.yarnpkg.com/@ethersproject/basex/-/basex-5.6.0.tgz#9ea7209bf0a1c3ddc2a90f180c3a7f0d7d2e8a69" - integrity sha512-qN4T+hQd/Md32MoJpc69rOwLYRUXwjTlhHDIeUkUmiN/JyWkkLLMoG0TqvSQKNqZOMgN5stbUYN6ILC+eD7MEQ== - dependencies: - "@ethersproject/bytes" "^5.6.0" - "@ethersproject/properties" "^5.6.0" - -"@ethersproject/bignumber@5.6.0", "@ethersproject/bignumber@>=5.0.0-beta.130", "@ethersproject/bignumber@^5.6.0": - version "5.6.0" - resolved "https://registry.yarnpkg.com/@ethersproject/bignumber/-/bignumber-5.6.0.tgz#116c81b075c57fa765a8f3822648cf718a8a0e26" - integrity sha512-VziMaXIUHQlHJmkv1dlcd6GY2PmT0khtAqaMctCIDogxkrarMzA9L94KN1NeXqqOfFD6r0sJT3vCTOFSmZ07DA== - dependencies: - "@ethersproject/bytes" "^5.6.0" - "@ethersproject/logger" "^5.6.0" - bn.js "^4.11.9" - -"@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.6.1", "@ethersproject/bytes@>=5.0.0-beta.129", "@ethersproject/bytes@^5.6.0": - version "5.6.1" - resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.6.1.tgz#24f916e411f82a8a60412344bf4a813b917eefe7" - integrity sha512-NwQt7cKn5+ZE4uDn+X5RAXLp46E1chXoaMmrxAyA0rblpxz8t58lVkrHXoRIn0lz1joQElQ8410GqhTqMOwc6g== - dependencies: - "@ethersproject/logger" "^5.6.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.6.0", "@ethersproject/constants@>=5.0.0-beta.128", "@ethersproject/constants@^5.6.0": - version "5.6.0" - resolved "https://registry.yarnpkg.com/@ethersproject/constants/-/constants-5.6.0.tgz#55e3eb0918584d3acc0688e9958b0cedef297088" - integrity sha512-SrdaJx2bK0WQl23nSpV/b1aq293Lh0sUaZT/yYKPDKn4tlAbkH96SPJwIhwSwTsoQQZxuh1jnqsKwyymoiBdWA== - dependencies: - "@ethersproject/bignumber" "^5.6.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.6.0": - version "5.6.0" - resolved "https://registry.yarnpkg.com/@ethersproject/contracts/-/contracts-5.6.0.tgz#60f2cfc7addd99a865c6c8cfbbcec76297386067" - integrity sha512-74Ge7iqTDom0NX+mux8KbRUeJgu1eHZ3iv6utv++sLJG80FVuU9HnHeKVPfjd9s3woFhaFoQGf3B3iH/FrQmgw== - dependencies: - "@ethersproject/abi" "^5.6.0" - "@ethersproject/abstract-provider" "^5.6.0" - "@ethersproject/abstract-signer" "^5.6.0" - "@ethersproject/address" "^5.6.0" - "@ethersproject/bignumber" "^5.6.0" - "@ethersproject/bytes" "^5.6.0" - "@ethersproject/constants" "^5.6.0" - "@ethersproject/logger" "^5.6.0" - "@ethersproject/properties" "^5.6.0" - "@ethersproject/transactions" "^5.6.0" - -"@ethersproject/hash@5.6.0", "@ethersproject/hash@>=5.0.0-beta.128", "@ethersproject/hash@^5.6.0": - version "5.6.0" - resolved "https://registry.yarnpkg.com/@ethersproject/hash/-/hash-5.6.0.tgz#d24446a5263e02492f9808baa99b6e2b4c3429a2" - integrity sha512-fFd+k9gtczqlr0/BruWLAu7UAOas1uRRJvOR84uDf4lNZ+bTkGl366qvniUZHKtlqxBRU65MkOobkmvmpHU+jA== - dependencies: - "@ethersproject/abstract-signer" "^5.6.0" - "@ethersproject/address" "^5.6.0" - "@ethersproject/bignumber" "^5.6.0" - "@ethersproject/bytes" "^5.6.0" - "@ethersproject/keccak256" "^5.6.0" - "@ethersproject/logger" "^5.6.0" - "@ethersproject/properties" "^5.6.0" - "@ethersproject/strings" "^5.6.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.6.0", "@ethersproject/hdnode@^5.6.0": - version "5.6.0" - resolved "https://registry.yarnpkg.com/@ethersproject/hdnode/-/hdnode-5.6.0.tgz#9dcbe8d629bbbcf144f2cae476337fe92d320998" - integrity sha512-61g3Jp3nwDqJcL/p4nugSyLrpl/+ChXIOtCEM8UDmWeB3JCAt5FoLdOMXQc3WWkc0oM2C0aAn6GFqqMcS/mHTw== - dependencies: - "@ethersproject/abstract-signer" "^5.6.0" - "@ethersproject/basex" "^5.6.0" - "@ethersproject/bignumber" "^5.6.0" - "@ethersproject/bytes" "^5.6.0" - "@ethersproject/logger" "^5.6.0" - "@ethersproject/pbkdf2" "^5.6.0" - "@ethersproject/properties" "^5.6.0" - "@ethersproject/sha2" "^5.6.0" - "@ethersproject/signing-key" "^5.6.0" - "@ethersproject/strings" "^5.6.0" - "@ethersproject/transactions" "^5.6.0" - "@ethersproject/wordlists" "^5.6.0" - -"@ethersproject/json-wallets@5.6.0", "@ethersproject/json-wallets@^5.6.0": - version "5.6.0" - resolved "https://registry.yarnpkg.com/@ethersproject/json-wallets/-/json-wallets-5.6.0.tgz#4c2fc27f17e36c583e7a252fb938bc46f98891e5" - integrity sha512-fmh86jViB9r0ibWXTQipxpAGMiuxoqUf78oqJDlCAJXgnJF024hOOX7qVgqsjtbeoxmcLwpPsXNU0WEe/16qPQ== - dependencies: - "@ethersproject/abstract-signer" "^5.6.0" - "@ethersproject/address" "^5.6.0" - "@ethersproject/bytes" "^5.6.0" - "@ethersproject/hdnode" "^5.6.0" - "@ethersproject/keccak256" "^5.6.0" - "@ethersproject/logger" "^5.6.0" - "@ethersproject/pbkdf2" "^5.6.0" - "@ethersproject/properties" "^5.6.0" - "@ethersproject/random" "^5.6.0" - "@ethersproject/strings" "^5.6.0" - "@ethersproject/transactions" "^5.6.0" - aes-js "3.0.0" - scrypt-js "3.0.1" - -"@ethersproject/keccak256@5.6.0", "@ethersproject/keccak256@>=5.0.0-beta.127", "@ethersproject/keccak256@^5.6.0": - version "5.6.0" - resolved "https://registry.yarnpkg.com/@ethersproject/keccak256/-/keccak256-5.6.0.tgz#fea4bb47dbf8f131c2e1774a1cecbfeb9d606459" - integrity sha512-tk56BJ96mdj/ksi7HWZVWGjCq0WVl/QvfhFQNeL8fxhBlGoP+L80uDCiQcpJPd+2XxkivS3lwRm3E0CXTfol0w== - dependencies: - "@ethersproject/bytes" "^5.6.0" - js-sha3 "0.8.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.6.0", "@ethersproject/logger@>=5.0.0-beta.129", "@ethersproject/logger@^5.6.0": - version "5.6.0" - resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.6.0.tgz#d7db1bfcc22fd2e4ab574cba0bb6ad779a9a3e7a" - integrity sha512-BiBWllUROH9w+P21RzoxJKzqoqpkyM1pRnEKG69bulE9TSQD8SAIvTQqIMZmmCO8pUNkgLP1wndX1gKghSpBmg== - -"@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.6.2", "@ethersproject/networks@^5.6.0": - version "5.6.2" - resolved "https://registry.yarnpkg.com/@ethersproject/networks/-/networks-5.6.2.tgz#2bacda62102c0b1fcee408315f2bed4f6fbdf336" - integrity sha512-9uEzaJY7j5wpYGTojGp8U89mSsgQLc40PCMJLMCnFXTs7nhBveZ0t7dbqWUNrepWTszDbFkYD6WlL8DKx5huHA== - dependencies: - "@ethersproject/logger" "^5.6.0" - -"@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.6.0", "@ethersproject/pbkdf2@^5.6.0": - version "5.6.0" - resolved "https://registry.yarnpkg.com/@ethersproject/pbkdf2/-/pbkdf2-5.6.0.tgz#04fcc2d7c6bff88393f5b4237d906a192426685a" - integrity sha512-Wu1AxTgJo3T3H6MIu/eejLFok9TYoSdgwRr5oGY1LTLfmGesDoSx05pemsbrPT2gG4cQME+baTSCp5sEo2erZQ== - dependencies: - "@ethersproject/bytes" "^5.6.0" - "@ethersproject/sha2" "^5.6.0" - -"@ethersproject/properties@5.6.0", "@ethersproject/properties@>=5.0.0-beta.131", "@ethersproject/properties@^5.6.0": - version "5.6.0" - resolved "https://registry.yarnpkg.com/@ethersproject/properties/-/properties-5.6.0.tgz#38904651713bc6bdd5bdd1b0a4287ecda920fa04" - integrity sha512-szoOkHskajKePTJSZ46uHUWWkbv7TzP2ypdEK6jGMqJaEt2sb0jCgfBo0gH0m2HBpRixMuJ6TBRaQCF7a9DoCg== - dependencies: - "@ethersproject/logger" "^5.6.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.6.4": - version "5.6.4" - resolved "https://registry.yarnpkg.com/@ethersproject/providers/-/providers-5.6.4.tgz#1a49c211b57b0b2703c320819abbbfa35c83dff7" - integrity sha512-WAdknnaZ52hpHV3qPiJmKx401BLpup47h36Axxgre9zT+doa/4GC/Ne48ICPxTm0BqndpToHjpLP1ZnaxyE+vw== - dependencies: - "@ethersproject/abstract-provider" "^5.6.0" - "@ethersproject/abstract-signer" "^5.6.0" - "@ethersproject/address" "^5.6.0" - "@ethersproject/basex" "^5.6.0" - "@ethersproject/bignumber" "^5.6.0" - "@ethersproject/bytes" "^5.6.0" - "@ethersproject/constants" "^5.6.0" - "@ethersproject/hash" "^5.6.0" - "@ethersproject/logger" "^5.6.0" - "@ethersproject/networks" "^5.6.0" - "@ethersproject/properties" "^5.6.0" - "@ethersproject/random" "^5.6.0" - "@ethersproject/rlp" "^5.6.0" - "@ethersproject/sha2" "^5.6.0" - "@ethersproject/strings" "^5.6.0" - "@ethersproject/transactions" "^5.6.0" - "@ethersproject/web" "^5.6.0" - bech32 "1.1.4" - ws "7.4.6" - -"@ethersproject/random@5.6.0", "@ethersproject/random@^5.6.0": - version "5.6.0" - resolved "https://registry.yarnpkg.com/@ethersproject/random/-/random-5.6.0.tgz#1505d1ab6a250e0ee92f436850fa3314b2cb5ae6" - integrity sha512-si0PLcLjq+NG/XHSZz90asNf+YfKEqJGVdxoEkSukzbnBgC8rydbgbUgBbBGLeHN4kAJwUFEKsu3sCXT93YMsw== - dependencies: - "@ethersproject/bytes" "^5.6.0" - "@ethersproject/logger" "^5.6.0" - -"@ethersproject/rlp@5.6.0", "@ethersproject/rlp@^5.6.0": - version "5.6.0" - resolved "https://registry.yarnpkg.com/@ethersproject/rlp/-/rlp-5.6.0.tgz#55a7be01c6f5e64d6e6e7edb6061aa120962a717" - integrity sha512-dz9WR1xpcTL+9DtOT/aDO+YyxSSdO8YIS0jyZwHHSlAmnxA6cKU3TrTd4Xc/bHayctxTgGLYNuVVoiXE4tTq1g== - dependencies: - "@ethersproject/bytes" "^5.6.0" - "@ethersproject/logger" "^5.6.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.6.0", "@ethersproject/sha2@^5.6.0": - version "5.6.0" - resolved "https://registry.yarnpkg.com/@ethersproject/sha2/-/sha2-5.6.0.tgz#364c4c11cc753bda36f31f001628706ebadb64d9" - integrity sha512-1tNWCPFLu1n3JM9t4/kytz35DkuF9MxqkGGEHNauEbaARdm2fafnOyw1s0tIQDPKF/7bkP1u3dbrmjpn5CelyA== - dependencies: - "@ethersproject/bytes" "^5.6.0" - "@ethersproject/logger" "^5.6.0" - hash.js "1.1.7" - -"@ethersproject/signing-key@5.6.0", "@ethersproject/signing-key@^5.6.0": - version "5.6.0" - resolved "https://registry.yarnpkg.com/@ethersproject/signing-key/-/signing-key-5.6.0.tgz#4f02e3fb09e22b71e2e1d6dc4bcb5dafa69ce042" - integrity sha512-S+njkhowmLeUu/r7ir8n78OUKx63kBdMCPssePS89So1TH4hZqnWFsThEd/GiXYp9qMxVrydf7KdM9MTGPFukA== - dependencies: - "@ethersproject/bytes" "^5.6.0" - "@ethersproject/logger" "^5.6.0" - "@ethersproject/properties" "^5.6.0" - bn.js "^4.11.9" - elliptic "6.5.4" - hash.js "1.1.7" - -"@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.6.0": - version "5.6.0" - resolved "https://registry.yarnpkg.com/@ethersproject/solidity/-/solidity-5.6.0.tgz#64657362a596bf7f5630bdc921c07dd78df06dc3" - integrity sha512-YwF52vTNd50kjDzqKaoNNbC/r9kMDPq3YzDWmsjFTRBcIF1y4JCQJ8gB30wsTfHbaxgxelI5BfxQSxD/PbJOww== - dependencies: - "@ethersproject/bignumber" "^5.6.0" - "@ethersproject/bytes" "^5.6.0" - "@ethersproject/keccak256" "^5.6.0" - "@ethersproject/logger" "^5.6.0" - "@ethersproject/sha2" "^5.6.0" - "@ethersproject/strings" "^5.6.0" - -"@ethersproject/strings@5.6.0", "@ethersproject/strings@>=5.0.0-beta.130", "@ethersproject/strings@^5.6.0": - version "5.6.0" - resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.6.0.tgz#9891b26709153d996bf1303d39a7f4bc047878fd" - integrity sha512-uv10vTtLTZqrJuqBZR862ZQjTIa724wGPWQqZrofaPI/kUsf53TBG0I0D+hQ1qyNtllbNzaW+PDPHHUI6/65Mg== - dependencies: - "@ethersproject/bytes" "^5.6.0" - "@ethersproject/constants" "^5.6.0" - "@ethersproject/logger" "^5.6.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.6.0", "@ethersproject/transactions@^5.0.0-beta.135", "@ethersproject/transactions@^5.6.0": - version "5.6.0" - resolved "https://registry.yarnpkg.com/@ethersproject/transactions/-/transactions-5.6.0.tgz#4b594d73a868ef6e1529a2f8f94a785e6791ae4e" - integrity sha512-4HX+VOhNjXHZyGzER6E/LVI2i6lf9ejYeWD6l4g50AdmimyuStKc39kvKf1bXWQMg7QNVh+uC7dYwtaZ02IXeg== - dependencies: - "@ethersproject/address" "^5.6.0" - "@ethersproject/bignumber" "^5.6.0" - "@ethersproject/bytes" "^5.6.0" - "@ethersproject/constants" "^5.6.0" - "@ethersproject/keccak256" "^5.6.0" - "@ethersproject/logger" "^5.6.0" - "@ethersproject/properties" "^5.6.0" - "@ethersproject/rlp" "^5.6.0" - "@ethersproject/signing-key" "^5.6.0" - -"@ethersproject/transactions@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/transactions/-/transactions-5.7.0.tgz#91318fc24063e057885a6af13fdb703e1f993d3b" - integrity sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ== - dependencies: - "@ethersproject/address" "^5.7.0" - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/constants" "^5.7.0" - "@ethersproject/keccak256" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/rlp" "^5.7.0" - "@ethersproject/signing-key" "^5.7.0" - -"@ethersproject/units@5.6.0": - version "5.6.0" - resolved "https://registry.yarnpkg.com/@ethersproject/units/-/units-5.6.0.tgz#e5cbb1906988f5740254a21b9ded6bd51e826d9c" - integrity sha512-tig9x0Qmh8qbo1w8/6tmtyrm/QQRviBh389EQ+d8fP4wDsBrJBf08oZfoiz1/uenKK9M78yAP4PoR7SsVoTjsw== - dependencies: - "@ethersproject/bignumber" "^5.6.0" - "@ethersproject/constants" "^5.6.0" - "@ethersproject/logger" "^5.6.0" - -"@ethersproject/wallet@5.6.0": - version "5.6.0" - resolved "https://registry.yarnpkg.com/@ethersproject/wallet/-/wallet-5.6.0.tgz#33d11a806d783864208f348709a5a3badac8e22a" - integrity sha512-qMlSdOSTyp0MBeE+r7SUhr1jjDlC1zAXB8VD84hCnpijPQiSNbxr6GdiLXxpUs8UKzkDiNYYC5DRI3MZr+n+tg== - dependencies: - "@ethersproject/abstract-provider" "^5.6.0" - "@ethersproject/abstract-signer" "^5.6.0" - "@ethersproject/address" "^5.6.0" - "@ethersproject/bignumber" "^5.6.0" - "@ethersproject/bytes" "^5.6.0" - "@ethersproject/hash" "^5.6.0" - "@ethersproject/hdnode" "^5.6.0" - "@ethersproject/json-wallets" "^5.6.0" - "@ethersproject/keccak256" "^5.6.0" - "@ethersproject/logger" "^5.6.0" - "@ethersproject/properties" "^5.6.0" - "@ethersproject/random" "^5.6.0" - "@ethersproject/signing-key" "^5.6.0" - "@ethersproject/transactions" "^5.6.0" - "@ethersproject/wordlists" "^5.6.0" - -"@ethersproject/web@5.6.0", "@ethersproject/web@^5.6.0": - version "5.6.0" - resolved "https://registry.yarnpkg.com/@ethersproject/web/-/web-5.6.0.tgz#4bf8b3cbc17055027e1a5dd3c357e37474eaaeb8" - integrity sha512-G/XHj0hV1FxI2teHRfCGvfBUHFmU+YOSbCxlAMqJklxSa7QMiHFQfAxvwY2PFqgvdkxEKwRNr/eCjfAPEm2Ctg== - dependencies: - "@ethersproject/base64" "^5.6.0" - "@ethersproject/bytes" "^5.6.0" - "@ethersproject/logger" "^5.6.0" - "@ethersproject/properties" "^5.6.0" - "@ethersproject/strings" "^5.6.0" - -"@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.6.0", "@ethersproject/wordlists@^5.6.0": - version "5.6.0" - resolved "https://registry.yarnpkg.com/@ethersproject/wordlists/-/wordlists-5.6.0.tgz#79e62c5276e091d8575f6930ba01a29218ded032" - integrity sha512-q0bxNBfIX3fUuAo9OmjlEYxP40IB8ABgb7HjEZCL5IKubzV3j30CWi2rqQbjTS2HfoyQbfINoKcTVWP4ejwR7Q== - dependencies: - "@ethersproject/bytes" "^5.6.0" - "@ethersproject/hash" "^5.6.0" - "@ethersproject/logger" "^5.6.0" - "@ethersproject/properties" "^5.6.0" - "@ethersproject/strings" "^5.6.0" - -"@fastify/busboy@^2.0.0": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@fastify/busboy/-/busboy-2.1.1.tgz#b9da6a878a371829a0502c9b6c1c143ef6663f4d" - integrity sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA== - -"@humanwhocodes/config-array@^0.11.14": - version "0.11.14" - resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.14.tgz#d78e481a039f7566ecc9660b4ea7fe6b1fec442b" - integrity sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg== - dependencies: - "@humanwhocodes/object-schema" "^2.0.2" - debug "^4.3.1" - minimatch "^3.0.5" - -"@humanwhocodes/module-importer@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" - integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== - -"@humanwhocodes/object-schema@^2.0.2": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz#d9fae00a2d5cb40f92cfe64b47ad749fbc38f917" - integrity sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw== - -"@iden3/bigarray@0.0.2": - version "0.0.2" - resolved "https://registry.yarnpkg.com/@iden3/bigarray/-/bigarray-0.0.2.tgz#6fc4ba5be18daf8a26ee393f2fb62b80d98c05e9" - integrity sha512-Xzdyxqm1bOFF6pdIsiHLLl3HkSLjbhqJHVyqaTxXt3RqXBEnmsUmEW47H7VOi/ak7TdkRpNkxjyK5Zbkm+y52g== - -"@metamask/eth-sig-util@^4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@metamask/eth-sig-util/-/eth-sig-util-4.0.0.tgz#11553ba06de0d1352332c1bde28c8edd00e0dcf6" - integrity sha512-LczOjjxY4A7XYloxzyxJIHONELmUxVZncpOLoClpEcTiebiVdM46KRPYXGuULro9oNNR2xdVx3yoKiQjdfWmoA== - dependencies: - ethereumjs-abi "^0.6.8" - ethereumjs-util "^6.2.1" - ethjs-util "^0.1.6" - tweetnacl "^1.0.3" - tweetnacl-util "^0.15.1" - -"@noble/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/curves@1.3.0", "@noble/curves@~1.3.0": - version "1.3.0" - resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.3.0.tgz#01be46da4fd195822dab821e72f71bf4aeec635e" - integrity sha512-t01iSXPuN+Eqzb4eBX0S5oubSqXbK/xXa1Ne18Hj8f9pStxztHCE2gfboSp/dZRLSqfuLpRK2nDXDK+W9puocA== - dependencies: - "@noble/hashes" "1.3.3" - -"@noble/hashes@1.0.0", "@noble/hashes@~1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.0.0.tgz#d5e38bfbdaba174805a4e649f13be9a9ed3351ae" - integrity sha512-DZVbtY62kc3kkBtMHqwCOfXrT/hnoORy5BJ4+HU1IR59X0KWAOqsfzQPcUl/lQLlG7qXbe/fZ3r/emxtAl+sqg== - -"@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/hashes@1.3.3", "@noble/hashes@~1.3.2": - version "1.3.3" - resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.3.tgz#39908da56a4adc270147bb07968bf3b16cfe1699" - integrity sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA== - -"@noble/secp256k1@1.5.5", "@noble/secp256k1@~1.5.2": - version "1.5.5" - resolved "https://registry.yarnpkg.com/@noble/secp256k1/-/secp256k1-1.5.5.tgz#315ab5745509d1a8c8e90d0bdf59823ccf9bcfc3" - integrity sha512-sZ1W6gQzYnu45wPrWx8D3kwI2/U29VYTx9OjbDAd7jwRItJ0cSTMPRL/C8AWZFn9kWFLQGqEXVEE86w4Z8LpIQ== - -"@nodelib/fs.scandir@2.1.5": - version "2.1.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" - integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== - dependencies: - "@nodelib/fs.stat" "2.0.5" - run-parallel "^1.1.9" - -"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": - version "2.0.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" - integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== - -"@nodelib/fs.walk@^1.2.3", "@nodelib/fs.walk@^1.2.8": - version "1.2.8" - resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" - integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== - dependencies: - "@nodelib/fs.scandir" "2.1.5" - fastq "^1.6.0" - -"@nomicfoundation/edr-darwin-arm64@0.3.1": - version "0.3.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-darwin-arm64/-/edr-darwin-arm64-0.3.1.tgz#386cbb7dd8ba70659d76d6ce5e8b06242fac6c8c" - integrity sha512-qsdGS1Kfp6bVH4fk4hUzbsEm0fH7hGurraKk+IWby7Ecv+u7BuNaLVqeoYauYRFLYnGg8XZmcKOJ9BW35Y96Jg== - -"@nomicfoundation/edr-darwin-x64@0.3.1": - version "0.3.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-darwin-x64/-/edr-darwin-x64-0.3.1.tgz#809ebd68127fb7b4219c5ddc8ef65b38bc88312b" - integrity sha512-vtS2yuXIgjte42KEg/Aw/xmLRneVrIaDFhFMk578zg3m1UjNP+a29Lirw5fRXaqaL8aPyhRFmUy+1/V4MGaH+g== - -"@nomicfoundation/edr-linux-arm64-gnu@0.3.1": - version "0.3.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-arm64-gnu/-/edr-linux-arm64-gnu-0.3.1.tgz#897bf524e88d6a07a2b39c5a9c5d94eaeee6ec20" - integrity sha512-GrbQcrVjTFLm/x8HdUzmJ1F8Juau9UEZM/YNr4sAxxTGvBHJlq73VaDZfArxj9Anq/u6aImPbs1ksu28D6XC3A== - -"@nomicfoundation/edr-linux-arm64-musl@0.3.1": - version "0.3.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-arm64-musl/-/edr-linux-arm64-musl-0.3.1.tgz#726d57edee1adcd4844aaf31ec80063f1c44616b" - integrity sha512-wOqugcbugmbZkh58PcIC5naT0ilwkZ0/qH86AniENxsviOaPSrL4aMYhtfypQ3MNxlfrlgLZFCC+D5eJTsNsgQ== - -"@nomicfoundation/edr-linux-x64-gnu@0.3.1": - version "0.3.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-x64-gnu/-/edr-linux-x64-gnu-0.3.1.tgz#d45ca451a30d429ed4ea97982879bf65842385f8" - integrity sha512-V+kyUVqbt52dQRgaZK+EWuPWJ5h/PsCYZmiK18A+DQynZvird7jrTsDppcTvlv1Dvny8UAAP0q/ue7G67OoLJQ== - -"@nomicfoundation/edr-linux-x64-musl@0.3.1": - version "0.3.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-x64-musl/-/edr-linux-x64-musl-0.3.1.tgz#ee1d01135654124c0f22ae0c3e7d62388a41e595" - integrity sha512-vwrzLW40jQBDZVYmoJUBMwl36i7muB9AfT4F2fMRsb1JoOMgoeOBp8R+IAxbA6mjIJGwAClkRz5W5hCb3zMtMQ== - -"@nomicfoundation/edr-win32-arm64-msvc@0.3.1": - version "0.3.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-win32-arm64-msvc/-/edr-win32-arm64-msvc-0.3.1.tgz#e89c6e2c7a4458a6fd1de3ef3f57f915b771579e" - integrity sha512-7G29vUGrkwfbJqxo1V+QTxD976gVHx3Z0P5kwb1bErLmlP89cRNX3UN3/dzXpbKH9mp8ZcAjIcIbRUd4C+vH/A== - -"@nomicfoundation/edr-win32-ia32-msvc@0.3.1": - version "0.3.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-win32-ia32-msvc/-/edr-win32-ia32-msvc-0.3.1.tgz#8f05be496c18eff37e3a95628ed8265a03824df0" - integrity sha512-Q39eAkk/j1ZlvHcxQRTAzdY9qlckDNfiuJDgLYTlxdubpmX6KZucuUin/1A5NVhhCToTxw7aFwSglUROY3ejJw== - -"@nomicfoundation/edr-win32-x64-msvc@0.3.1": - version "0.3.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-win32-x64-msvc/-/edr-win32-x64-msvc-0.3.1.tgz#942c2b1490194d70d67c38b702a56e5603db19c7" - integrity sha512-8WzEzWUshw28xowVBhEyu4EQpx0TqNmDa70C3L1MWl5waym4U/VwbijFrI0Sb6Y1kdoNCdBTMvfr8OJNF2qJ/A== - -"@nomicfoundation/edr@^0.3.0": - version "0.3.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/edr/-/edr-0.3.1.tgz#2a7d4de8d70f63f872f9e86a8487f946cc3d2dcc" - integrity sha512-uPg1/CvIJpsCe7Ipe80bYnC/Q2Bt/O55KB2ssLx7Z0os4jwDvWBZas8tLMopT+hpOQnv8cZkHJap1iNDTwAfQg== - optionalDependencies: - "@nomicfoundation/edr-darwin-arm64" "0.3.1" - "@nomicfoundation/edr-darwin-x64" "0.3.1" - "@nomicfoundation/edr-linux-arm64-gnu" "0.3.1" - "@nomicfoundation/edr-linux-arm64-musl" "0.3.1" - "@nomicfoundation/edr-linux-x64-gnu" "0.3.1" - "@nomicfoundation/edr-linux-x64-musl" "0.3.1" - "@nomicfoundation/edr-win32-arm64-msvc" "0.3.1" - "@nomicfoundation/edr-win32-ia32-msvc" "0.3.1" - "@nomicfoundation/edr-win32-x64-msvc" "0.3.1" - -"@nomicfoundation/ethereumjs-common@4.0.4": - version "4.0.4" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-common/-/ethereumjs-common-4.0.4.tgz#9901f513af2d4802da87c66d6f255b510bef5acb" - integrity sha512-9Rgb658lcWsjiicr5GzNCjI1llow/7r0k50dLL95OJ+6iZJcVbi15r3Y0xh2cIO+zgX0WIHcbzIu6FeQf9KPrg== - dependencies: - "@nomicfoundation/ethereumjs-util" "9.0.4" - -"@nomicfoundation/ethereumjs-rlp@5.0.4": - version "5.0.4" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-rlp/-/ethereumjs-rlp-5.0.4.tgz#66c95256fc3c909f6fb18f6a586475fc9762fa30" - integrity sha512-8H1S3s8F6QueOc/X92SdrA4RDenpiAEqMg5vJH99kcQaCy/a3Q6fgseo75mgWlbanGJXSlAPtnCeG9jvfTYXlw== - -"@nomicfoundation/ethereumjs-tx@5.0.4": - version "5.0.4" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-tx/-/ethereumjs-tx-5.0.4.tgz#b0ceb58c98cc34367d40a30d255d6315b2f456da" - integrity sha512-Xjv8wAKJGMrP1f0n2PeyfFCCojHd7iS3s/Ab7qzF1S64kxZ8Z22LCMynArYsVqiFx6rzYy548HNVEyI+AYN/kw== - dependencies: - "@nomicfoundation/ethereumjs-common" "4.0.4" - "@nomicfoundation/ethereumjs-rlp" "5.0.4" - "@nomicfoundation/ethereumjs-util" "9.0.4" - ethereum-cryptography "0.1.3" - -"@nomicfoundation/ethereumjs-util@9.0.4": - version "9.0.4" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-util/-/ethereumjs-util-9.0.4.tgz#84c5274e82018b154244c877b76bc049a4ed7b38" - integrity sha512-sLOzjnSrlx9Bb9EFNtHzK/FJFsfg2re6bsGqinFinH1gCqVfz9YYlXiMWwDM4C/L4ywuHFCYwfKTVr/QHQcU0Q== - dependencies: - "@nomicfoundation/ethereumjs-rlp" "5.0.4" - ethereum-cryptography "0.1.3" - -"@nomicfoundation/hardhat-chai-matchers@^2.0.6": - version "2.0.6" - resolved "https://registry.yarnpkg.com/@nomicfoundation/hardhat-chai-matchers/-/hardhat-chai-matchers-2.0.6.tgz#ef88be3bd666adf29c06ac7882e96c8dbaaa32ba" - integrity sha512-Te1Uyo9oJcTCF0Jy9dztaLpshmlpjLf2yPtWXlXuLjMt3RRSmJLm/+rKVTW6gfadAEs12U/it6D0ZRnnRGiICQ== - 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.5": - version "3.0.5" - resolved "https://registry.yarnpkg.com/@nomicfoundation/hardhat-ethers/-/hardhat-ethers-3.0.5.tgz#0422c2123dec7c42e7fb2be8e1691f1d9708db56" - integrity sha512-RNFe8OtbZK6Ila9kIlHp0+S80/0Bu/3p41HUpaRIoHLm6X3WekTd83vob3rE54Duufu1edCiBDxspBzi2rxHHw== - dependencies: - debug "^4.1.1" - lodash.isequal "^4.5.0" - -"@nomicfoundation/hardhat-verify@^2.0.5": - version "2.0.5" - resolved "https://registry.yarnpkg.com/@nomicfoundation/hardhat-verify/-/hardhat-verify-2.0.5.tgz#dcc2cb5e5c55a39704c7d492436f80f05a4ca5a3" - integrity sha512-Tg4zu8RkWpyADSFIgF4FlJIUEI4VkxcvELsmbJn2OokbvH2SnUrqKmw0BBfDrtvP0hhmx8wsnrRKP5DV/oTyTA== - dependencies: - "@ethersproject/abi" "^5.1.2" - "@ethersproject/address" "^5.0.2" - cbor "^8.1.0" - chalk "^2.4.2" - debug "^4.1.1" - lodash.clonedeep "^4.5.0" - semver "^6.3.0" - table "^6.8.0" - undici "^5.14.0" - -"@nomicfoundation/solidity-analyzer-darwin-arm64@0.1.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" - -"@openzeppelin/contracts-upgradeable@^v4.9.3": - version "4.9.3" - resolved "https://registry.yarnpkg.com/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-4.9.3.tgz#ff17a80fb945f5102571f8efecb5ce5915cc4811" - integrity sha512-jjaHAVRMrE4UuZNfDwjlLGDxTHWIOwTJS2ldnc278a0gevfXfPr8hxKEVBGFBE96kl2G3VHDZhUimw/+G3TG2A== - -"@openzeppelin/contracts@^v4.9.3": - version "4.9.3" - resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.9.3.tgz#00d7a8cf35a475b160b3f0293a6403c511099364" - integrity sha512-He3LieZ1pP2TNt5JbkPA4PNT9WC3gOTOlDcFGJW4Le4QKqwmiNJCRt44APfxMxvq7OugU/cqYuPcSBzOw38DAg== - -"@primitivefi/hardhat-dodoc@^0.2.3": - version "0.2.3" - resolved "https://registry.yarnpkg.com/@primitivefi/hardhat-dodoc/-/hardhat-dodoc-0.2.3.tgz#76aebbfa70de2d6454af29e166b1430583b54c5c" - integrity sha512-ver9uHa79LTDTeebOKZ/eOVRL/FP1k0s0x/5Bo/8ZaDdLWFVClKqZyZYVjjW4CJqTPCt8uU9b9p71P2vzH4O9A== - dependencies: - squirrelly "^8.0.8" - -"@resolver-engine/core@^0.3.3": - version "0.3.3" - resolved "https://registry.yarnpkg.com/@resolver-engine/core/-/core-0.3.3.tgz#590f77d85d45bc7ecc4e06c654f41345db6ca967" - integrity sha512-eB8nEbKDJJBi5p5SrvrvILn4a0h42bKtbCTri3ZxCGt6UvoQyp7HnGOfki944bUjBSHKK3RvgfViHn+kqdXtnQ== - dependencies: - debug "^3.1.0" - is-url "^1.2.4" - request "^2.85.0" - -"@resolver-engine/fs@^0.3.3": - version "0.3.3" - resolved "https://registry.yarnpkg.com/@resolver-engine/fs/-/fs-0.3.3.tgz#fbf83fa0c4f60154a82c817d2fe3f3b0c049a973" - integrity sha512-wQ9RhPUcny02Wm0IuJwYMyAG8fXVeKdmhm8xizNByD4ryZlx6PP6kRen+t/haF43cMfmaV7T3Cx6ChOdHEhFUQ== - dependencies: - "@resolver-engine/core" "^0.3.3" - debug "^3.1.0" - -"@resolver-engine/imports-fs@^0.3.3": - version "0.3.3" - resolved "https://registry.yarnpkg.com/@resolver-engine/imports-fs/-/imports-fs-0.3.3.tgz#4085db4b8d3c03feb7a425fbfcf5325c0d1e6c1b" - integrity sha512-7Pjg/ZAZtxpeyCFlZR5zqYkz+Wdo84ugB5LApwriT8XFeQoLwGUj4tZFFvvCuxaNCcqZzCYbonJgmGObYBzyCA== - dependencies: - "@resolver-engine/fs" "^0.3.3" - "@resolver-engine/imports" "^0.3.3" - debug "^3.1.0" - -"@resolver-engine/imports@^0.3.3": - version "0.3.3" - resolved "https://registry.yarnpkg.com/@resolver-engine/imports/-/imports-0.3.3.tgz#badfb513bb3ff3c1ee9fd56073e3144245588bcc" - integrity sha512-anHpS4wN4sRMwsAbMXhMfOD/y4a4Oo0Cw/5+rue7hSwGWsDOQaAU1ClK1OxjUC35/peazxEl8JaSRRS+Xb8t3Q== - dependencies: - "@resolver-engine/core" "^0.3.3" - debug "^3.1.0" - hosted-git-info "^2.6.0" - path-browserify "^1.0.0" - url "^0.11.0" - -"@scure/base@~1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.0.0.tgz#109fb595021de285f05a7db6806f2f48296fcee7" - integrity sha512-gIVaYhUsy+9s58m/ETjSJVKHhKTBMmcRb9cEV5/5dwvfDlfORjKrFsDeDHWRrm6RjcPvCLZFwGJjAjLj1gg4HA== - -"@scure/base@~1.1.4": - version "1.1.5" - resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.5.tgz#1d85d17269fe97694b9c592552dd9e5e33552157" - integrity sha512-Brj9FiG2W1MRQSTB212YVPRrcbjkv48FoZi/u4l/zds/ieRrqsh7aUf6CLwkAq61oKXr/ZlTzlY66gLIj3TFTQ== - -"@scure/bip32@1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.0.1.tgz#1409bdf9f07f0aec99006bb0d5827693418d3aa5" - integrity sha512-AU88KKTpQ+YpTLoicZ/qhFhRRIo96/tlb+8YmDDHR9yiKVjSsFZiefJO4wjS2PMTkz5/oIcw84uAq/8pleQURA== - dependencies: - "@noble/hashes" "~1.0.0" - "@noble/secp256k1" "~1.5.2" - "@scure/base" "~1.0.0" - -"@scure/bip32@1.3.3": - version "1.3.3" - resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.3.3.tgz#a9624991dc8767087c57999a5d79488f48eae6c8" - integrity sha512-LJaN3HwRbfQK0X1xFSi0Q9amqOgzQnnDngIt+ZlsBC3Bm7/nE7K0kwshZHyaru79yIVRv/e1mQAjZyuZG6jOFQ== - dependencies: - "@noble/curves" "~1.3.0" - "@noble/hashes" "~1.3.2" - "@scure/base" "~1.1.4" - -"@scure/bip39@1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.0.0.tgz#47504e58de9a56a4bbed95159d2d6829fa491bb0" - integrity sha512-HrtcikLbd58PWOkl02k9V6nXWQyoa7A0+Ek9VF7z17DDk9XZAFUcIdqfh0jJXLypmizc5/8P6OxoUeKliiWv4w== - dependencies: - "@noble/hashes" "~1.0.0" - "@scure/base" "~1.0.0" - -"@scure/bip39@1.2.2": - version "1.2.2" - resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.2.2.tgz#f3426813f4ced11a47489cbcf7294aa963966527" - integrity sha512-HYf9TUXG80beW+hGAt3TRM8wU6pQoYur9iNypTROm42dorCGmLnFe3eWjz3gOq6G62H2WRh0FCzAR1PI+29zIA== - dependencies: - "@noble/hashes" "~1.3.2" - "@scure/base" "~1.1.4" - -"@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@^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== - -"@solidity-parser/parser@^0.14.0", "@solidity-parser/parser@^0.14.1": - version "0.14.1" - resolved "https://registry.yarnpkg.com/@solidity-parser/parser/-/parser-0.14.1.tgz#179afb29f4e295a77cc141151f26b3848abc3c46" - integrity sha512-eLjj2L6AuQjBB6s/ibwCAc0DwrR5Ge+ys+wgWo+bviU7fV2nTMQhU63CGaDKXg9iTmMxwhkyoggdIR7ZGRfMgw== - 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== - -"@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== - dependencies: - defer-to-connect "^1.0.1" - -"@tsconfig/node10@^1.0.7": - version "1.0.8" - resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.8.tgz#c1e4e80d6f964fbecb3359c43bd48b40f7cadad9" - integrity sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg== - -"@tsconfig/node12@^1.0.7": - version "1.0.9" - resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.9.tgz#62c1f6dee2ebd9aead80dc3afa56810e58e1a04c" - integrity sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw== - -"@tsconfig/node14@^1.0.0": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.1.tgz#95f2d167ffb9b8d2068b0b235302fafd4df711f2" - integrity sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg== - -"@tsconfig/node16@^1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.2.tgz#423c77877d0569db20e1fc80885ac4118314010e" - integrity sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA== - -"@typechain/ethers-v5@^2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@typechain/ethers-v5/-/ethers-v5-2.0.0.tgz#cd3ca1590240d587ca301f4c029b67bfccd08810" - integrity sha512-0xdCkyGOzdqh4h5JSf+zoWx85IusEjDcPIwNEHP8mrWSnCae4rvrqB+/gtpdNfX7zjlFlZiMeePn2r63EI3Lrw== - dependencies: - ethers "^5.0.2" - -"@typechain/ethers-v6@^0.5.1": - version "0.5.1" - resolved "https://registry.yarnpkg.com/@typechain/ethers-v6/-/ethers-v6-0.5.1.tgz#42fe214a19a8b687086c93189b301e2b878797ea" - integrity sha512-F+GklO8jBWlsaVV+9oHaPh5NJdd6rAKN4tklGfInX1Q7h0xPgVLP39Jl3eCulPB5qexI71ZFHwbljx4ZXNfouA== - dependencies: - lodash "^4.17.15" - ts-essentials "^7.0.1" - -"@typechain/hardhat@^9.1.0": - version "9.1.0" - resolved "https://registry.yarnpkg.com/@typechain/hardhat/-/hardhat-9.1.0.tgz#6985015f01dfb37ef2ca8a29c742d05890351ddc" - integrity sha512-mtaUlzLlkqTlfPwB3FORdejqBskSnh+Jl8AIJGjXNAQfRQ4ofHADPl1+oU7Z3pAJzmZbUXII8MhOLQltcHgKnA== - dependencies: - fs-extra "^9.1.0" - -"@types/bn.js@^4.11.3", "@types/bn.js@^4.11.5": - version "4.11.6" - resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-4.11.6.tgz#c306c70d9358aaea33cd4eda092a742b9505967c" - integrity sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg== - dependencies: - "@types/node" "*" - -"@types/bn.js@^5.1.0": - version "5.1.0" - resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-5.1.0.tgz#32c5d271503a12653c62cf4d2b45e6eab8cebc68" - integrity sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA== - dependencies: - "@types/node" "*" - -"@types/chai-as-promised@^7.1.3": - version "7.1.8" - resolved "https://registry.yarnpkg.com/@types/chai-as-promised/-/chai-as-promised-7.1.8.tgz#f2b3d82d53c59626b5d6bbc087667ccb4b677fe9" - integrity sha512-ThlRVIJhr69FLlh6IctTXFkmhtP3NpMZ2QGq69StYLyKZFp/HOp1VdKZj7RvfNWYYcJ1xlbLGLLWj1UvP5u/Gw== - dependencies: - "@types/chai" "*" - -"@types/chai@*": - version "4.3.12" - resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.3.12.tgz#b192fe1c553b54f45d20543adc2ab88455a07d5e" - integrity sha512-zNKDHG/1yxm8Il6uCCVsm+dRdEsJlFoDu73X17y09bId6UwoYww+vFBsAcRzl8knM1sab3Dp1VRikFQwDOtDDw== - -"@types/chai@^4.2.21": - version "4.3.1" - resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.3.1.tgz#e2c6e73e0bdeb2521d00756d099218e9f5d90a04" - integrity sha512-/zPMqDkzSZ8t3VtxOa4KPq7uzzW978M9Tvh+j7GHKuo6k6GTLxPJ4J5gE5cjfJ26pnXst0N5Hax8Sr0T2Mi9zQ== - -"@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/edit-json-file@^1.7.0": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@types/edit-json-file/-/edit-json-file-1.7.0.tgz#c3ab99b33ca8f018d412b2b6a1e3c7bf1a05f732" - integrity sha512-yZrbGD4Qp92s6xU80MWBdz9vJE8k8EbO+gLWYb4W1UL9WYVUMOtUr5zvKlKgbcc2veYmFLO9dPnYA9Mxul0lOw== - dependencies: - "@types/node" "*" - "@types/set-value" "*" - -"@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 sha1-yayFsqX9GENbjIXZ7LUObWyJP/g= - dependencies: - "@types/node" "*" - -"@types/glob@^7.1.1": - 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/json-schema@^7.0.12": - version "7.0.15" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" - integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== - -"@types/json5@^0.0.29": - version "0.0.29" - resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" - integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4= - -"@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 "3.0.5" - resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.5.tgz#1001cc5e6a3704b83c236027e77f2f58ea010f40" - integrity sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ== - -"@types/mkdirp@^0.5.2": - version "0.5.2" - resolved "https://registry.yarnpkg.com/@types/mkdirp/-/mkdirp-0.5.2.tgz#503aacfe5cc2703d5484326b1b27efa67a339c1f" - integrity sha512-U5icWpv7YnZYGsN4/cmh3WD2onMY0aJIiTE6+51TwJCttdHvtCYmkBNOobHlXwrJRL0nkH9jH4kD+1FAdMN4Tg== - dependencies: - "@types/node" "*" - -"@types/mocha@^9.0.0": - version "9.1.0" - resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-9.1.0.tgz#baf17ab2cca3fcce2d322ebc30454bff487efad5" - integrity sha512-QCWHkbMv4Y5U9oW10Uxbr45qMMSzl4OzijsozynUAgx3kEHUdXB00udx2dWDQ7f2TU2a2uuiFaRZjCe3unPpeg== - -"@types/node-fetch@^2.5.5": - version "2.6.1" - resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.6.1.tgz#8f127c50481db65886800ef496f20bbf15518975" - integrity sha512-oMqjURCaxoSIsHSr1E47QHzbmzNR5rK8McHuNb11BOM9cHcIK3Avy0s/b2JlXHoQGTYS3NsvWzV1M0iK7l0wbA== - dependencies: - "@types/node" "*" - form-data "^3.0.0" - -"@types/node@*": - version "17.0.24" - resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.24.tgz#20ba1bf69c1b4ab405c7a01e950c4f446b05029f" - integrity sha512-aveCYRQbgTH9Pssp1voEP7HiuWlD2jW2BO56w+bVrJn04i61yh6mRfoKO6hEYQD9vF+W8Chkwc6j1M36uPkx4g== - -"@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@^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.48" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.48.tgz#55f70bd432b6515828c0298689776861b90ca4fa" - integrity sha512-4kxzqkrpwYtn6okJUcb2lfUu9ilnb3yhUOH6qX3nug8D2DupZ2drIkff2yJzYcNJVl3begnlcaBJ7tqiTTzjnQ== - -"@types/node@^20.11.27": - version "20.11.27" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.11.27.tgz#debe5cfc8a507dd60fe2a3b4875b1604f215c2ac" - integrity sha512-qyUZfMnCg1KEz57r7pzFtSGt49f6RPkPBis3Vo4PbS7roQEDn22hiHzl/Lo1q4i4hDEgBJmBF/NTNg2XR0HbFg== - dependencies: - undici-types "~5.26.4" - -"@types/node@^8.0.0": - version "8.10.66" - resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.66.tgz#dd035d409df322acc83dff62a602f12a5783bbb3" - integrity sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw== - -"@types/pbkdf2@^3.0.0": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@types/pbkdf2/-/pbkdf2-3.1.0.tgz#039a0e9b67da0cdc4ee5dab865caa6b267bb66b1" - integrity sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ== - dependencies: - "@types/node" "*" - -"@types/prettier@^2.1.1": - version "2.6.0" - resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.6.0.tgz#efcbd41937f9ae7434c714ab698604822d890759" - integrity sha512-G/AdOadiZhnJp0jXCaBQU449W2h716OW/EoXeYkCytxKL06X1WCXB4DZpp8TpZ8eyIJVS1cw4lrlkkSYU21cDw== - -"@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/resolve@^0.0.8": - version "0.0.8" - resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-0.0.8.tgz#f26074d238e02659e323ce1a13d041eee280e194" - integrity sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ== - dependencies: - "@types/node" "*" - -"@types/secp256k1@^4.0.1": - version "4.0.3" - resolved "https://registry.yarnpkg.com/@types/secp256k1/-/secp256k1-4.0.3.tgz#1b8e55d8e00f08ee7220b4d59a6abe89c37a901c" - integrity sha512-Da66lEIFeIz9ltsdMZcpQvmrmmoqrfju8pm1BH8WbYjZSwUgCwXLb9C+9XYogwBITnbsSaMdVPb2ekf7TV+03w== - dependencies: - "@types/node" "*" - -"@types/semver@^7.5.0": - version "7.5.8" - resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.8.tgz#8268a8c57a3e4abd25c165ecd36237db7948a55e" - integrity sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ== - -"@types/set-value@*": - version "4.0.1" - resolved "https://registry.yarnpkg.com/@types/set-value/-/set-value-4.0.1.tgz#7caf185556a67c2d9051080931853047423c93bd" - integrity sha512-mP/CLy6pdrhsDVrz1+Yp5Ly6Tcel2IAEejhyI5NxY6WnBUdWN+AAfGa0HHsdgCdsPWWcd/4D5J2X2TrRYcYRag== - -"@typescript-eslint/eslint-plugin@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.2.0.tgz#5a5fcad1a7baed85c10080d71ad901f98c38d5b7" - integrity sha512-mdekAHOqS9UjlmyF/LSs6AIEvfceV749GFxoBAjwAv0nkevfKHWQFDMcBZWUiIC5ft6ePWivXoS36aKQ0Cy3sw== - dependencies: - "@eslint-community/regexpp" "^4.5.1" - "@typescript-eslint/scope-manager" "7.2.0" - "@typescript-eslint/type-utils" "7.2.0" - "@typescript-eslint/utils" "7.2.0" - "@typescript-eslint/visitor-keys" "7.2.0" - debug "^4.3.4" - graphemer "^1.4.0" - ignore "^5.2.4" - natural-compare "^1.4.0" - semver "^7.5.4" - ts-api-utils "^1.0.1" - -"@typescript-eslint/parser@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-7.2.0.tgz#44356312aea8852a3a82deebdacd52ba614ec07a" - integrity sha512-5FKsVcHTk6TafQKQbuIVkXq58Fnbkd2wDL4LB7AURN7RUOu1utVP+G8+6u3ZhEroW3DF6hyo3ZEXxgKgp4KeCg== - dependencies: - "@typescript-eslint/scope-manager" "7.2.0" - "@typescript-eslint/types" "7.2.0" - "@typescript-eslint/typescript-estree" "7.2.0" - "@typescript-eslint/visitor-keys" "7.2.0" - debug "^4.3.4" - -"@typescript-eslint/scope-manager@7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-7.2.0.tgz#cfb437b09a84f95a0930a76b066e89e35d94e3da" - integrity sha512-Qh976RbQM/fYtjx9hs4XkayYujB/aPwglw2choHmf3zBjB4qOywWSdt9+KLRdHubGcoSwBnXUH2sR3hkyaERRg== - dependencies: - "@typescript-eslint/types" "7.2.0" - "@typescript-eslint/visitor-keys" "7.2.0" - -"@typescript-eslint/type-utils@7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-7.2.0.tgz#7be5c30e9b4d49971b79095a1181324ef6089a19" - integrity sha512-xHi51adBHo9O9330J8GQYQwrKBqbIPJGZZVQTHHmy200hvkLZFWJIFtAG/7IYTWUyun6DE6w5InDReePJYJlJA== - dependencies: - "@typescript-eslint/typescript-estree" "7.2.0" - "@typescript-eslint/utils" "7.2.0" - debug "^4.3.4" - ts-api-utils "^1.0.1" - -"@typescript-eslint/types@7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-7.2.0.tgz#0feb685f16de320e8520f13cca30779c8b7c403f" - integrity sha512-XFtUHPI/abFhm4cbCDc5Ykc8npOKBSJePY3a3s+lwumt7XWJuzP5cZcfZ610MIPHjQjNsOLlYK8ASPaNG8UiyA== - -"@typescript-eslint/typescript-estree@7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-7.2.0.tgz#5beda2876c4137f8440c5a84b4f0370828682556" - integrity sha512-cyxS5WQQCoBwSakpMrvMXuMDEbhOo9bNHHrNcEWis6XHx6KF518tkF1wBvKIn/tpq5ZpUYK7Bdklu8qY0MsFIA== - dependencies: - "@typescript-eslint/types" "7.2.0" - "@typescript-eslint/visitor-keys" "7.2.0" - debug "^4.3.4" - globby "^11.1.0" - is-glob "^4.0.3" - minimatch "9.0.3" - semver "^7.5.4" - ts-api-utils "^1.0.1" - -"@typescript-eslint/utils@7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-7.2.0.tgz#fc8164be2f2a7068debb4556881acddbf0b7ce2a" - integrity sha512-YfHpnMAGb1Eekpm3XRK8hcMwGLGsnT6L+7b2XyRv6ouDuJU1tZir1GS2i0+VXRatMwSI1/UfcyPe53ADkU+IuA== - dependencies: - "@eslint-community/eslint-utils" "^4.4.0" - "@types/json-schema" "^7.0.12" - "@types/semver" "^7.5.0" - "@typescript-eslint/scope-manager" "7.2.0" - "@typescript-eslint/types" "7.2.0" - "@typescript-eslint/typescript-estree" "7.2.0" - semver "^7.5.4" - -"@typescript-eslint/visitor-keys@7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-7.2.0.tgz#5035f177752538a5750cca1af6044b633610bf9e" - integrity sha512-c6EIQRHhcpl6+tO8EMR+kjkkV+ugUNXOmeASA1rlzkd8EPIriavpWoiEz1HR/VLhbVIdhqnV6E7JZm00cBDx2A== - dependencies: - "@typescript-eslint/types" "7.2.0" - eslint-visitor-keys "^3.4.1" - -"@ungap/promise-all-settled@1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz#aa58042711d6e3275dd37dc597e5d31e8c290a44" - integrity sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q== - -"@ungap/structured-clone@^1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.2.0.tgz#756641adb587851b5ccb3e095daf27ae581c8406" - integrity sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ== - -"@yarnpkg/lockfile@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz#e77a97fbd345b76d83245edcd17d393b1b41fb31" - integrity sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ== - -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= - -abstract-leveldown@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-3.0.0.tgz#5cb89f958a44f526779d740d1440e743e0c30a57" - integrity sha512-KUWx9UWGQD12zsmLNj64/pndaz4iJh/Pj7nopgkfDG6RlCcbMZvT6+9l7dchK4idog2Is8VdC/PvNbFuFmalIQ== - dependencies: - xtend "~4.0.0" - -abstract-leveldown@^2.4.1, 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" - -abstract-leveldown@^5.0.0, abstract-leveldown@~5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-5.0.0.tgz#f7128e1f86ccabf7d2893077ce5d06d798e386c6" - integrity sha512-5mU5P1gXtsMIXg65/rsYGsi93+MlogXZ9FA8JnwKurHQg64bfXwGYVdVdijNTVNOlAsuIiOwHdvFFD5JqCJQ7A== - dependencies: - xtend "~4.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" - -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.0.0, acorn-jsx@^5.3.2: - version "5.3.2" - resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" - integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== - -acorn-walk@^8.1.1: - version "8.2.0" - resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" - integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== - -acorn@^6.0.7: - version "6.4.2" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.2.tgz#35866fd710528e92de10cf06016498e47e39e1e6" - integrity sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ== - -acorn@^8.4.1: - version "8.7.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.0.tgz#90951fde0f8f09df93549481e5fc141445b791cf" - integrity sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ== - -acorn@^8.9.0: - version "8.11.3" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.3.tgz#71e0b14e13a4ec160724b38fb7b0f233b1b81d7a" - integrity sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg== - -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= - -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== - -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== - -agent-base@6: - version "6.0.2" - resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" - integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== - dependencies: - debug "4" - -aggregate-error@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" - integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== - dependencies: - clean-stack "^2.0.0" - indent-string "^4.0.0" - -ajv@^6.10.2, ajv@^6.12.3, ajv@^6.12.4, ajv@^6.6.1, ajv@^6.9.1: - 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.11.0" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.11.0.tgz#977e91dd96ca669f54a11e23e378e33b884a565f" - integrity sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg== - 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= - -ansi-align@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-3.0.1.tgz#0cdf12e111ace773a86e9a1fad1225c43cb19a59" - integrity sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w== - dependencies: - string-width "^4.1.0" - -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: - 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-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= - -ansi-regex@^3.0.0: - 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.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.1.tgz#164daac87ab2d6f6db3a29875e2d1766582dabed" - integrity sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g== - -ansi-regex@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" - integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== - -ansi-regex@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" - integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== - -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-styles@^3.2.0, ansi-styles@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" - integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== - dependencies: - color-convert "^1.9.0" - -ansi-styles@^4.0.0, ansi-styles@^4.1.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" - integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== - dependencies: - color-convert "^2.0.1" - -ansi-styles@^6.0.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.1.0.tgz#87313c102b8118abd57371afab34618bf7350ed3" - integrity sha512-VbqNsoz55SYGczauuup0MFUyXNQviSpFTj1RQtFzmQLk18qbVSpTFFGMT293rmDaQuKCT6InmbuEyUne4mTuxQ== - -antlr4@4.7.1: - version "4.7.1" - resolved "https://registry.yarnpkg.com/antlr4/-/antlr4-4.7.1.tgz#69984014f096e9e775f53dd9744bf994d8959773" - integrity sha512-haHyTW7Y9joE5MVs37P2lNYfU2RWBLfcRDD8OWldcdZm5TiCE91B5Xl1oWSwiDUSd4rlExpt2pu1fksYQjRBYQ== - -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, anymatch@~3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" - integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== - dependencies: - normalize-path "^3.0.0" - picomatch "^2.0.4" - -arg@^4.1.0: - version "4.1.3" - resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" - integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== - -argparse@^1.0.7: - version "1.0.10" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" - integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== - dependencies: - sprintf-js "~1.0.2" - -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== - -arr-diff@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" - integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA= - -arr-flatten@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" - integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== - -arr-union@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" - integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= - -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" - -array-back@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/array-back/-/array-back-2.0.0.tgz#6877471d51ecc9c9bfa6136fb6c7d5fe69748022" - integrity sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw== - dependencies: - typical "^2.6.1" - -array-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-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= - -array-includes@^3.1.4: - version "3.1.4" - resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.4.tgz#f5b493162c760f3539631f005ba2bb46acb45ba9" - integrity sha512-ZTNSQkmWumEbiHO2GF4GmWxYVTiQyJy2XOTa15sdQSrvKn7l+180egQMqlrMOUMCyLMD7pmyQe4mMDUT6Behrw== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.1" - get-intrinsic "^1.1.1" - is-string "^1.0.7" - -array-union@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" - integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== - -array-uniq@1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" - integrity sha1-r2rId6Jcx/dOBYiUdThY39sk/bY= - -array-unique@^0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" - integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= - -array.prototype.flat@^1.2.5: - version "1.3.0" - resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.0.tgz#0b0c1567bf57b38b56b4c97b8aa72ab45e4adc7b" - integrity sha512-12IUEkHsAhA4DY5s0FPgNXIdc8VRSqD9Zp78a5au9abH/SOBrsp082JOWFNTjkMozh8mqcdiKuaLGhPeYztxSw== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.2" - es-shim-unscopables "^1.0.0" - -asap@~2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" - integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY= - -asn1.js@^5.2.0: - version "5.4.1" - resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-5.4.1.tgz#11a980b84ebb91781ce35b0fdc2ee294e3783f07" - integrity sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA== - dependencies: - bn.js "^4.0.0" - inherits "^2.0.1" - minimalistic-assert "^1.0.0" - safer-buffer "^2.1.0" - -asn1@~0.2.3: - version "0.2.6" - resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.6.tgz#0d3a7bb6e64e02a90c0303b31f292868ea09a08d" - integrity sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ== - dependencies: - safer-buffer "~2.1.0" - -assert-plus@1.0.0, assert-plus@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" - integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= - -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== - -assign-symbols@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" - integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= - -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== - -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-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" - -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: - version "1.5.2" - resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" - integrity sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo= - -async@2.6.2: - version "2.6.2" - resolved "https://registry.yarnpkg.com/async/-/async-2.6.2.tgz#18330ea7e6e313887f5d2f2a904bac6fe4dd5381" - integrity sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg== - dependencies: - lodash "^4.17.11" - -async@^2.0.1, async@^2.1.2, async@^2.4.0, async@^2.5.0, async@^2.6.1: - version "2.6.4" - resolved "https://registry.yarnpkg.com/async/-/async-2.6.4.tgz#706b7ff6084664cd7eae713f6f965433b5504221" - integrity sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA== - dependencies: - lodash "^4.17.14" - -async@^3.2.3: - version "3.2.4" - resolved "https://registry.yarnpkg.com/async/-/async-3.2.4.tgz#2d22e00f8cddeb5fde5dd33522b56d1cf569a81c" - integrity sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ== - -asynckit@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" - integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= - -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== - -atob@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" - integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== - -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= - -aws4@^1.8.0: - version "1.11.0" - resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59" - integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA== - -b4a@^1.0.1: - version "1.6.1" - resolved "https://registry.yarnpkg.com/b4a/-/b4a-1.6.1.tgz#9effac93a469a868d024e16fd77162c653544cbd" - integrity sha512-AsKjNhz72yxteo/0EtQEiwkMUgk/tGmycXlbG4g3Ard2/ULtNLUykGOkeK0egmN27h0xMAhb76jYccW+XTBExA== - -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" - -balanced-match@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" - integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== - -base-x@^3.0.2, base-x@^3.0.8: - version "3.0.9" - resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.9.tgz#6349aaabb58526332de9f60995e548a53fe21320" - integrity sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ== - dependencies: - safe-buffer "^5.0.1" - -base64-js@^1.3.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" - integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== - -base@^0.11.1: - version "0.11.2" - resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" - integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== - dependencies: - cache-base "^1.0.1" - class-utils "^0.3.5" - component-emitter "^1.2.1" - define-property "^1.0.0" - isobject "^3.0.1" - mixin-deep "^1.2.0" - pascalcase "^0.1.1" - -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= - dependencies: - tweetnacl "^0.14.3" - -bech32@1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/bech32/-/bech32-1.1.4.tgz#e38c9f37bf179b8eb16ae3a772b40c356d4832e9" - integrity sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ== - -big-integer@^1.6.42, big-integer@^1.6.48: - version "1.6.51" - resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.51.tgz#0df92a5d9880560d3ff2d5fd20245c889d130686" - integrity sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg== - -bignumber.js@^9.0.0: - version "9.0.2" - resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.0.2.tgz#71c6c6bed38de64e24a65ebe16cfcf23ae693673" - integrity sha512-GAcQvbpsM0pUb0zw1EI0KhQEZ+lRwR5fYaAp3vPOYuP7aDvGy6cVN6XHLauvF8SOga2y0dcLcjt3iQDTSEliyw== - -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== - -bindings@^1.2.1: - 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" - -bip39@2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/bip39/-/bip39-2.5.0.tgz#51cbd5179460504a63ea3c000db3f787ca051235" - integrity sha512-xwIx/8JKoT2+IPJpFEfXoWdYwP7UVAoUxxLNfGCfVowaJE7yg1Y5B1BVPqlUNsBq5/nGwmFkwRJ8xDW4sX8OdA== - dependencies: - create-hash "^1.1.0" - pbkdf2 "^3.0.9" - randombytes "^2.0.1" - safe-buffer "^5.0.1" - unorm "^1.3.3" - -blake-hash@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/blake-hash/-/blake-hash-1.1.1.tgz#b6251600d7812dd5097f96cb341ceae245bf9d12" - integrity sha512-V93H+FEJuXXZi1eEsMtbcBFP9oL5Ept7SLw3cbXYlPC3nocm9Fr4m18ZhbhdJrZVS9J/Z0oNE4L3oDZvmorHNA== - dependencies: - bindings "^1.2.1" - inherits "^2.0.3" - nan "^2.2.1" - -blake2b-wasm@^2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/blake2b-wasm/-/blake2b-wasm-2.4.0.tgz#9115649111edbbd87eb24ce7c04b427e4e2be5be" - integrity sha512-S1kwmW2ZhZFFFOghcx73+ZajEfKBqhP82JMssxtLVMxlaPea1p9uoLiUZ5WYyHn0KddwbLc+0vh4wR0KBNoT5w== - dependencies: - b4a "^1.0.1" - nanoassert "^2.0.0" - -blake2b@^2.1.3: - version "2.1.4" - resolved "https://registry.yarnpkg.com/blake2b/-/blake2b-2.1.4.tgz#817d278526ddb4cd673bfb1af16d1ad61e393ba3" - integrity sha512-AyBuuJNI64gIvwx13qiICz6H6hpmjvYS5DGkG6jbXMOT8Z3WUJ3V1X0FlhIoT1b/5JtHE3ki+xjtMvu1nn+t9A== - dependencies: - blake2b-wasm "^2.4.0" - nanoassert "^2.0.0" - -blakejs@^1.1.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/blakejs/-/blakejs-1.2.1.tgz#5057e4206eadb4a97f7c0b6e197a505042fc3814" - integrity sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ== - -bluebird@^3.5.0, bluebird@^3.5.2: - version "3.7.2" - resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" - integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== - -bn.js@4.11.6: - version "4.11.6" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.6.tgz#53344adb14617a13f6e8dd2ce28905d1c0ba3215" - integrity sha1-UzRK2xRhehP26N0s4okF0cC6MhU= - -bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.10.0, bn.js@^4.11.0, bn.js@^4.11.6, bn.js@^4.11.8, bn.js@^4.11.9, bn.js@^4.8.0: - 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.0.0, bn.js@^5.1.1, bn.js@^5.1.2, bn.js@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.0.tgz#358860674396c6997771a9d051fcc1b57d4ae002" - integrity sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw== - -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.2: - version "1.19.2" - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.2.tgz#4714ccd9c157d44797b8b5607d72c0b89952f26e" - integrity sha512-SAAwOxgoCKMGs9uUAUFHygfLAyaniaoun6I8mFY9pRAJL9+Kec34aU+oIjDhTycub1jozEfEwx1W1IuOYxVSFw== - dependencies: - bytes "3.1.2" - content-type "~1.0.4" - debug "2.6.9" - depd "~1.1.2" - http-errors "1.8.1" - iconv-lite "0.4.24" - on-finished "~2.3.0" - qs "6.9.7" - raw-body "2.4.3" - type-is "~1.6.18" - -body-parser@^1.16.0: - version "1.20.0" - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.0.tgz#3de69bd89011c11573d7bfee6a64f11b6bd27cc5" - integrity sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg== - dependencies: - bytes "3.1.2" - content-type "~1.0.4" - debug "2.6.9" - depd "2.0.0" - destroy "1.2.0" - http-errors "2.0.0" - iconv-lite "0.4.24" - on-finished "2.4.1" - qs "6.10.3" - raw-body "2.5.1" - type-is "~1.6.18" - unpipe "1.0.0" - -boxen@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/boxen/-/boxen-5.1.2.tgz#788cb686fc83c1f486dfa8a40c68fc2b831d2b50" - integrity sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ== - dependencies: - ansi-align "^3.0.0" - camelcase "^6.2.0" - chalk "^4.1.0" - cli-boxes "^2.2.1" - string-width "^4.2.2" - type-fest "^0.20.2" - widest-line "^3.1.0" - wrap-ansi "^7.0.0" - -brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -brace-expansion@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" - integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== - dependencies: - balanced-match "^1.0.0" - -braces@^2.3.1: - version "2.3.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" - integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== - dependencies: - arr-flatten "^1.1.0" - array-unique "^0.3.2" - extend-shallow "^2.0.1" - fill-range "^4.0.0" - isobject "^3.0.1" - repeat-element "^1.1.2" - snapdragon "^0.8.1" - snapdragon-node "^2.0.1" - split-string "^3.0.2" - to-regex "^3.0.1" - -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= - -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.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" - integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA== - dependencies: - buffer-xor "^1.0.3" - cipher-base "^1.0.0" - create-hash "^1.1.0" - evp_bytestokey "^1.0.3" - inherits "^2.0.1" - safe-buffer "^5.0.1" - -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.1.0" - resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.1.0.tgz#b2fd06b5b75ae297f7ce2dc651f918f5be158c8d" - integrity sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog== - dependencies: - bn.js "^5.0.0" - randombytes "^2.0.1" - -browserify-sign@^4.0.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.2.1.tgz#eaf4add46dd54be3bb3b36c0cf15abbeba7956c3" - integrity sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg== - dependencies: - bn.js "^5.1.1" - browserify-rsa "^4.0.1" - create-hash "^1.2.0" - create-hmac "^1.1.7" - elliptic "^6.5.3" - 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== - dependencies: - caniuse-lite "^1.0.30000844" - electron-to-chromium "^1.3.47" - -bs58@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a" - integrity sha1-vhYedsNU9veIrkBx9j806MTwpCo= - dependencies: - base-x "^3.0.2" - -bs58check@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/bs58check/-/bs58check-2.1.2.tgz#53b018291228d82a5aa08e7d796fdafda54aebfc" - integrity sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA== - dependencies: - bs58 "^4.0.0" - create-hash "^1.1.0" - safe-buffer "^5.1.2" - -buffer-from@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" - integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== - -buffer-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= - -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= - -buffer-xor@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-2.0.2.tgz#34f7c64f04c777a1f8aac5e661273bb9dd320289" - integrity sha512-eHslX0bin3GB+Lx2p7lEYRShRewuNZL3fUl4qlVJGGiwoPGftmt8JQgk2Y9Ji5/01TnVDo33E5b5O3vUB1HdqQ== - dependencies: - safe-buffer "^5.1.1" - -buffer@^5.0.5, buffer@^5.2.1, 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.6" - resolved "https://registry.yarnpkg.com/bufferutil/-/bufferutil-4.0.6.tgz#ebd6c67c7922a0e902f053e5d8be5ec850e48433" - integrity sha512-jduaYOYtnio4aIAyc6UbvPCVcgq7nYpVnucyxr6eCYg/Woad9Hf/oxxBRDnGGjPfjUm6j5O/uBWhIu4iLebFaw== - dependencies: - node-gyp-build "^4.3.0" - -builtin-modules@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-3.3.0.tgz#cae62812b89801e9656336e46223e030386be7b6" - integrity sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw== - -builtins@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/builtins/-/builtins-5.0.1.tgz#87f6db9ab0458be728564fa81d876d8d74552fa9" - integrity sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ== - dependencies: - semver "^7.0.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== - -bytewise-core@^1.2.2: - version "1.2.3" - resolved "https://registry.yarnpkg.com/bytewise-core/-/bytewise-core-1.2.3.tgz#3fb410c7e91558eb1ab22a82834577aa6bd61d42" - integrity sha1-P7QQx+kVWOsasiqCg0V3qmvWHUI= - dependencies: - typewise-core "^1.2" - -bytewise@~1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/bytewise/-/bytewise-1.1.0.tgz#1d13cbff717ae7158094aa881b35d081b387253e" - integrity sha1-HRPL/3F65xWAlKqIGzXQgbOHJT4= - dependencies: - bytewise-core "^1.2.2" - typewise "^1.0.3" - -cache-base@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" - integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== - dependencies: - collection-visit "^1.0.0" - component-emitter "^1.2.1" - get-value "^2.0.6" - has-value "^1.0.0" - isobject "^3.0.1" - set-value "^2.0.0" - to-object-path "^0.3.0" - union-value "^1.0.0" - unset-value "^1.0.0" - -cacheable-request@^6.0.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-6.1.0.tgz#20ffb8bd162ba4be11e9567d823db651052ca912" - integrity sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg== - dependencies: - clone-response "^1.0.2" - get-stream "^5.1.0" - http-cache-semantics "^4.0.0" - keyv "^3.0.0" - lowercase-keys "^2.0.0" - normalize-url "^4.1.0" - responselike "^1.0.2" - -cachedown@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/cachedown/-/cachedown-1.0.0.tgz#d43f036e4510696b31246d7db31ebf0f7ac32d15" - integrity sha1-1D8DbkUQaWsxJG19sx6/D3rDLRU= - dependencies: - abstract-leveldown "^2.4.1" - lru-cache "^3.2.0" - -call-bind@^1.0.0, call-bind@^1.0.2, call-bind@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" - integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== - dependencies: - function-bind "^1.1.1" - get-intrinsic "^1.0.2" - -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" - -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= - 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= - -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@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a" - integrity sha1-MvxLn82vhF/N9+c7uXysImHwqwo= - -camelcase@^5.0.0: - version "5.3.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" - integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== - -camelcase@^6.0.0, camelcase@^6.2.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" - integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== - -caniuse-lite@^1.0.30000844: - version "1.0.30001332" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001332.tgz#39476d3aa8d83ea76359c70302eafdd4a1d727dd" - integrity sha512-10T30NYOEQtN6C11YGg411yebhvpnC6Z102+B95eAsN0oB6KUs01ivE8u+G6FMIRtIrVlYXhL+LUwQ3/hXwDWw== - -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= - -cbor@^8.1.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/cbor/-/cbor-8.1.0.tgz#cfc56437e770b73417a2ecbfc9caf6b771af60d5" - integrity sha512-DwGjNW9omn6EwP70aXsn7FQJx5kO12tX0bZkaTjzdVFM6/7nhA4t0EENocKGx6D2Bch9PE2KzCUf5SceBdeijg== - dependencies: - nofilter "^3.1.0" - -chai-as-promised@^7.1.1: - version "7.1.1" - resolved "https://registry.yarnpkg.com/chai-as-promised/-/chai-as-promised-7.1.1.tgz#08645d825deb8696ee61725dbf590c012eb00ca0" - integrity sha512-azL6xMoi+uxu6z4rhWQ1jbdUhOMhis2PvscD/xjLqNMkv3BPPp2JyyuTHOrf9BOosGpNQ11v6BKv/g57RXbiaA== - dependencies: - check-error "^1.0.2" - -chai@^4.2.0: - version "4.3.6" - resolved "https://registry.yarnpkg.com/chai/-/chai-4.3.6.tgz#ffe4ba2d9fa9d6680cc0b370adae709ec9011e9c" - integrity sha512-bbcp3YfHCUzMOvKqsztczerVgBKSsEijCySNlHHbX3VG1nskvqjz5Rfso1gGwD6w6oOV3eI60pKuMOV5MV7p3Q== - dependencies: - assertion-error "^1.1.0" - check-error "^1.0.2" - deep-eql "^3.0.1" - get-func-name "^2.0.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: - version "2.4.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" - integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - -chalk@^4.0.0, chalk@^4.0.2, chalk@^4.1.0: - 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== - -"charenc@>= 0.0.1": - version "0.0.2" - resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667" - integrity sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc= - -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= - -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= - dependencies: - functional-red-black-tree "^1.0.1" - -chokidar@3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.3.0.tgz#12c0714668c55800f659e262d4962a97faf554a6" - integrity sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A== - dependencies: - anymatch "~3.1.1" - braces "~3.0.2" - glob-parent "~5.1.0" - is-binary-path "~2.1.0" - is-glob "~4.0.1" - normalize-path "~3.0.0" - readdirp "~3.2.0" - optionalDependencies: - fsevents "~2.1.1" - -chokidar@3.5.1: - version "3.5.1" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.1.tgz#ee9ce7bbebd2b79f49f304799d5468e31e14e68a" - integrity sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw== - dependencies: - anymatch "~3.1.1" - braces "~3.0.2" - glob-parent "~5.1.0" - is-binary-path "~2.1.0" - is-glob "~4.0.1" - normalize-path "~3.0.0" - readdirp "~3.5.0" - optionalDependencies: - fsevents "~2.3.1" - -chokidar@3.5.3, chokidar@^3.4.0: - version "3.5.3" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" - integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== - dependencies: - anymatch "~3.1.2" - braces "~3.0.2" - glob-parent "~5.1.2" - is-binary-path "~2.1.0" - is-glob "~4.0.1" - normalize-path "~3.0.0" - readdirp "~3.6.0" - optionalDependencies: - fsevents "~2.3.2" - -chownr@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" - integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== - -ci-info@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" - integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== - -cids@^0.7.1: - version "0.7.5" - resolved "https://registry.yarnpkg.com/cids/-/cids-0.7.5.tgz#60a08138a99bfb69b6be4ceb63bfef7a396b28b2" - integrity sha512-zT7mPeghoWAu+ppn8+BS1tQ5qGmbMfB4AregnQjA/qHY3GC1m1ptI9GkWNlgeu38r7CuRdXB47uY2XgAYt6QVA== - dependencies: - buffer "^5.5.0" - class-is "^1.1.0" - multibase "~0.6.0" - multicodec "^1.0.0" - multihashes "~0.4.15" - -cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" - integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q== - dependencies: - inherits "^2.0.1" - safe-buffer "^5.0.1" - -circom@0.5.33: - version "0.5.33" - resolved "https://registry.yarnpkg.com/circom/-/circom-0.5.33.tgz#6943d5799adf5388989bfbb3ef8f502fb1b4f662" - integrity sha512-UdL8fr6GckhQ4VoWjIvuYwCHneJe8z/AyJpDxgKLyuaX51ijd4gBP6jlwHDbQJsha2aU2GR9qgDsxd0jfari1Q== - dependencies: - chai "^4.2.0" - circom_runtime "0.1.8" - fastfile "0.0.18" - ffiasm "0.1.1" - ffjavascript "0.2.22" - ffwasm "0.0.7" - fnv-plus "^1.3.1" - r1csfile "0.0.16" - tmp-promise "^2.0.2" - wasmbuilder "0.0.10" - -circom@^0.5.46: - version "0.5.46" - resolved "https://registry.yarnpkg.com/circom/-/circom-0.5.46.tgz#031e96b1d83744103c0054eb1561bf191c6e8cdd" - integrity sha512-clvfqJudyBlHAubTu4dKY04dVgst8OxGS7SAxdbXKbGO2c6XGOzP2TSygNUmYHanLDvUgJpOqQYe/AkLt9x/1g== - dependencies: - chai "^4.2.0" - circom_runtime "0.1.12" - fastfile "0.0.18" - ffiasm "0.1.1" - ffjavascript "0.2.22" - ffwasm "0.0.7" - fnv-plus "^1.3.1" - r1csfile "0.0.16" - tmp-promise "^2.0.2" - wasmbuilder "0.0.10" - -circom_runtime@0.1.12: - version "0.1.12" - resolved "https://registry.yarnpkg.com/circom_runtime/-/circom_runtime-0.1.12.tgz#e1a302c6fe8cec390f035c2e7a8496cfa7cfb4a2" - integrity sha512-R+QT9HS9w71cmGmWIn+PSyD3aHyR5JZBiVvxOjCfn12wwnpuFwBjdMG7he+v8h/oQD1mDRAu2KrBeL4mAt5s4A== - dependencies: - ffjavascript "0.2.34" - fnv-plus "^1.3.1" - -circom_runtime@0.1.8: - version "0.1.8" - resolved "https://registry.yarnpkg.com/circom_runtime/-/circom_runtime-0.1.8.tgz#d967a1618fe5290849f9c0bbffb6b97b95c0f1c8" - integrity sha512-5ZmzCyidkNPb1zZsJGRXTuWcJ6kW6+gRBtHgf2tFqTh5dUyWVVPH0Zg7AsU2ijPr1AmYZUlme0yORUZK5HrjOA== - dependencies: - ffjavascript "0.2.10" - fnv-plus "^1.3.1" - -circomlib@^0.5.0: - version "0.5.5" - resolved "https://registry.yarnpkg.com/circomlib/-/circomlib-0.5.5.tgz#aa2f91100b2bbc5208201f381e2c04b843f73890" - integrity sha512-5FUw6AnEw+65suAgEQCucVepxOm96wnIo89vBldeX1DjeSV8zpP88Tje3BLBTLz0C1U6SkRnwqULrtiA5IVtZQ== - dependencies: - blake-hash "^1.1.0" - blake2b "^2.1.3" - circom "0.5.33" - ffjavascript "0.2.38" - web3-utils "^1.3.0" - -class-is@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/class-is/-/class-is-1.1.0.tgz#9d3c0fba0440d211d843cec3dedfa48055005825" - integrity sha512-rhjH9AG1fvabIDoGRVH587413LPjTZgmDF9fOFCbFJQV4yuocX1mHxxvXI4g3cGwbVY9wAYIoKlg1N79frJKQw== - -class-utils@^0.3.5: - version "0.3.6" - resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" - integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== - dependencies: - arr-union "^3.1.0" - define-property "^0.2.5" - isobject "^3.0.0" - static-extend "^0.1.1" - -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-boxes@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.1.tgz#ddd5035d25094fce220e9cab40a45840a440318f" - integrity sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw== - -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= - dependencies: - restore-cursor "^2.0.0" - -cli-cursor@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" - integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== - dependencies: - restore-cursor "^3.1.0" - -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-truncate@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-2.1.0.tgz#c39e28bf05edcde5be3b98992a22deed5a2b93c7" - integrity sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg== - dependencies: - slice-ansi "^3.0.0" - string-width "^4.2.0" - -cli-truncate@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-3.1.0.tgz#3f23ab12535e3d73e839bb43e73c9de487db1389" - integrity sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA== - dependencies: - slice-ansi "^5.0.0" - string-width "^5.0.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== - -cliui@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" - integrity sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0= - dependencies: - string-width "^1.0.1" - strip-ansi "^3.0.1" - wrap-ansi "^2.0.0" - -cliui@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5" - integrity sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA== - dependencies: - string-width "^3.1.0" - strip-ansi "^5.2.0" - wrap-ansi "^5.1.0" - -cliui@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-6.0.0.tgz#511d702c0c4e41ca156d7d0e96021f23e13225b1" - integrity sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ== - dependencies: - string-width "^4.2.0" - strip-ansi "^6.0.0" - wrap-ansi "^6.2.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= - dependencies: - mimic-response "^1.0.0" - -clone@2.1.2, clone@^2.0.0: - 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 sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= - -collection-visit@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" - integrity sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA= - dependencies: - map-visit "^1.0.0" - object-visit "^1.0.0" - -color-convert@^1.9.0: - version "1.9.3" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" - integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== - dependencies: - color-name "1.1.3" - -color-convert@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" - integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== - dependencies: - color-name "~1.1.4" - -color-name@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= - -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== - -colorette@^2.0.16, colorette@^2.0.17: - version "2.0.19" - resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.19.tgz#cdf044f47ad41a0f4b56b3a0d5b4e6e1a2d5a798" - integrity sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ== - -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.8, combined-stream@~1.0.6: - version "1.0.8" - resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" - integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== - dependencies: - delayed-stream "~1.0.0" - -command-exists@^1.2.8: - version "1.2.9" - resolved "https://registry.yarnpkg.com/command-exists/-/command-exists-1.2.9.tgz#c50725af3808c8ab0260fd60b01fbfa25b954f69" - integrity sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w== - -command-line-args@^4.0.7: - version "4.0.7" - resolved "https://registry.yarnpkg.com/command-line-args/-/command-line-args-4.0.7.tgz#f8d1916ecb90e9e121eda6428e41300bfb64cc46" - integrity sha512-aUdPvQRAyBvQd2n7jXcsMDz68ckBJELXNzBybCHOibUWEg0mWTnaYCSRU8h9R+aNRSvDihJtssSRCiDRpLaezA== - dependencies: - array-back "^2.0.0" - find-replace "^1.0.3" - typical "^2.6.1" - -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 "^3.1.0" - find-replace "^3.0.0" - lodash.camelcase "^4.3.0" - typical "^4.0.0" - -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@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== - -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@^9.3.0: - version "9.3.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-9.3.0.tgz#f619114a5a2d2054e0d9ff1b31d5ccf89255e26b" - integrity sha512-hv95iU5uXPbK83mjrJKuZyFM/LBAoCV/XhVGkS5Je6tl7sxr6A0ITMw5WoRV46/UaJ46Nllm3Xt7IaJhXTIkzw== - -component-emitter@^1.2.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" - integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== - -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= - -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== - dependencies: - buffer-from "^1.0.0" - inherits "^2.0.3" - readable-stream "^2.2.2" - typedarray "^0.0.6" - -content-disposition@0.5.4: - version "0.5.4" - resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" - integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== - dependencies: - safe-buffer "5.2.1" - -content-hash@^2.5.2: - version "2.5.2" - resolved "https://registry.yarnpkg.com/content-hash/-/content-hash-2.5.2.tgz#bbc2655e7c21f14fd3bfc7b7d4bfe6e454c9e211" - integrity sha512-FvIQKy0S1JaWV10sMsA7TRx8bpU+pqPkhbsfvOJAdjRXvYxEckAwQWGwtRjiaJfh+E0DvcWUGqcdjwMGFjsSdw== - dependencies: - cids "^0.7.1" - multicodec "^0.5.5" - multihashes "^0.4.15" - -content-type@~1.0.4: - 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.8.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369" - integrity sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA== - dependencies: - safe-buffer "~5.1.1" - -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.2, 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== - -cookiejar@^2.1.1: - version "2.1.3" - resolved "https://registry.yarnpkg.com/cookiejar/-/cookiejar-2.1.3.tgz#fc7a6216e408e74414b90230050842dacda75acc" - integrity sha512-JxbCBUdrfr6AQjOXrxoTvAMJO4HBTUIlBzslcJPAz+/KT8yk53fXun51u+RenNYvad/+Vc2DIz5o9UxlCDymFQ== - -copy-descriptor@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" - integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= - -core-js-pure@^3.0.1: - version "3.22.0" - resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.22.0.tgz#0eaa54b6d1f4ebb4d19976bb4916dfad149a3747" - integrity sha512-ylOC9nVy0ak1N+fPIZj00umoZHgUVqmucklP5RT5N+vJof38klKn8Ze6KGyvchdClvEBr6LcQqJpI216LUMqYA== - -core-js@^2.4.0, core-js@^2.5.0: - version "2.6.12" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.12.tgz#d9333dfa7b065e347cc5682219d6f690859cc2ec" - integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ== - -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= - -core-util-is@~1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" - integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== - -cors@^2.8.1: - version "2.8.5" - resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29" - integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g== - dependencies: - object-assign "^4" - vary "^1" - -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== - dependencies: - import-fresh "^2.0.0" - is-directory "^0.3.1" - js-yaml "^3.13.1" - parse-json "^4.0.0" - -create-ecdh@^4.0.0: - version "4.0.4" - resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.4.tgz#d6e7f4bffa66736085a0762fd3a632684dabcc4e" - integrity sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A== - dependencies: - bn.js "^4.1.0" - elliptic "^6.5.3" - -create-hash@^1.1.0, create-hash@^1.1.2, create-hash@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" - integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== - dependencies: - cipher-base "^1.0.1" - inherits "^2.0.1" - md5.js "^1.3.4" - ripemd160 "^2.0.1" - sha.js "^2.4.0" - -create-hmac@^1.1.0, create-hmac@^1.1.4, create-hmac@^1.1.7: - version "1.1.7" - resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" - integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== - dependencies: - cipher-base "^1.0.3" - create-hash "^1.1.0" - inherits "^2.0.1" - ripemd160 "^2.0.0" - safe-buffer "^5.0.1" - sha.js "^2.4.8" - -create-require@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" - integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== - -cross-fetch@^2.1.0, cross-fetch@^2.1.1: - version "2.2.6" - resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-2.2.6.tgz#2ef0bb39a24ac034787965c457368a28730e220a" - integrity sha512-9JZz+vXCmfKUZ68zAptS7k4Nu8e2qcibe7WVZYps7sAgk5R8GYTc+T1WR0v1rlP9HxgARmOX1UTIJZFytajpNA== - dependencies: - node-fetch "^2.6.7" - whatwg-fetch "^2.0.4" - -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== - dependencies: - nice-try "^1.0.4" - path-key "^2.0.1" - semver "^5.5.0" - shebang-command "^1.2.0" - which "^1.2.9" - -cross-spawn@^7.0.2, cross-spawn@^7.0.3: - version "7.0.3" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" - integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== - dependencies: - path-key "^3.1.0" - shebang-command "^2.0.0" - which "^2.0.1" - -"crypt@>= 0.0.1": - version "0.0.2" - resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b" - integrity sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs= - -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== - 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" - -d@1, d@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a" - integrity sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA== - dependencies: - es5-ext "^0.10.50" - type "^1.0.1" - -dashdash@^1.12.0: - version "1.14.1" - resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" - integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= - 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= - -debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: - version "2.6.9" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== - dependencies: - ms "2.0.0" - -debug@3.2.6: - version "3.2.6" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" - integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== - dependencies: - ms "^2.1.1" - -debug@4, debug@4.3.4, debug@^4.0.1, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4: - version "4.3.4" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" - integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== - dependencies: - ms "2.1.2" - -debug@4.3.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee" - integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ== - dependencies: - ms "2.1.2" - -debug@^3.1.0, debug@^3.2.7: - version "3.2.7" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" - integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== - dependencies: - ms "^2.1.1" - -decamelize@^1.1.1, decamelize@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" - integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= - -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= - -decompress-response@^3.2.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= - dependencies: - mimic-response "^1.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== - dependencies: - type-detect "^4.0.0" - -deep-eql@^4.0.1: - 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.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== - -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== - -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" - -deferred-leveldown@~4.0.0: - version "4.0.2" - resolved "https://registry.yarnpkg.com/deferred-leveldown/-/deferred-leveldown-4.0.2.tgz#0b0570087827bf480a23494b398f04c128c19a20" - integrity sha512-5fMC8ek8alH16QiV0lTCis610D1Zt1+LA4MS4d63JgS32lrCjTFDUFz2ao09/j2I4Bqb5jL4FZYwu7Jz0XO1ww== - dependencies: - abstract-leveldown "~5.0.0" - inherits "^2.0.3" - -define-properties@^1.1.2, define-properties@^1.1.3: - version "1.1.4" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.4.tgz#0b14d7bd7fbeb2f3572c3a7eda80ea5d57fb05b1" - integrity sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA== - dependencies: - has-property-descriptors "^1.0.0" - object-keys "^1.1.1" - -define-property@^0.2.5: - version "0.2.5" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" - integrity sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY= - dependencies: - is-descriptor "^0.1.0" - -define-property@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" - integrity sha1-dp66rz9KY6rTr56NMEybvnm/sOY= - dependencies: - is-descriptor "^1.0.0" - -define-property@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" - integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== - dependencies: - is-descriptor "^1.0.2" - isobject "^3.0.1" - -defined@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693" - integrity sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM= - -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= - -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== - -depd@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" - integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= - -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@^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== - -diff@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" - integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== - -diff@^4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" - integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== - -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== - dependencies: - bn.js "^4.1.0" - miller-rabin "^4.0.0" - randombytes "^2.0.0" - -difflib@^0.2.4: - version "0.2.4" - resolved "https://registry.yarnpkg.com/difflib/-/difflib-0.2.4.tgz#b5e30361a6db023176d562892db85940a718f47e" - integrity sha512-9YVwmMb0wQHQNr5J9m6BSj6fk4pfGITGQOOs+D9Fl+INODWFOfvhIU1hNv6GgR1RBoC/9NJcwu77zShxV0kT7w== - dependencies: - heap ">= 0.2.0" - -dir-glob@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" - integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== - dependencies: - path-type "^4.0.0" - -doctrine@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" - integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw== - dependencies: - esutils "^2.0.2" - -doctrine@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" - integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== - dependencies: - esutils "^2.0.2" - -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== - -dotenv@^10.0.0: - version "10.0.0" - resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-10.0.0.tgz#3d4227b8fb95f81096cdd2b66653fb2c7085ba81" - integrity sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q== - -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== - dependencies: - minimatch "^3.0.4" - -duplexer3@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" - integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI= - -eastasianwidth@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" - integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== - -ecc-jsbn@~0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" - integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= - dependencies: - jsbn "~0.1.0" - safer-buffer "^2.1.0" - -edit-json-file@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/edit-json-file/-/edit-json-file-1.7.0.tgz#b0bfb626169890568c2668369a8e5202f5c49150" - integrity sha512-eIkLJ9i4ija7b2TbaLHy3scyjWFLzwM2Wa6kHbV4ppVLcCqn7FzqnO1vmCG3dLrkd+teWE3mvACfv166mO0VZg== - dependencies: - find-value "^1.0.12" - iterate-object "^1.3.4" - r-json "^1.2.10" - set-value "^4.1.0" - w-json "^1.3.10" - -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= - -ejs@^3.0.1: - version "3.1.8" - resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.8.tgz#758d32910c78047585c7ef1f92f9ee041c1c190b" - integrity sha512-/sXZeMlhS0ArkfX2Aw780gJzXSMPnKjtspYZv+f3NiKLlubezAHDU5+9xz6gd3/NhG3txQCo6xlglmTS+oTGEQ== - dependencies: - jake "^10.8.5" - -electron-to-chromium@^1.3.47: - version "1.4.111" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.111.tgz#897613f6504f3f17c9381c7499a635b413e4df4e" - integrity sha512-/s3+fwhKf1YK4k7btOImOzCQLpUjS6MaPf0ODTNuT4eTM1Bg4itBpLkydhOzJmpmH6Z9eXFyuuK5czsmzRzwtw== - -elliptic@6.5.4, elliptic@^6.4.0, elliptic@^6.5.2, elliptic@^6.5.3, elliptic@^6.5.4: - version "6.5.4" - resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb" - integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ== - dependencies: - bn.js "^4.11.9" - brorand "^1.1.0" - hash.js "^1.0.0" - hmac-drbg "^1.0.1" - inherits "^2.0.4" - minimalistic-assert "^1.0.1" - minimalistic-crypto-utils "^1.0.1" - -emoji-regex@^10.0.0: - version "10.1.0" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-10.1.0.tgz#d50e383743c0f7a5945c47087295afc112e3cf66" - integrity sha512-xAEnNCT3w2Tg6MA7ly6QqYJvEoY1tm9iIjJ3yMKK9JPlWuRHAMoe5iETwQnx3M9TVbFMfsrBgWKR+IsmswwNjg== - -emoji-regex@^7.0.1: - version "7.0.3" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" - integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== - -emoji-regex@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" - integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== - -emoji-regex@^9.2.2: - 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-down@5.0.4, encoding-down@~5.0.0: - version "5.0.4" - resolved "https://registry.yarnpkg.com/encoding-down/-/encoding-down-5.0.4.tgz#1e477da8e9e9d0f7c8293d320044f8b2cd8e9614" - integrity sha512-8CIZLDcSKxgzT+zX8ZVfgNbu8Md2wq/iqa1Y7zyVR18QBEAc0Nmzuvj/N5ykSKpfGzjM8qxbaFntLPwnVoUhZw== - dependencies: - abstract-leveldown "^5.0.0" - inherits "^2.0.3" - level-codec "^9.0.0" - level-errors "^2.0.0" - xtend "^4.0.1" - -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" - -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.3.6" - resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" - integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== - dependencies: - ansi-colors "^4.1.1" - -env-paths@^2.2.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2" - integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A== - -errno@~0.1.1: - version "0.1.8" - resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.8.tgz#8bb3e9c7d463be4976ff888f76b4809ebc2e811f" - integrity sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A== - dependencies: - prr "~1.0.1" - -error-ex@^1.2.0, error-ex@^1.3.1: - version "1.3.2" - resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" - integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== - dependencies: - is-arrayish "^0.2.1" - -es-abstract@^1.19.1, es-abstract@^1.19.2: - version "1.19.5" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.19.5.tgz#a2cb01eb87f724e815b278b0dd0d00f36ca9a7f1" - integrity sha512-Aa2G2+Rd3b6kxEUKTF4TaW67czBLyAv3z7VOhYRU50YBx+bbsYZ9xQP4lMNazePuFlybXI0V4MruPos7qUo5fA== - dependencies: - call-bind "^1.0.2" - es-to-primitive "^1.2.1" - function-bind "^1.1.1" - get-intrinsic "^1.1.1" - get-symbol-description "^1.0.0" - has "^1.0.3" - has-symbols "^1.0.3" - internal-slot "^1.0.3" - is-callable "^1.2.4" - is-negative-zero "^2.0.2" - is-regex "^1.1.4" - is-shared-array-buffer "^1.0.2" - is-string "^1.0.7" - is-weakref "^1.0.2" - object-inspect "^1.12.0" - object-keys "^1.1.1" - object.assign "^4.1.2" - string.prototype.trimend "^1.0.4" - string.prototype.trimstart "^1.0.4" - unbox-primitive "^1.0.1" - -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" - resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" - integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== - dependencies: - is-callable "^1.1.4" - is-date-object "^1.0.1" - is-symbol "^1.0.2" - -es5-ext@^0.10.35, es5-ext@^0.10.50: - version "0.10.60" - resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.60.tgz#e8060a86472842b93019c31c34865012449883f4" - integrity sha512-jpKNXIt60htYG59/9FGf2PYT3pwMpnEbNKysU+k/4FGwyGtMotOvcZOuW+EmXXYASRqYSXQfGL5cVIthOTgbkg== - dependencies: - es6-iterator "^2.0.3" - es6-symbol "^3.1.3" - next-tick "^1.1.0" - -es6-iterator@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" - integrity sha1-p96IkUGgWpSwhUQDstCg+/qY87c= - dependencies: - d "1" - es5-ext "^0.10.35" - es6-symbol "^3.1.1" - -es6-symbol@^3.1.1, es6-symbol@^3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.3.tgz#bad5d3c1bcdac28269f4cb331e431c78ac705d18" - integrity sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA== - dependencies: - d "^1.0.1" - ext "^1.1.2" - -escalade@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" - integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== - -escape-html@~1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" - integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= - -escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= - -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== - -escodegen@1.8.x: - version "1.8.1" - resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.8.1.tgz#5a5b53af4693110bebb0867aa3430dd3b70a1018" - integrity sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg= - dependencies: - esprima "^2.7.1" - estraverse "^1.9.1" - esutils "^2.0.2" - optionator "^0.8.1" - optionalDependencies: - source-map "~0.2.0" - -eslint-compat-utils@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/eslint-compat-utils/-/eslint-compat-utils-0.1.2.tgz#f45e3b5ced4c746c127cf724fb074cd4e730d653" - integrity sha512-Jia4JDldWnFNIru1Ehx1H5s9/yxiRHY/TimCuUc0jNexew3cF1gI6CYZil1ociakfWO3rRqFjl1mskBblB3RYg== - -eslint-config-prettier@^8.3.0: - version "8.5.0" - resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz#5a81680ec934beca02c7b1a61cf8ca34b66feab1" - integrity sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q== - -eslint-config-standard@^17.1.0: - version "17.1.0" - resolved "https://registry.yarnpkg.com/eslint-config-standard/-/eslint-config-standard-17.1.0.tgz#40ffb8595d47a6b242e07cbfd49dc211ed128975" - integrity sha512-IwHwmaBNtDK4zDHQukFDW5u/aTb8+meQWZvNFWkiGmbWjD6bqyuSSBxxXKkCftCUzc1zwCH2m/baCNDLGmuO5Q== - -eslint-import-resolver-node@^0.3.6: - version "0.3.6" - resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz#4048b958395da89668252001dbd9eca6b83bacbd" - integrity sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw== - dependencies: - debug "^3.2.7" - resolve "^1.20.0" - -eslint-module-utils@^2.7.3: - version "2.7.3" - resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.7.3.tgz#ad7e3a10552fdd0642e1e55292781bd6e34876ee" - integrity sha512-088JEC7O3lDZM9xGe0RerkOMd0EjFl+Yvd1jPWIkMT5u3H9+HC34mWWPnqPrN13gieT9pBOO+Qt07Nb/6TresQ== - dependencies: - debug "^3.2.7" - find-up "^2.1.0" - -eslint-plugin-es-x@^7.5.0: - version "7.5.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-es-x/-/eslint-plugin-es-x-7.5.0.tgz#d08d9cd155383e35156c48f736eb06561d07ba92" - integrity sha512-ODswlDSO0HJDzXU0XvgZ3lF3lS3XAZEossh15Q2UHjwrJggWeBoKqqEsLTZLXl+dh5eOAozG0zRcYtuE35oTuQ== - dependencies: - "@eslint-community/eslint-utils" "^4.1.2" - "@eslint-community/regexpp" "^4.6.0" - eslint-compat-utils "^0.1.2" - -eslint-plugin-es@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz#75a7cdfdccddc0589934aeeb384175f221c57893" - integrity sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ== - dependencies: - eslint-utils "^2.0.0" - regexpp "^3.0.0" - -eslint-plugin-import@^2.23.4: - version "2.26.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz#f812dc47be4f2b72b478a021605a59fc6fe8b88b" - integrity sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA== - dependencies: - array-includes "^3.1.4" - array.prototype.flat "^1.2.5" - debug "^2.6.9" - doctrine "^2.1.0" - eslint-import-resolver-node "^0.3.6" - eslint-module-utils "^2.7.3" - has "^1.0.3" - is-core-module "^2.8.1" - is-glob "^4.0.3" - minimatch "^3.1.2" - object.values "^1.1.5" - resolve "^1.22.0" - tsconfig-paths "^3.14.1" - -eslint-plugin-n@^16.6.2: - version "16.6.2" - resolved "https://registry.yarnpkg.com/eslint-plugin-n/-/eslint-plugin-n-16.6.2.tgz#6a60a1a376870064c906742272074d5d0b412b0b" - integrity sha512-6TyDmZ1HXoFQXnhCTUjVFULReoBPOAjpuiKELMkeP40yffI/1ZRO+d9ug/VC6fqISo2WkuIBk3cvuRPALaWlOQ== - dependencies: - "@eslint-community/eslint-utils" "^4.4.0" - builtins "^5.0.1" - eslint-plugin-es-x "^7.5.0" - get-tsconfig "^4.7.0" - globals "^13.24.0" - ignore "^5.2.4" - is-builtin-module "^3.2.1" - is-core-module "^2.12.1" - minimatch "^3.1.2" - resolve "^1.22.2" - semver "^7.5.3" - -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== - dependencies: - eslint-plugin-es "^3.0.0" - eslint-utils "^2.0.0" - ignore "^5.1.1" - minimatch "^3.0.4" - resolve "^1.10.1" - semver "^6.1.0" - -eslint-plugin-prettier@^3.4.0: - 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@^6.1.1: - version "6.1.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-6.1.1.tgz#269a3e2772f62875661220631bd4dafcb4083816" - integrity sha512-tjqWDwVZQo7UIPMeDReOpUgHCmCiH+ePnVT+5zVapL0uuHnegBUs2smM13CzOs2Xb5+MHMRFTs9v24yjba4Oig== - -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-scope@^7.2.2: - version "7.2.2" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.2.2.tgz#deb4f92563390f32006894af62a22dba1c46423f" - integrity sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg== - dependencies: - esrecurse "^4.3.0" - estraverse "^5.2.0" - -eslint-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: - version "2.1.0" - resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27" - integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg== - dependencies: - eslint-visitor-keys "^1.1.0" - -eslint-visitor-keys@^1.0.0, eslint-visitor-keys@^1.1.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-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4.3: - version "3.4.3" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800" - integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== - -eslint@^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@^8.57.0: - version "8.57.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.57.0.tgz#c786a6fd0e0b68941aaf624596fb987089195668" - integrity sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ== - dependencies: - "@eslint-community/eslint-utils" "^4.2.0" - "@eslint-community/regexpp" "^4.6.1" - "@eslint/eslintrc" "^2.1.4" - "@eslint/js" "8.57.0" - "@humanwhocodes/config-array" "^0.11.14" - "@humanwhocodes/module-importer" "^1.0.1" - "@nodelib/fs.walk" "^1.2.8" - "@ungap/structured-clone" "^1.2.0" - ajv "^6.12.4" - chalk "^4.0.0" - cross-spawn "^7.0.2" - debug "^4.3.2" - doctrine "^3.0.0" - escape-string-regexp "^4.0.0" - eslint-scope "^7.2.2" - eslint-visitor-keys "^3.4.3" - espree "^9.6.1" - esquery "^1.4.2" - esutils "^2.0.2" - fast-deep-equal "^3.1.3" - file-entry-cache "^6.0.1" - find-up "^5.0.0" - glob-parent "^6.0.2" - globals "^13.19.0" - graphemer "^1.4.0" - ignore "^5.2.0" - imurmurhash "^0.1.4" - is-glob "^4.0.0" - is-path-inside "^3.0.3" - js-yaml "^4.1.0" - json-stable-stringify-without-jsonify "^1.0.1" - levn "^0.4.1" - lodash.merge "^4.6.2" - minimatch "^3.1.2" - natural-compare "^1.4.0" - optionator "^0.9.3" - strip-ansi "^6.0.1" - text-table "^0.2.0" - -espree@^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@^9.6.0, espree@^9.6.1: - version "9.6.1" - resolved "https://registry.yarnpkg.com/espree/-/espree-9.6.1.tgz#a2a17b8e434690a5432f2f8018ce71d331a48c6f" - integrity sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ== - dependencies: - acorn "^8.9.0" - acorn-jsx "^5.3.2" - eslint-visitor-keys "^3.4.1" - -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= - -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: - version "1.4.0" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.4.0.tgz#2148ffc38b82e8c7057dfed48425b3e61f0f24a5" - integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w== - dependencies: - estraverse "^5.1.0" - -esquery@^1.4.2: - version "1.5.0" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.5.0.tgz#6ce17738de8577694edd7361c57182ac8cb0db0b" - integrity sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg== - dependencies: - estraverse "^5.1.0" - -esrecurse@^4.1.0, esrecurse@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" - integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== - dependencies: - estraverse "^5.2.0" - -estraverse@^1.9.1: - version "1.9.3" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-1.9.3.tgz#af67f2dc922582415950926091a4005d29c9bb44" - integrity sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q= - -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, estraverse@^5.2.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" - integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== - -esutils@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" - integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== - -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@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/eth-block-tracker/-/eth-block-tracker-3.0.1.tgz#95cd5e763c7293e0b1b2790a2a39ac2ac188a5e1" - integrity sha512-WUVxWLuhMmsfenfZvFO5sbl1qFY2IqUlw/FPVmjjdElpqLsZtSG+wPe9Dz7W/sB6e80HgFKknOmKk2eNlznHug== - dependencies: - eth-query "^2.1.0" - ethereumjs-tx "^1.3.3" - ethereumjs-util "^5.1.3" - ethjs-util "^0.1.3" - json-rpc-engine "^3.6.0" - pify "^2.3.0" - tape "^4.6.3" - -eth-ens-namehash@2.0.8, 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= - dependencies: - idna-uts46-hx "^2.3.1" - js-sha3 "^0.5.7" - -eth-gas-reporter@^0.2.24: - 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-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.8: - version "0.2.8" - resolved "https://registry.yarnpkg.com/eth-lib/-/eth-lib-0.2.8.tgz#b194058bef4b220ad12ea497431d6cb6aa0623c8" - integrity sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw== - dependencies: - bn.js "^4.11.6" - elliptic "^6.4.0" - xhr-request-promise "^0.1.2" - -eth-lib@^0.1.26: - version "0.1.29" - resolved "https://registry.yarnpkg.com/eth-lib/-/eth-lib-0.1.29.tgz#0c11f5060d42da9f931eab6199084734f4dbd1d9" - integrity sha512-bfttrr3/7gG4E02HoWTDUcDDslN003OlOoBxk9virpAZQ1ja/jDgwkWB8QfJF7ojuEowrqy+lzp9VcJG7/k5bQ== - dependencies: - bn.js "^4.11.6" - elliptic "^6.4.0" - nano-json-stream-parser "^0.1.2" - servify "^0.1.12" - ws "^3.0.0" - xhr-request-promise "^0.1.2" - -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-sig-util@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/eth-sig-util/-/eth-sig-util-3.0.0.tgz#75133b3d7c20a5731af0690c385e184ab942b97e" - integrity sha512-4eFkMOhpGbTxBQ3AMzVf0haUX2uTur7DpWiHzWyTURa28BVJJtOkcb9Ok5TV0YvEPG61DODPW7ZUATbJTslioQ== - dependencies: - buffer "^5.2.1" - elliptic "^6.4.0" - ethereumjs-abi "0.6.5" - ethereumjs-util "^5.1.1" - tweetnacl "^1.0.0" - tweetnacl-util "^0.15.0" - -eth-sig-util@^1.4.2: - version "1.4.2" - resolved "https://registry.yarnpkg.com/eth-sig-util/-/eth-sig-util-1.4.2.tgz#8d958202c7edbaae839707fba6f09ff327606210" - integrity sha1-jZWCAsftuq6Dlwf7pvCf8ydgYhA= - dependencies: - ethereumjs-abi "git+https://github.com/ethereumjs/ethereumjs-abi.git" - ethereumjs-util "^5.1.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" - -ethashjs@~0.0.7: - version "0.0.8" - resolved "https://registry.yarnpkg.com/ethashjs/-/ethashjs-0.0.8.tgz#227442f1bdee409a548fb04136e24c874f3aa6f9" - integrity sha512-/MSbf/r2/Ld8o0l15AymjOTlPqpN8Cr4ByUEA9GtR4x0yAh3TdtDzEg29zMjXCNPI7u6E5fOQdj/Cf9Tc7oVNw== - dependencies: - async "^2.1.2" - buffer-xor "^2.0.1" - ethereumjs-util "^7.0.2" - miller-rabin "^4.0.0" - -ethereum-bloom-filters@^1.0.6: - version "1.0.10" - resolved "https://registry.yarnpkg.com/ethereum-bloom-filters/-/ethereum-bloom-filters-1.0.10.tgz#3ca07f4aed698e75bd134584850260246a5fed8a" - 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: - version "0.1.3" - resolved "https://registry.yarnpkg.com/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz#8d6143cfc3d74bf79bbd8edecdf29e4ae20dd191" - integrity sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ== - dependencies: - "@types/pbkdf2" "^3.0.0" - "@types/secp256k1" "^4.0.1" - blakejs "^1.1.0" - browserify-aes "^1.2.0" - bs58check "^2.1.2" - create-hash "^1.2.0" - create-hmac "^1.1.7" - hash.js "^1.1.7" - keccak "^3.0.0" - pbkdf2 "^3.0.17" - randombytes "^2.1.0" - safe-buffer "^5.1.2" - scrypt-js "^3.0.0" - secp256k1 "^4.0.1" - setimmediate "^1.0.5" - -ethereum-cryptography@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/ethereum-cryptography/-/ethereum-cryptography-1.0.3.tgz#b1f8f4e702434b2016248dbb2f9fdd60c54772d8" - integrity sha512-NQLTW0x0CosoVb/n79x/TRHtfvS3hgNUPTUSCu0vM+9k6IIhHFFrAOJReneexjZsoZxMjJHnJn4lrE8EbnSyqQ== - dependencies: - "@noble/hashes" "1.0.0" - "@noble/secp256k1" "1.5.5" - "@scure/bip32" "1.0.1" - "@scure/bip39" "1.0.0" - -ethereum-cryptography@^2.0.0, ethereum-cryptography@^2.1.2: - version "2.1.3" - resolved "https://registry.yarnpkg.com/ethereum-cryptography/-/ethereum-cryptography-2.1.3.tgz#1352270ed3b339fe25af5ceeadcf1b9c8e30768a" - integrity sha512-BlwbIL7/P45W8FGW2r7LGuvoEZ+7PWsniMvQ4p5s2xCyw9tmaDlpfsN9HjAucbF+t/qpVHwZUisgfK24TCW8aA== - dependencies: - "@noble/curves" "1.3.0" - "@noble/hashes" "1.3.3" - "@scure/bip32" "1.3.3" - "@scure/bip39" "1.2.2" - -ethereum-waffle@^3.0.0: - version "3.4.4" - resolved "https://registry.yarnpkg.com/ethereum-waffle/-/ethereum-waffle-3.4.4.tgz#1378b72040697857b7f5e8f473ca8f97a37b5840" - integrity sha512-PA9+jCjw4WC3Oc5ocSMBj5sXvueWQeAbvCA+hUlb6oFgwwKyq5ka3bWQ7QZcjzIX+TdFkxP4IbFmoY2D8Dkj9Q== - dependencies: - "@ethereum-waffle/chai" "^3.4.4" - "@ethereum-waffle/compiler" "^3.4.4" - "@ethereum-waffle/mock-contract" "^3.4.4" - "@ethereum-waffle/provider" "^3.4.4" - ethers "^5.0.1" - -ethereumjs-abi@0.6.5: - version "0.6.5" - resolved "https://registry.yarnpkg.com/ethereumjs-abi/-/ethereumjs-abi-0.6.5.tgz#5a637ef16ab43473fa72a29ad90871405b3f5241" - integrity sha1-WmN+8Wq0NHP6cqKa2QhxQFs/UkE= - dependencies: - bn.js "^4.10.0" - ethereumjs-util "^4.3.0" - -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: - bn.js "^4.11.8" - ethereumjs-util "^6.0.0" - -"ethereumjs-abi@git+https://github.com/ethereumjs/ethereumjs-abi.git": - version "0.6.8" - resolved "git+https://github.com/ethereumjs/ethereumjs-abi.git#ee3994657fa7a427238e6ba92a84d0b529bbcde0" - dependencies: - bn.js "^4.11.8" - ethereumjs-util "^6.0.0" - -ethereumjs-account@3.0.0, ethereumjs-account@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/ethereumjs-account/-/ethereumjs-account-3.0.0.tgz#728f060c8e0c6e87f1e987f751d3da25422570a9" - integrity sha512-WP6BdscjiiPkQfF9PVfMcwx/rDvfZTjFKY0Uwc09zSQr9JfIVH87dYIJu0gNhBhpmovV4yq295fdllS925fnBA== - dependencies: - ethereumjs-util "^6.0.0" - rlp "^2.2.1" - safe-buffer "^5.1.1" - -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@2.2.2, ethereumjs-block@^2.2.2, ethereumjs-block@~2.2.0, ethereumjs-block@~2.2.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/ethereumjs-block/-/ethereumjs-block-2.2.2.tgz#c7654be7e22df489fda206139ecd63e2e9c04965" - integrity sha512-2p49ifhek3h2zeg/+da6XpdFR3GlqY3BIEiqxGF8j9aSRIgkb7M1Ky+yULBKJOu8PAZxfhsYA+HxUk2aCQp3vg== - 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" - -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== - 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" - -ethereumjs-blockchain@^4.0.3: - version "4.0.4" - resolved "https://registry.yarnpkg.com/ethereumjs-blockchain/-/ethereumjs-blockchain-4.0.4.tgz#30f2228dc35f6dcf94423692a6902604ae34960f" - integrity sha512-zCxaRMUOzzjvX78DTGiKjA+4h2/sF0OYL1QuPux0DHpyq8XiNoF5GYHtb++GUxVlMsMfZV7AVyzbtgcRdIcEPQ== - dependencies: - async "^2.6.1" - ethashjs "~0.0.7" - ethereumjs-block "~2.2.2" - ethereumjs-common "^1.5.0" - ethereumjs-util "^6.1.0" - flow-stoplight "^1.0.0" - level-mem "^3.0.1" - lru-cache "^5.1.1" - rlp "^2.2.2" - semaphore "^1.1.0" - -ethereumjs-common@1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/ethereumjs-common/-/ethereumjs-common-1.5.0.tgz#d3e82fc7c47c0cef95047f431a99485abc9bb1cd" - integrity sha512-SZOjgK1356hIY7MRj3/ma5qtfr/4B5BL+G4rP/XSMYr2z1H5el4RX5GReYCKmQmYI/nSBmRnwrZ17IfHuG0viQ== - -ethereumjs-common@^1.1.0, ethereumjs-common@^1.3.2, ethereumjs-common@^1.5.0: - version "1.5.2" - resolved "https://registry.yarnpkg.com/ethereumjs-common/-/ethereumjs-common-1.5.2.tgz#2065dbe9214e850f2e955a80e650cb6999066979" - integrity sha512-hTfZjwGX52GS2jcVO6E2sx4YuFnf0Fhp5ylo4pEPhEffNln7vS59Hr5sLnp3/QCazFLluuBZ+FZ6J5HTp0EqCA== - -ethereumjs-tx@2.1.2, 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== - dependencies: - ethereumjs-common "^1.5.0" - ethereumjs-util "^6.0.0" - -ethereumjs-tx@^1.1.1, ethereumjs-tx@^1.2.0, ethereumjs-tx@^1.2.2, ethereumjs-tx@^1.3.3: - version "1.3.7" - resolved "https://registry.yarnpkg.com/ethereumjs-tx/-/ethereumjs-tx-1.3.7.tgz#88323a2d875b10549b8347e09f4862b546f3d89a" - integrity sha512-wvLMxzt1RPhAQ9Yi3/HKZTn0FZYpnsmQdbKYfUUpi4j1SEIcbkd9tndVjcPrufY3V7j2IebOpC00Zp2P/Ay2kA== - dependencies: - ethereum-common "^0.0.18" - ethereumjs-util "^5.0.0" - -ethereumjs-util@6.2.1, ethereumjs-util@^6.0.0, ethereumjs-util@^6.1.0, ethereumjs-util@^6.2.0, ethereumjs-util@^6.2.1: - version "6.2.1" - resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz#fcb4e4dd5ceacb9d2305426ab1a5cd93e3163b69" - integrity sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw== - dependencies: - "@types/bn.js" "^4.11.3" - bn.js "^4.11.0" - create-hash "^1.1.2" - elliptic "^6.5.2" - ethereum-cryptography "^0.1.3" - ethjs-util "0.1.6" - rlp "^2.2.3" - -ethereumjs-util@^4.3.0: - version "4.5.1" - resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-4.5.1.tgz#f4bf9b3b515a484e3cc8781d61d9d980f7c83bd0" - integrity sha512-WrckOZ7uBnei4+AKimpuF1B3Fv25OmoRgmYCpGsP7u8PFxXAmAgiJSYT2kRWnt6fVIlKaQlZvuwXp7PIrmn3/w== - dependencies: - bn.js "^4.8.0" - create-hash "^1.1.2" - elliptic "^6.5.2" - ethereum-cryptography "^0.1.3" - rlp "^2.0.0" - -ethereumjs-util@^5.0.0, ethereumjs-util@^5.0.1, ethereumjs-util@^5.1.1, ethereumjs-util@^5.1.2, ethereumjs-util@^5.1.3, ethereumjs-util@^5.1.5, ethereumjs-util@^5.2.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz#a833f0e5fca7e5b361384dc76301a721f537bf65" - integrity sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ== - dependencies: - bn.js "^4.11.0" - 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" - -ethereumjs-util@^7.0.2, ethereumjs-util@^7.1.0: - version "7.1.4" - resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-7.1.4.tgz#a6885bcdd92045b06f596c7626c3e89ab3312458" - integrity sha512-p6KmuPCX4mZIqsQzXfmSx9Y0l2hqf+VkAiwSisW3UKUFdk8ZkAt+AYaor83z2nSi6CU2zSsXMlD80hAbNEGM0A== - dependencies: - "@types/bn.js" "^5.1.0" - bn.js "^5.1.2" - create-hash "^1.1.2" - ethereum-cryptography "^0.1.3" - rlp "^2.2.4" - -ethereumjs-vm@4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/ethereumjs-vm/-/ethereumjs-vm-4.2.0.tgz#e885e861424e373dbc556278f7259ff3fca5edab" - integrity sha512-X6qqZbsY33p5FTuZqCnQ4+lo957iUJMM6Mpa6bL4UW0dxM6WmDSHuI4j/zOp1E2TDKImBGCJA9QPfc08PaNubA== - dependencies: - async "^2.1.2" - async-eventemitter "^0.2.2" - core-js-pure "^3.0.1" - ethereumjs-account "^3.0.0" - ethereumjs-block "^2.2.2" - ethereumjs-blockchain "^4.0.3" - ethereumjs-common "^1.5.0" - ethereumjs-tx "^2.1.2" - ethereumjs-util "^6.2.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" - util.promisify "^1.0.0" - -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.5: - 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.40: - version "4.0.49" - resolved "https://registry.yarnpkg.com/ethers/-/ethers-4.0.49.tgz#0eb0e9161a0c8b4761be547396bbe2fb121a8894" - integrity sha512-kPltTvWiyu+OktYy1IStSO16i2e7cS9D9OxZ81q2UUaiNPVrm/RTcbxamCXF9VUSKzJIdJV68EAIhTEVBalRWg== - dependencies: - aes-js "3.0.0" - bn.js "^4.11.9" - elliptic "6.5.4" - hash.js "1.1.3" - js-sha3 "0.5.7" - scrypt-js "2.0.4" - setimmediate "1.0.4" - uuid "2.0.1" - xmlhttprequest "1.8.0" - -ethers@^5.0.1, ethers@^5.0.2, ethers@^5.5.2: - version "5.6.4" - resolved "https://registry.yarnpkg.com/ethers/-/ethers-5.6.4.tgz#23629e9a7d4bc5802dfb53d4da420d738744b53c" - integrity sha512-62UIfxAQXdf67TeeOaoOoPctm5hUlYgfd0iW3wxfj7qRYKDcvvy0f+sJ3W2/Pyx77R8dblvejA8jokj+lS+ATQ== - dependencies: - "@ethersproject/abi" "5.6.1" - "@ethersproject/abstract-provider" "5.6.0" - "@ethersproject/abstract-signer" "5.6.0" - "@ethersproject/address" "5.6.0" - "@ethersproject/base64" "5.6.0" - "@ethersproject/basex" "5.6.0" - "@ethersproject/bignumber" "5.6.0" - "@ethersproject/bytes" "5.6.1" - "@ethersproject/constants" "5.6.0" - "@ethersproject/contracts" "5.6.0" - "@ethersproject/hash" "5.6.0" - "@ethersproject/hdnode" "5.6.0" - "@ethersproject/json-wallets" "5.6.0" - "@ethersproject/keccak256" "5.6.0" - "@ethersproject/logger" "5.6.0" - "@ethersproject/networks" "5.6.2" - "@ethersproject/pbkdf2" "5.6.0" - "@ethersproject/properties" "5.6.0" - "@ethersproject/providers" "5.6.4" - "@ethersproject/random" "5.6.0" - "@ethersproject/rlp" "5.6.0" - "@ethersproject/sha2" "5.6.0" - "@ethersproject/signing-key" "5.6.0" - "@ethersproject/solidity" "5.6.0" - "@ethersproject/strings" "5.6.0" - "@ethersproject/transactions" "5.6.0" - "@ethersproject/units" "5.6.0" - "@ethersproject/wallet" "5.6.0" - "@ethersproject/web" "5.6.0" - "@ethersproject/wordlists" "5.6.0" - -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: - "@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" - -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= - 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: - version "0.1.6" - resolved "https://registry.yarnpkg.com/ethjs-util/-/ethjs-util-0.1.6.tgz#f308b62f185f9fe6237132fb2a9818866a5cd536" - integrity sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w== - dependencies: - is-hex-prefixed "1.0.0" - strip-hex-prefix "1.0.0" - -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.3.0" - resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" - integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== - -evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" - integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA== - dependencies: - md5.js "^1.3.4" - safe-buffer "^5.1.1" - -execa@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-6.1.0.tgz#cea16dee211ff011246556388effa0818394fb20" - integrity sha512-QVWlX2e50heYJcCPG0iWtf8r0xjEYfz/OYLGDYH+IyjWezzPNxz63qNFOu0l4YftGWuizFVZHHs8PrLU5p2IDA== - dependencies: - cross-spawn "^7.0.3" - get-stream "^6.0.1" - human-signals "^3.0.1" - is-stream "^3.0.0" - merge-stream "^2.0.0" - npm-run-path "^5.1.0" - onetime "^6.0.0" - signal-exit "^3.0.7" - strip-final-newline "^3.0.0" - -expand-brackets@^2.1.4: - version "2.1.4" - resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" - integrity sha1-t3c14xXOMPa27/D4OwQVGiJEliI= - dependencies: - debug "^2.3.3" - define-property "^0.2.5" - extend-shallow "^2.0.1" - posix-character-classes "^0.1.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - -express@^4.14.0: - version "4.17.3" - resolved "https://registry.yarnpkg.com/express/-/express-4.17.3.tgz#f6c7302194a4fb54271b73a1fe7a06478c8f85a1" - integrity sha512-yuSQpz5I+Ch7gFrPCk4/c+dIBKlQUxtgwqzph132bsT6qhuzss6I8cLJQz7B3rFblzd6wtcI0ZbGltH/C4LjUg== - dependencies: - accepts "~1.3.8" - array-flatten "1.1.1" - body-parser "1.19.2" - content-disposition "0.5.4" - content-type "~1.0.4" - cookie "0.4.2" - cookie-signature "1.0.6" - debug "2.6.9" - depd "~1.1.2" - encodeurl "~1.0.2" - escape-html "~1.0.3" - etag "~1.8.1" - finalhandler "~1.1.2" - fresh "0.5.2" - merge-descriptors "1.0.1" - methods "~1.1.2" - on-finished "~2.3.0" - parseurl "~1.3.3" - path-to-regexp "0.1.7" - proxy-addr "~2.0.7" - qs "6.9.7" - range-parser "~1.2.1" - safe-buffer "5.2.1" - send "0.17.2" - serve-static "1.14.2" - setprototypeof "1.2.0" - statuses "~1.5.0" - type-is "~1.6.18" - utils-merge "1.0.1" - vary "~1.1.2" - -ext@^1.1.2: - version "1.6.0" - resolved "https://registry.yarnpkg.com/ext/-/ext-1.6.0.tgz#3871d50641e874cc172e2b53f919842d19db4c52" - integrity sha512-sdBImtzkq2HpkdRLtlLWDa6w4DX22ijZLKx8BMPUuKe1c5lbN6xwQDQCxSfxBQnHZ13ls/FH0MQZx/q/gr6FQg== - dependencies: - type "^2.5.0" - -extend-shallow@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" - integrity sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8= - dependencies: - is-extendable "^0.1.0" - -extend-shallow@^3.0.0, extend-shallow@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" - integrity sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg= - dependencies: - assign-symbols "^1.0.0" - is-extendable "^1.0.1" - -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" - -extglob@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" - integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== - dependencies: - array-unique "^0.3.2" - define-property "^1.0.0" - expand-brackets "^2.1.4" - extend-shallow "^2.0.1" - fragment-cache "^0.2.1" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - -extsprintf@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" - integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= - -extsprintf@^1.2.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.1.tgz#8d172c064867f235c0c84a596806d279bf4bcc07" - integrity sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA== - -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= - dependencies: - checkpoint-store "^1.1.0" - -fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" - integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== - -fast-diff@^1.1.2: - version "1.2.0" - resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.2.0.tgz#73ee11982d86caaf7959828d519cfe927fac5f03" - integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w== - -fast-glob@^3.0.3, fast-glob@^3.2.9: - version "3.2.11" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.11.tgz#a1172ad95ceb8a16e20caa5c5e56480e5129c1d9" - integrity sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew== - dependencies: - "@nodelib/fs.stat" "^2.0.2" - "@nodelib/fs.walk" "^1.2.3" - glob-parent "^5.1.2" - merge2 "^1.3.0" - micromatch "^4.0.4" - -fast-json-stable-stringify@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" - integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== - -fast-levenshtein@^2.0.6, 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= - -fastfile@0.0.18: - version "0.0.18" - resolved "https://registry.yarnpkg.com/fastfile/-/fastfile-0.0.18.tgz#2b69bbbfd2fcccc9bc8099c27de1379b89756a4b" - integrity sha512-q03PTKc+wptis4WmuFOwPNQx2p5myFUrl/dMgRlW9mymc1Egyc14JPHgiGnWK+sJ0+dBl2Vwtfh5GfSQltYOpw== - -fastq@^1.6.0: - version "1.13.0" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c" - integrity sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw== - dependencies: - reusify "^1.0.4" - -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" - -ffiasm@0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/ffiasm/-/ffiasm-0.1.1.tgz#34ca6a00a875b5a926f66fd46e79530194e9c312" - integrity sha512-irMMHiR9JJ7BVBrAhtliUawxVdPYSdyl81taUYJ4C1mJ0iw2ueThE/qtr0J8B83tsIY8HJvh0lg5F+6ClK4xpA== - dependencies: - big-integer "^1.6.48" - ejs "^3.0.1" - yargs "^15.3.1" - -ffjavascript@0.2.10: - version "0.2.10" - resolved "https://registry.yarnpkg.com/ffjavascript/-/ffjavascript-0.2.10.tgz#b0bf88d69be0b51e0bd28e1966c4a6fb29a86682" - integrity sha512-GQI6gHYYG5/iD4Kt3VzezzK7fARJzP0zkc82V/+JAdjfeKBXhDSo5rpKFuK3cDcrdW0Fu2emuYNMEAuFqhEQvQ== - dependencies: - big-integer "^1.6.48" - wasmcurves "0.0.5" - worker-threads "^1.0.0" - -ffjavascript@0.2.22: - version "0.2.22" - resolved "https://registry.yarnpkg.com/ffjavascript/-/ffjavascript-0.2.22.tgz#101f33db330b0f6a0c10dec22ebf5725618a8a7d" - integrity sha512-EsVqap2Txm17bKW0z/jXCX3M7rQ++nQUAJY8alWDpyhjRj90xjl6GLeVSKZQ8rOFDQ/SFFXcEB8w9X8Boxid+w== - dependencies: - big-integer "^1.6.48" - wasmcurves "0.0.12" - worker-threads "^1.0.0" - -ffjavascript@0.2.34: - version "0.2.34" - resolved "https://registry.yarnpkg.com/ffjavascript/-/ffjavascript-0.2.34.tgz#e0607d1635ad06e8519268af475bc90deac60fbd" - integrity sha512-fq/qfJluC4spiOD1lp5jfckZVnS0o0kI5eKXVLw7UKwIwbNr+NBMBveBVcidSfMizF87T6wb7NBtLSdckQiAnQ== - dependencies: - big-integer "^1.6.48" - mocha "^8.2.1" - wasmcurves "0.0.14" - worker-threads "^1.0.0" - -ffjavascript@0.2.38: - version "0.2.38" - resolved "https://registry.yarnpkg.com/ffjavascript/-/ffjavascript-0.2.38.tgz#920832795be1e60a12832da80692b6c86259f3b7" - integrity sha512-b4dobcci6QxxUvNYFCHw2ONhXwtgSHCzqxbH6c7ipWMOzyoG+MPRMZgAqnUREYX8UC6zqA7AiRmiIB76nxt2TQ== - dependencies: - big-integer "^1.6.48" - wasmcurves "0.0.14" - web-worker "^1.0.0" - -ffwasm@0.0.7: - version "0.0.7" - resolved "https://registry.yarnpkg.com/ffwasm/-/ffwasm-0.0.7.tgz#23bb9a3537ecc87c0f24fcfb3a9ddd0e86855fff" - integrity sha512-17cTLzv7HHAKqZbX8MvHxjSrR0yDdn1sh4TVsTbAvO9e6klhFicnyoVXc/sCuViV/M8g65sCmVrAmoPCZp1YkQ== - dependencies: - big-integer "^1.6.48" - wasmbuilder "0.0.10" - -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== - dependencies: - flat-cache "^2.0.1" - -file-entry-cache@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" - integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== - dependencies: - flat-cache "^3.0.4" - -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== - -filelist@^1.0.1: - version "1.0.4" - resolved "https://registry.yarnpkg.com/filelist/-/filelist-1.0.4.tgz#f78978a1e944775ff9e62e744424f215e58352b5" - integrity sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q== - dependencies: - minimatch "^5.0.1" - -fill-range@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" - integrity sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc= - dependencies: - extend-shallow "^2.0.1" - is-number "^3.0.0" - repeat-string "^1.6.1" - to-regex-range "^2.1.0" - -fill-range@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" - integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== - dependencies: - to-regex-range "^5.0.1" - -finalhandler@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" - integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== - dependencies: - debug "2.6.9" - encodeurl "~1.0.2" - escape-html "~1.0.3" - on-finished "~2.3.0" - parseurl "~1.3.3" - statuses "~1.5.0" - 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= - dependencies: - array-back "^1.0.4" - test-value "^2.1.0" - -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 "^3.0.1" - -find-up@3.0.0, find-up@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" - integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== - dependencies: - locate-path "^3.0.0" - -find-up@5.0.0, find-up@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" - integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== - dependencies: - locate-path "^6.0.0" - path-exists "^4.0.0" - -find-up@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" - integrity sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8= - 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= - dependencies: - locate-path "^2.0.0" - -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 "^5.0.0" - path-exists "^4.0.0" - -find-value@^1.0.12: - version "1.0.12" - resolved "https://registry.yarnpkg.com/find-value/-/find-value-1.0.12.tgz#68b6cec84e5b2d51272965e0bf09b26c9159c26e" - integrity sha512-OCpo8LTk8eZ2sdDCwbU2Lc3ivYsdM6yod6jP2jHcNEFcjPhkgH0+POzTIol7xx1LZgtbI5rkO5jqxsG5MWtPjQ== - -find-yarn-workspace-root@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/find-yarn-workspace-root/-/find-yarn-workspace-root-1.2.1.tgz#40eb8e6e7c2502ddfaa2577c176f221422f860db" - integrity sha512-dVtfb0WuQG+8Ag2uWkbG79hOUzEsRrhBzgfn86g2sJPkzmcpGdghbNTfUKGTxymFrY/tLIodDzLoW9nOJ4FY8Q== - dependencies: - fs-extra "^4.0.3" - micromatch "^3.1.4" - -find-yarn-workspace-root@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/find-yarn-workspace-root/-/find-yarn-workspace-root-2.0.0.tgz#f47fb8d239c900eb78179aa81b66673eac88f7bd" - integrity sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ== - dependencies: - micromatch "^4.0.2" - -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== - dependencies: - flatted "^2.0.0" - rimraf "2.6.3" - write "1.0.3" - -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 "^3.1.0" - rimraf "^3.0.2" - -flat@^4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/flat/-/flat-4.1.1.tgz#a392059cc382881ff98642f5da4dde0a959f309b" - integrity sha512-FmTtBsHskrU6FJ2VxCnsDb84wu9zhmO3cUX2kGFb5tuwhfXxGciiT0oRY+cck35QmG+NmGh5eLz6lLCpWTqwpA== - dependencies: - is-buffer "~2.0.3" - -flat@^5.0.2: - version "5.0.2" - resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" - 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.5" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.5.tgz#76c8584f4fc843db64702a6bd04ab7a8bd666da3" - integrity sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg== - -flow-stoplight@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/flow-stoplight/-/flow-stoplight-1.0.0.tgz#4a292c5bcff8b39fa6cc0cb1a853d86f27eeff7b" - integrity sha1-SiksW8/4s5+mzAyxqFPYbyfu/3s= - -fnv-plus@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/fnv-plus/-/fnv-plus-1.3.1.tgz#c34cb4572565434acb08ba257e4044ce2b006d67" - integrity sha512-Gz1EvfOneuFfk4yG458dJ3TLJ7gV19q3OM/vVvvHf7eT02Hm1DleB4edsia6ahbKgAYxO9gvyQ1ioWZR+a00Yw== - -follow-redirects@^1.12.1: - version "1.14.9" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.9.tgz#dd4ea157de7bfaf9ea9b3fbd85aa16951f78d8d7" - integrity sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w== - -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== - dependencies: - is-callable "^1.1.3" - -for-in@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" - integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= - -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= - -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@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.1.tgz#ebd53791b78356a99af9a300d4282c4d5eb9755f" - integrity sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.8" - mime-types "^2.1.12" - -form-data@~2.3.2: - version "2.3.3" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" - integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.6" - mime-types "^2.1.12" - -forwarded@0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" - integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== - -fp-ts@1.19.3: - version "1.19.3" - resolved "https://registry.yarnpkg.com/fp-ts/-/fp-ts-1.19.3.tgz#261a60d1088fbff01f91256f91d21d0caaaaa96f" - 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== - -fragment-cache@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" - integrity sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk= - dependencies: - map-cache "^0.2.2" - -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-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= - dependencies: - graceful-fs "^4.1.2" - jsonfile "^2.1.0" - klaw "^1.0.0" - path-is-absolute "^1.0.0" - rimraf "^2.2.8" - -fs-extra@^4.0.2, fs-extra@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-4.0.3.tgz#0d852122e5bc5beb453fb028e9c0c9bf36340c94" - integrity sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg== - dependencies: - graceful-fs "^4.1.2" - jsonfile "^4.0.0" - universalify "^0.1.0" - -fs-extra@^7.0.0, fs-extra@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9" - integrity sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw== - dependencies: - graceful-fs "^4.1.2" - jsonfile "^4.0.0" - universalify "^0.1.0" - -fs-extra@^8.1.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" - integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== - dependencies: - graceful-fs "^4.2.0" - jsonfile "^4.0.0" - universalify "^0.1.0" - -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= - -fsevents@~2.1.1: - version "2.1.3" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.3.tgz#fb738703ae8d2f9fe900c33836ddebee8b97f23e" - integrity sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ== - -fsevents@~2.3.1, fsevents@~2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" - integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== - -function-bind@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" - integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== - -function-bind@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" - integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== - -functional-red-black-tree@^1.0.1, 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= - -functions-have-names@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.2.tgz#98d93991c39da9361f8e50b337c4f6e41f120e21" - integrity sha512-bLgc3asbWdwPbx2mNk2S49kmJCuQeu0nfmaOgbs8WIyzzkw3r4htszdIi9Q9EMezDPTYuJx2wvjZ/EwgAthpnA== - -ganache-core@^2.13.2: - version "2.13.2" - resolved "https://registry.yarnpkg.com/ganache-core/-/ganache-core-2.13.2.tgz#27e6fc5417c10e6e76e2e646671869d7665814a3" - integrity sha512-tIF5cR+ANQz0+3pHWxHjIwHqFXcVo0Mb+kcsNhglNFALcYo49aQpnS9dqHartqPfMFjiHh/qFoD3mYK0d/qGgw== - dependencies: - abstract-leveldown "3.0.0" - async "2.6.2" - bip39 "2.5.0" - cachedown "1.0.0" - clone "2.1.2" - debug "3.2.6" - encoding-down "5.0.4" - eth-sig-util "3.0.0" - ethereumjs-abi "0.6.8" - ethereumjs-account "3.0.0" - ethereumjs-block "2.2.2" - ethereumjs-common "1.5.0" - ethereumjs-tx "2.1.2" - ethereumjs-util "6.2.1" - ethereumjs-vm "4.2.0" - heap "0.2.6" - keccak "3.0.1" - level-sublevel "6.6.4" - levelup "3.1.1" - lodash "4.17.20" - lru-cache "5.1.1" - merkle-patricia-tree "3.0.0" - patch-package "6.2.2" - seedrandom "3.0.1" - source-map-support "0.5.12" - tmp "0.1.0" - web3-provider-engine "14.2.1" - websocket "1.0.32" - optionalDependencies: - ethereumjs-wallet "0.6.5" - web3 "1.2.11" - -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.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" - integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== - -get-func-name@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41" - integrity sha1-6td0q+5y4gQJQzoGY2YCPdaIekE= - -get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6" - integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q== - dependencies: - function-bind "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.1" - -get-port@^3.1.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/get-port/-/get-port-3.2.0.tgz#dd7ce7de187c06c8bf353796ac71e099f0980ebc" - integrity sha1-3Xzn3hh8Bsi/NTeWrHHgmfCYDrw= - -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.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== - dependencies: - pump "^3.0.0" - -get-stream@^5.1.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" - integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== - dependencies: - pump "^3.0.0" - -get-stream@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" - integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== - -get-symbol-description@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz#7fdb81c900101fbd564dd5f1a30af5aadc1e58d6" - integrity sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.1.1" - -get-tsconfig@^4.7.0: - version "4.7.3" - resolved "https://registry.yarnpkg.com/get-tsconfig/-/get-tsconfig-4.7.3.tgz#0498163d98f7b58484dd4906999c0c9d5f103f83" - integrity sha512-ZvkrzoUA0PQZM6fy6+/Hce561s+faD1rsNwhnO5FelNjyy7EMGJ3Rz1AQ8GYDWjhRs/7dBLOEJvhK8MiEJOAFg== - dependencies: - resolve-pkg-maps "^1.0.0" - -get-value@^2.0.3, get-value@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" - integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= - -getpass@^0.1.1: - version "0.1.7" - resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" - integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= - dependencies: - assert-plus "^1.0.0" - -ghost-testrpc@^0.0.2: - version "0.0.2" - resolved "https://registry.yarnpkg.com/ghost-testrpc/-/ghost-testrpc-0.0.2.tgz#c4de9557b1d1ae7b2d20bbe474a91378ca90ce92" - integrity sha512-i08dAEgJ2g8z5buJIrCTduwPIhih3DP+hOCTyyryikfV8T0bNvHnGXO67i0DD1H4GBDETTclPy9njZbfluQYrQ== - dependencies: - chalk "^2.4.2" - node-emoji "^1.10.0" - -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-parent@^6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" - integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== - dependencies: - is-glob "^4.0.3" - -glob@7.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.6: - version "7.1.6" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" - integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== - 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, glob@^7.0.0, glob@^7.1.2, glob@^7.1.3, glob@~7.2.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" - integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -glob@8.1.0: - 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= - dependencies: - inflight "^1.0.4" - inherits "2" - minimatch "2 || 3" - 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" - integrity sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A== - dependencies: - global-prefix "^3.0.0" - -global-prefix@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-3.0.0.tgz#fc85f73064df69f50421f47f883fe5b913ba9b97" - integrity sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg== - dependencies: - ini "^1.3.5" - kind-of "^6.0.2" - which "^1.3.1" - -global@~4.4.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/global/-/global-4.4.0.tgz#3e7b105179006a323ed71aafca3e9c57a5cc6406" - integrity sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w== - dependencies: - min-document "^2.19.0" - process "^0.11.10" - -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== - -globals@^13.19.0, globals@^13.24.0: - version "13.24.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-13.24.0.tgz#8432a19d78ce0c1e833949c36adb345400bb1171" - integrity sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ== - dependencies: - 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== - -globby@^10.0.1: - version "10.0.2" - resolved "https://registry.yarnpkg.com/globby/-/globby-10.0.2.tgz#277593e745acaa4646c3ab411289ec47a0392543" - integrity sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg== - dependencies: - "@types/glob" "^7.1.1" - array-union "^2.1.0" - dir-glob "^3.0.1" - fast-glob "^3.0.3" - glob "^7.1.3" - ignore "^5.1.1" - merge2 "^1.2.3" - slash "^3.0.0" - -globby@^11.1.0: - version "11.1.0" - resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" - integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== - dependencies: - array-union "^2.1.0" - dir-glob "^3.0.1" - fast-glob "^3.2.9" - ignore "^5.2.0" - merge2 "^1.4.1" - slash "^3.0.0" - -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.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@^4.2.0: - version "4.2.10" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" - integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== - -graphemer@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" - integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== - -growl@1.10.5: - version "1.10.5" - resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" - integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== - -handlebars@^4.0.1: - 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" - source-map "^0.6.1" - wordwrap "^1.0.0" - optionalDependencies: - uglify-js "^3.1.4" - -har-schema@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" - integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= - -har-validator@~5.1.3: - version "5.1.5" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.5.tgz#1f0803b9f8cb20c0fa13822df1ecddb36bde1efd" - integrity sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w== - dependencies: - ajv "^6.12.3" - har-schema "^2.0.0" - -hardhat-gas-reporter@^1.0.4: - version "1.0.8" - resolved "https://registry.yarnpkg.com/hardhat-gas-reporter/-/hardhat-gas-reporter-1.0.8.tgz#93ce271358cd748d9c4185dbb9d1d5525ec145e0" - integrity sha512-1G5thPnnhcwLHsFnl759f2tgElvuwdkzxlI65fC9PwxYMEe9cmjkVAAWTf3/3y8uP6ZSPiUiOW8PgZnykmZe0g== - dependencies: - array-uniq "1.0.3" - eth-gas-reporter "^0.2.24" - sha1 "^1.1.1" - -hardhat@^2.22.0: - version "2.22.0" - resolved "https://registry.yarnpkg.com/hardhat/-/hardhat-2.22.0.tgz#ccb03fbacc2a3c5902a70e0e4df4acd92ee533f0" - integrity sha512-t1J+ThxNYANL6ub6yM5XC84RY38vhfG7ODBtVRNQFQozdALo3qZUjxDzyGQU0U0eswe6orK49hq9UpdB7nPXNQ== - dependencies: - "@ethersproject/abi" "^5.1.2" - "@metamask/eth-sig-util" "^4.0.0" - "@nomicfoundation/edr" "^0.3.0" - "@nomicfoundation/ethereumjs-common" "4.0.4" - "@nomicfoundation/ethereumjs-tx" "5.0.4" - "@nomicfoundation/ethereumjs-util" "9.0.4" - "@nomicfoundation/solidity-analyzer" "^0.1.0" - "@sentry/node" "^5.18.1" - "@types/bn.js" "^5.1.0" - "@types/lru-cache" "^5.1.0" - adm-zip "^0.4.16" - aggregate-error "^3.0.0" - ansi-escapes "^4.3.0" - boxen "^5.1.2" - chalk "^2.4.2" - chokidar "^3.4.0" - ci-info "^2.0.0" - debug "^4.1.1" - enquirer "^2.3.0" - env-paths "^2.2.0" - ethereum-cryptography "^1.0.3" - ethereumjs-abi "^0.6.8" - find-up "^2.1.0" - fp-ts "1.19.3" - fs-extra "^7.0.1" - glob "7.2.0" - immutable "^4.0.0-rc.12" - io-ts "1.10.4" - keccak "^3.0.2" - lodash "^4.17.11" - mnemonist "^0.38.0" - mocha "^10.0.0" - p-map "^4.0.0" - raw-body "^2.4.1" - resolve "1.17.0" - semver "^6.3.0" - solc "0.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-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= - dependencies: - ansi-regex "^2.0.0" - -has-bigints@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.1.tgz#64fe6acb020673e3b78db035a5af69aa9d07b113" - integrity sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA== - -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= - -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= - -has-flag@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" - integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== - -has-property-descriptors@^1.0.0: - version "1.0.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-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-symbols@^1.0.0, has-symbols@^1.0.1, 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-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== - dependencies: - has-symbol-support-x "^1.4.1" - -has-tostringtag@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" - integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== - dependencies: - has-symbols "^1.0.2" - -has-value@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" - integrity sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8= - dependencies: - get-value "^2.0.3" - has-values "^0.1.4" - isobject "^2.0.0" - -has-value@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" - integrity sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc= - dependencies: - get-value "^2.0.6" - has-values "^1.0.0" - isobject "^3.0.0" - -has-values@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" - integrity sha1-bWHeldkd/Km5oCCJrThL/49it3E= - -has-values@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" - integrity sha1-lbC2P+whRmGab+V/51Yo1aOe/k8= - dependencies: - is-number "^3.0.0" - kind-of "^4.0.0" - -has@^1.0.3, has@~1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" - integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== - dependencies: - function-bind "^1.1.1" - -hash-base@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.1.0.tgz#55c381d9e06e1d2997a883b4a3fddfe7f0d3af33" - integrity sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA== - dependencies: - inherits "^2.0.4" - readable-stream "^3.6.0" - safe-buffer "^5.2.0" - -hash.js@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.3.tgz#340dedbe6290187151c1ea1d777a3448935df846" - integrity sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA== - dependencies: - inherits "^2.0.3" - minimalistic-assert "^1.0.0" - -hash.js@1.1.7, hash.js@^1.0.0, hash.js@^1.0.3, hash.js@^1.1.7: - version "1.1.7" - resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" - integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== - dependencies: - inherits "^2.0.3" - minimalistic-assert "^1.0.1" - -hasown@^2.0.0: - 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== - -heap@0.2.6: - version "0.2.6" - resolved "https://registry.yarnpkg.com/heap/-/heap-0.2.6.tgz#087e1f10b046932fc8594dd9e6d378afc9d1e5ac" - integrity sha1-CH4fELBGky/IWU3Z5tN4r8nR5aw= - -"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== - -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= - 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= - dependencies: - os-homedir "^1.0.0" - os-tmpdir "^1.0.1" - -hosted-git-info@^2.1.4, hosted-git-info@^2.6.0: - 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== - -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.8.1: - version "1.8.1" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.8.1.tgz#7c3f28577cbc8a207388455dbd62295ed07bd68c" - integrity sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g== - dependencies: - depd "~1.1.2" - inherits "2.0.4" - setprototypeof "1.2.0" - statuses ">= 1.5.0 < 2" - toidentifier "1.0.1" - -http-errors@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" - integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== - dependencies: - depd "2.0.0" - inherits "2.0.4" - setprototypeof "1.2.0" - statuses "2.0.1" - toidentifier "1.0.1" - -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= - -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= - dependencies: - assert-plus "^1.0.0" - jsprim "^1.2.2" - sshpk "^1.7.0" - -https-proxy-agent@^5.0.0: - version "5.0.1" - resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" - integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== - dependencies: - agent-base "6" - debug "4" - -human-signals@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-3.0.1.tgz#c740920859dafa50e5a3222da9d3bf4bb0e5eef5" - integrity sha512-rQLskxnM/5OCldHo+wNXbpVgDn5A17CUoKX+7Sokwaknlq7CdSnphy0W39GU8dw59XiCXmFXDg4fRuckQRKewQ== - -husky@^8.0.1: - version "8.0.1" - resolved "https://registry.yarnpkg.com/husky/-/husky-8.0.1.tgz#511cb3e57de3e3190514ae49ed50f6bc3f50b3e9" - integrity sha512-xs7/chUH/CKdOCs7Zy0Aev9e/dKOMZf3K1Az1nar3tzlv0jfqnYtu235bstsWTmXOR0EfINrPa97yy4Lz6RiKw== - -iconv-lite@0.4.24, 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.3" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" - integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== - 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" - integrity sha512-PWoF9Keq6laYdIRwwCdhTPl60xRqAloYNMQLiyUnG42VjT53oW07BXIRM+NK7eQjzXjAk2gUvX9caRxlnF9TAA== - dependencies: - punycode "2.1.0" - -ieee754@^1.1.13: - 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, ignore@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" - integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== - -ignore@^5.2.4: - version "5.3.1" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.1.tgz#5073e554cd42c5b33b394375f538b8593e34d4ef" - integrity sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw== - -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== - -immediate@~3.2.3: - version "3.2.3" - resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.2.3.tgz#d140fa8f614659bd6541233097ddaac25cdd991c" - integrity sha1-0UD6j2FGWb1lQSMwl92qwlzdmRw= - -immutable@^4.0.0-rc.12: - version "4.0.0" - resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.0.0.tgz#b86f78de6adef3608395efb269a91462797e2c23" - integrity sha512-zIE9hX70qew5qTUjSS7wi1iwj/l7+m54KWU247nhM3v806UdGj1yDndXj+IOYxxtW9zyLI+xqFNZjTuDaLUqFw== - -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" - -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" - -imurmurhash@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" - integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= - -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= - 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: - version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - -ini@^1.3.5: - 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== - 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" - -internal-slot@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.3.tgz#7347e307deeea2faac2ac6205d4bc7d34967f59c" - integrity sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA== - dependencies: - get-intrinsic "^1.1.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 sha1-EEqOSqym09jNFXqO+L+rLXo//bY= - -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== - -is-accessor-descriptor@^0.1.6: - version "0.1.6" - resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" - integrity sha1-qeEss66Nh2cn7u84Q/igiXtcmNY= - dependencies: - kind-of "^3.0.2" - -is-accessor-descriptor@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" - integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== - dependencies: - kind-of "^6.0.0" - -is-arguments@^1.0.4: - 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-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= - -is-bigint@^1.0.1: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3" - integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg== - dependencies: - has-bigints "^1.0.1" - -is-binary-path@~2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" - integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== - dependencies: - binary-extensions "^2.0.0" - -is-boolean-object@^1.1.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719" - integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA== - dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" - -is-buffer@^1.1.5: - version "1.1.6" - resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" - integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== - -is-buffer@~2.0.3: - version "2.0.5" - resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.5.tgz#ebc252e400d22ff8d77fa09888821a24a658c191" - integrity sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ== - -is-builtin-module@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-3.2.1.tgz#f03271717d8654cfcaf07ab0463faa3571581169" - integrity sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A== - dependencies: - builtin-modules "^3.3.0" - -is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.4.tgz#47301d58dd0259407865547853df6d61fe471945" - integrity sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w== - -is-ci@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c" - integrity sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w== - dependencies: - ci-info "^2.0.0" - -is-core-module@^2.12.1, is-core-module@^2.13.0: - version "2.13.1" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.1.tgz#ad0d7532c6fea9da1ebdc82742d74525c6273384" - integrity sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw== - dependencies: - hasown "^2.0.0" - -is-core-module@^2.8.1: - version "2.8.1" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.8.1.tgz#f59fdfca701d5879d0a6b100a40aa1560ce27211" - integrity sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA== - dependencies: - has "^1.0.3" - -is-data-descriptor@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" - integrity sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y= - dependencies: - kind-of "^3.0.2" - -is-data-descriptor@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" - integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== - dependencies: - kind-of "^6.0.0" - -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-descriptor@^0.1.0: - version "0.1.6" - resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" - integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== - dependencies: - is-accessor-descriptor "^0.1.6" - is-data-descriptor "^0.1.4" - kind-of "^5.0.0" - -is-descriptor@^1.0.0, is-descriptor@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" - integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== - dependencies: - is-accessor-descriptor "^1.0.0" - is-data-descriptor "^1.0.0" - kind-of "^6.0.2" - -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-docker@^2.0.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" - integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== - -is-extendable@^0.1.0, is-extendable@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" - integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik= - -is-extendable@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" - integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== - dependencies: - is-plain-object "^2.0.4" - -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== - -is-fn@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-fn/-/is-fn-1.0.0.tgz#9543d5de7bcf5b08a22ec8a20bae6e286d510d8c" - integrity sha1-lUPV3nvPWwiiLsiiC65uKG1RDYw= - -is-fullwidth-code-point@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" - integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= - 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= - -is-fullwidth-code-point@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" - integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== - -is-fullwidth-code-point@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz#fae3167c729e7463f8461ce512b080a49268aa88" - integrity sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ== - -is-function@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-function/-/is-function-1.0.2.tgz#4f097f30abf6efadac9833b17ca5dc03f8144e08" - integrity sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ== - -is-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= - -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@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" - integrity sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU= - dependencies: - kind-of "^3.0.2" - -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.2" - resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.2.tgz#a56552e1c665c9e950b4a025461da87e72f86fcf" - integrity sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA== - -is-path-inside@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" - integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== - -is-plain-obj@^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= - -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-plain-object@^2.0.3, is-plain-object@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" - integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== - dependencies: - isobject "^3.0.1" - -is-primitive@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-3.0.1.tgz#98c4db1abff185485a657fc2905052b940524d05" - integrity sha512-GljRxhWvlCNRfZyORiH77FwdFwGcMO620o37EOYC0ORWdq+WYNVqW0w2Juzew4M+L81l6/QS3t5gkkihyRqv9w== - -is-regex@^1.0.4, is-regex@^1.1.4, is-regex@~1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" - integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== - dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" - -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-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@^1.0.0, is-stream@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" - integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= - -is-stream@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-3.0.0.tgz#e6bfd7aa6bef69f4f472ce9bb681e3e57b4319ac" - integrity sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA== - -is-string@^1.0.5, is-string@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" - integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg== - dependencies: - has-tostringtag "^1.0.0" - -is-symbol@^1.0.2, is-symbol@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c" - integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== - dependencies: - has-symbols "^1.0.2" - -is-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= - -is-unicode-supported@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" - integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== - -is-url@^1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/is-url/-/is-url-1.2.4.tgz#04a4df46d28c4cff3d73d01ff06abeb318a1aa52" - integrity sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww== - -is-utf8@^0.2.0: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" - integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI= - -is-weakref@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2" - integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ== - dependencies: - call-bind "^1.0.2" - -is-windows@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" - integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== - -is-wsl@^2.1.1: - version "2.2.0" - resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" - integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== - dependencies: - is-docker "^2.0.0" - -isarray@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" - integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= - -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= - -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= - -isobject@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" - integrity sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk= - dependencies: - isarray "1.0.0" - -isobject@^3.0.0, isobject@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" - integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= - -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= - -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" - -iterate-object@^1.3.4: - version "1.3.4" - resolved "https://registry.yarnpkg.com/iterate-object/-/iterate-object-1.3.4.tgz#fa50b1d9e58e340a7dd6b4c98c8a5e182e790096" - integrity sha512-4dG1D1x/7g8PwHS9aK6QV5V94+ZvyP4+d19qDv43EzImmrndysIl4prmJ1hWWIGCqrZHyaHBm6BSEWHOLnpoNw== - -jake@^10.8.5: - version "10.8.5" - resolved "https://registry.yarnpkg.com/jake/-/jake-10.8.5.tgz#f2183d2c59382cb274226034543b9c03b8164c46" - integrity sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw== - dependencies: - async "^3.2.3" - chalk "^4.0.2" - filelist "^1.0.1" - minimatch "^3.0.4" - -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= - -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: - 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" - integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw== - dependencies: - 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.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.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.0.0.tgz#f426bc0ff4b4051926cd588c71113183409a121f" - integrity sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q== - dependencies: - argparse "^2.0.1" - -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= - -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-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-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-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= - dependencies: - inherits "^2.0.1" - -json-rpc-random-id@^1.0.0: - 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-schema-traverse@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" - integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== - -json-schema-traverse@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" - integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== - -json-schema@0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5" - integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA== - -json-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" - -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= - -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== - 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= - 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= - optionalDependencies: - graceful-fs "^4.1.6" - -jsonfile@^6.0.1: - version "6.1.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" - integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== - dependencies: - universalify "^2.0.0" - optionalDependencies: - graceful-fs "^4.1.6" - -jsonify@~0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" - integrity sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM= - -jsonschema@^1.2.4: - version "1.4.0" - resolved "https://registry.yarnpkg.com/jsonschema/-/jsonschema-1.4.0.tgz#1afa34c4bc22190d8e42271ec17ac8b3404f87b2" - integrity sha512-/YgW6pRMr6M7C+4o8kS+B/2myEpHCrxO4PEWnqJNBFMjn7EWXqlQ4tGwL6xTHeRplwuZmcAncdvfOad1nT2yMw== - -jsprim@^1.2.2: - version "1.4.2" - resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.2.tgz#712c65533a15c878ba59e9ed5f0e26d5b77c5feb" - integrity sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw== - dependencies: - assert-plus "1.0.0" - extsprintf "1.3.0" - json-schema "0.4.0" - verror "1.10.0" - -keccak@3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/keccak/-/keccak-3.0.1.tgz#ae30a0e94dbe43414f741375cff6d64c8bea0bff" - integrity sha512-epq90L9jlFWCW7+pQa6JOnKn2Xgl2mtI664seYR6MHskvI9agt7AnDqmAlp9TqU4/caMYbA08Hi5DMZAl5zdkA== - dependencies: - node-addon-api "^2.0.0" - node-gyp-build "^4.2.0" - -keccak@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/keccak/-/keccak-3.0.2.tgz#4c2c6e8c54e04f2670ee49fa734eb9da152206e0" - integrity sha512-PyKKjkH53wDMLGrvmRGSNWgmSxZOUqbnXwKL9tmgbFYA1iAYqW21kfR7mZXV0MlESiefxQQE9X9fTa3X+2MPDQ== - dependencies: - node-addon-api "^2.0.0" - node-gyp-build "^4.2.0" - readable-stream "^3.6.0" - -keccak@^3.0.2: - version "3.0.4" - resolved "https://registry.yarnpkg.com/keccak/-/keccak-3.0.4.tgz#edc09b89e633c0549da444432ecf062ffadee86d" - integrity sha512-3vKuW0jV8J3XNTzvfyicFR5qvxrSAGl7KIhvgOu5cmWwM7tZRj3fMbj/pfIf4be7aznbc+prBWGjywox/g2Y6Q== - dependencies: - node-addon-api "^2.0.0" - node-gyp-build "^4.2.0" - 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== - dependencies: - json-buffer "3.0.0" - -kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: - version "3.2.2" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" - integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= - dependencies: - is-buffer "^1.1.5" - -kind-of@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" - integrity sha1-IIE989cSkosgc3hpGkUGb65y3Vc= - dependencies: - is-buffer "^1.1.5" - -kind-of@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" - integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== - -kind-of@^6.0.0, kind-of@^6.0.2: - 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== - -klaw-sync@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/klaw-sync/-/klaw-sync-6.0.0.tgz#1fd2cfd56ebb6250181114f0a581167099c2b28c" - integrity sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ== - dependencies: - graceful-fs "^4.1.11" - -klaw@^1.0.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/klaw/-/klaw-1.3.1.tgz#4088433b46b3b1ba259d78785d8e96f73ba02439" - integrity sha1-QIhDO0azsbolnXh4XY6W9zugJDk= - optionalDependencies: - graceful-fs "^4.1.9" - -lcid@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" - integrity sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU= - dependencies: - invert-kv "^1.0.0" - -level-codec@^9.0.0: - version "9.0.2" - resolved "https://registry.yarnpkg.com/level-codec/-/level-codec-9.0.2.tgz#fd60df8c64786a80d44e63423096ffead63d8cbc" - integrity sha512-UyIwNb1lJBChJnGfjmO0OR+ezh2iVu1Kas3nvBS/BzGnx79dv6g7unpKIDNPMhfdTEGoc7mC8uAu51XEtX+FHQ== - dependencies: - buffer "^5.6.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== - dependencies: - errno "~0.1.1" - -level-errors@^2.0.0, level-errors@~2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/level-errors/-/level-errors-2.0.1.tgz#2132a677bf4e679ce029f517c2f17432800c05c8" - integrity sha512-UVprBJXite4gPS+3VznfgDSU8PTRuVX0NXwoWW50KLxd2yw4Y1t2JUR5In1itQnudZqRMT9DlAM3Q//9NCjCFw== - dependencies: - errno "~0.1.1" - -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-iterator-stream@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/level-iterator-stream/-/level-iterator-stream-2.0.3.tgz#ccfff7c046dcf47955ae9a86f46dfa06a31688b4" - integrity sha512-I6Heg70nfF+e5Y3/qfthJFexhRw/Gi3bIymCoXAlijZdAcLaPuWSJs3KXyTYf23ID6g0o2QF62Yh+grOXY3Rig== - dependencies: - inherits "^2.0.1" - readable-stream "^2.0.5" - xtend "^4.0.0" - -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= - dependencies: - inherits "^2.0.1" - level-errors "^1.0.3" - readable-stream "^1.0.33" - xtend "^4.0.0" - -level-iterator-stream@~3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/level-iterator-stream/-/level-iterator-stream-3.0.1.tgz#2c98a4f8820d87cdacab3132506815419077c730" - integrity sha512-nEIQvxEED9yRThxvOrq8Aqziy4EGzrxSZK+QzEFAVuJvQ8glfyZ96GB6BoI4sBbLfjMXm2w4vu3Tkcm9obcY0g== - dependencies: - inherits "^2.0.1" - readable-stream "^2.3.6" - xtend "^4.0.0" - -level-mem@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/level-mem/-/level-mem-3.0.1.tgz#7ce8cf256eac40f716eb6489654726247f5a89e5" - integrity sha512-LbtfK9+3Ug1UmvvhR2DqLqXiPW1OJ5jEh0a3m9ZgAipiwpSxGj/qaVVy54RG5vAQN1nCuXqjvprCuKSCxcJHBg== - dependencies: - level-packager "~4.0.0" - memdown "~3.0.0" - -level-packager@~4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/level-packager/-/level-packager-4.0.1.tgz#7e7d3016af005be0869bc5fa8de93d2a7f56ffe6" - integrity sha512-svCRKfYLn9/4CoFfi+d8krOtrp6RoX8+xm0Na5cgXMqSyRru0AnDYdLl+YI8u1FyS6gGZ94ILLZDE5dh2but3Q== - dependencies: - encoding-down "~5.0.0" - levelup "^3.0.0" - -level-post@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/level-post/-/level-post-1.0.7.tgz#19ccca9441a7cc527879a0635000f06d5e8f27d0" - integrity sha512-PWYqG4Q00asOrLhX7BejSajByB4EmG2GaKHfj3h5UmmZ2duciXLPGYWIjBzLECFWUGOZWlm5B20h/n3Gs3HKew== - dependencies: - ltgt "^2.1.2" - -level-sublevel@6.6.4: - version "6.6.4" - resolved "https://registry.yarnpkg.com/level-sublevel/-/level-sublevel-6.6.4.tgz#f7844ae893919cd9d69ae19d7159499afd5352ba" - integrity sha512-pcCrTUOiO48+Kp6F1+UAzF/OtWqLcQVTVF39HLdZ3RO8XBoXt+XVPKZO1vVr1aUoxHZA9OtD2e1v7G+3S5KFDA== - dependencies: - bytewise "~1.1.0" - level-codec "^9.0.0" - level-errors "^2.0.0" - level-iterator-stream "^2.0.3" - ltgt "~2.1.1" - pull-defer "^0.2.2" - pull-level "^2.0.3" - pull-stream "^3.6.8" - typewiselite "~1.0.0" - xtend "~4.0.0" - -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= - dependencies: - readable-stream "~1.0.15" - xtend "~2.1.1" - -level-ws@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/level-ws/-/level-ws-1.0.0.tgz#19a22d2d4ac57b18cc7c6ecc4bd23d899d8f603b" - integrity sha512-RXEfCmkd6WWFlArh3X8ONvQPm8jNpfA0s/36M4QzLqrLEIt1iJE9WBHLZ5vZJK6haMjJPJGJCQWfjMNnRcq/9Q== - dependencies: - inherits "^2.0.3" - readable-stream "^2.2.8" - xtend "^4.0.1" - -levelup@3.1.1, levelup@^3.0.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/levelup/-/levelup-3.1.1.tgz#c2c0b3be2b4dc316647c53b42e2f559e232d2189" - integrity sha512-9N10xRkUU4dShSRRFTBdNaBxofz+PGaIZO962ckboJZiNmLuhVT6FZ6ZKAsICKfUBO76ySaYU6fJWX/jnj3Lcg== - dependencies: - deferred-leveldown "~4.0.0" - level-errors "~2.0.0" - level-iterator-stream "~3.0.0" - xtend "~4.0.0" - -levelup@^1.2.1: - version "1.3.9" - resolved "https://registry.yarnpkg.com/levelup/-/levelup-1.3.9.tgz#2dbcae845b2bb2b6bea84df334c475533bbd82ab" - integrity sha512-VVGHfKIlmw8w1XqpGOAGwq6sZm2WwWLmlDcULkKWQXEA5EopA8OBNJ2Ck2v6bdk8HeEZSbCSEgzXadyQFm76sQ== - 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" - -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= - 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" - -lilconfig@2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.0.5.tgz#19e57fd06ccc3848fd1891655b5a447092225b25" - integrity sha512-xaYmXZtTHPAw5m+xLN8ab9C+3a8YmV3asNSPOATITbtwrfbwaLJj8h66H1WMIpALCkqsIzK3h7oQ+PdX+LQ9Eg== - -lint-staged@^13.0.3: - version "13.0.3" - resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-13.0.3.tgz#d7cdf03a3830b327a2b63c6aec953d71d9dc48c6" - integrity sha512-9hmrwSCFroTSYLjflGI8Uk+GWAwMB4OlpU4bMJEAT5d/llQwtYKoim4bLOyLCuWFAhWEupE0vkIFqtw/WIsPug== - dependencies: - cli-truncate "^3.1.0" - colorette "^2.0.17" - commander "^9.3.0" - debug "^4.3.4" - execa "^6.1.0" - lilconfig "2.0.5" - listr2 "^4.0.5" - micromatch "^4.0.5" - normalize-path "^3.0.0" - object-inspect "^1.12.2" - pidtree "^0.6.0" - string-argv "^0.3.1" - yaml "^2.1.1" - -listr2@^4.0.5: - version "4.0.5" - resolved "https://registry.yarnpkg.com/listr2/-/listr2-4.0.5.tgz#9dcc50221583e8b4c71c43f9c7dfd0ef546b75d5" - integrity sha512-juGHV1doQdpNT3GSTs9IUN43QJb7KHdF9uqg7Vufs/tG9VTzpFphqF4pm/ICdAABGQxsyNn9CiYA3StkI6jpwA== - dependencies: - cli-truncate "^2.1.0" - colorette "^2.0.16" - log-update "^4.0.0" - p-map "^4.0.0" - rfdc "^1.3.0" - rxjs "^7.5.5" - through "^2.3.8" - wrap-ansi "^7.0.0" - -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 sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA= - dependencies: - graceful-fs "^4.1.2" - parse-json "^2.2.0" - pify "^2.0.0" - pinkie-promise "^2.0.0" - strip-bom "^2.0.0" - -locate-path@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" - integrity sha1-K1aLJl7slExtnA3pw9u7ygNUzY4= - dependencies: - p-locate "^2.0.0" - path-exists "^3.0.0" - -locate-path@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" - integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== - dependencies: - p-locate "^3.0.0" - path-exists "^3.0.0" - -locate-path@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" - integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== - dependencies: - p-locate "^4.1.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 sha1-DZnzzNem0mHRm9rrkkUAXShYCOc= - -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.clonedeep@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" - integrity sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ== - -lodash.isequal@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" - integrity sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ== - -lodash.merge@^4.6.2: - version "4.6.2" - resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" - integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== - -lodash.truncate@^4.4.2: - version "4.4.2" - resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193" - integrity sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM= - -lodash@4.17.20: - version "4.17.20" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52" - integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA== - -lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.21, lodash@^4.17.4: - version "4.17.21" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" - integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== - -log-symbols@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-3.0.0.tgz#f3a08516a5dea893336a7dee14d18a1cfdab77c4" - integrity sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ== - dependencies: - chalk "^2.4.2" - -log-symbols@4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.0.0.tgz#69b3cc46d20f448eccdb75ea1fa733d9e821c920" - integrity sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA== - dependencies: - chalk "^4.0.0" - -log-symbols@4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" - integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== - dependencies: - chalk "^4.1.0" - is-unicode-supported "^0.1.0" - -log-update@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/log-update/-/log-update-4.0.0.tgz#589ecd352471f2a1c0c570287543a64dfd20e0a1" - integrity sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg== - dependencies: - ansi-escapes "^4.3.0" - cli-cursor "^3.1.0" - slice-ansi "^4.0.0" - wrap-ansi "^6.2.0" - -looper@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/looper/-/looper-2.0.0.tgz#66cd0c774af3d4fedac53794f742db56da8f09ec" - integrity sha1-Zs0Md0rz1P7axTeU90LbVtqPCew= - -looper@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/looper/-/looper-3.0.0.tgz#2efa54c3b1cbaba9b94aee2e5914b0be57fbb749" - integrity sha1-LvpUw7HLq6m5Su4uWRSwvlf7t0k= - -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== - dependencies: - js-tokens "^3.0.0 || ^4.0.0" - -loupe@^2.3.1: - version "2.3.4" - resolved "https://registry.yarnpkg.com/loupe/-/loupe-2.3.4.tgz#7e0b9bffc76f148f9be769cb1321d3dcf3cb25f3" - integrity sha512-OvKfgCC2Ndby6aSTREl5aCCPTNIzlDfQZvZxNUrBrihDhL3xcrYegTblhmEiCrg2kKQz4XsFIaemE5BF4ybSaQ== - dependencies: - get-func-name "^2.0.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== - -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== - -lru-cache@5.1.1, 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@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-3.2.0.tgz#71789b3b7f5399bec8565dda38aa30d2a097efee" - integrity sha1-cXibO39Tmb7IVl3aOKow0qCX7+4= - dependencies: - pseudomap "^1.0.1" - -lru-cache@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" - integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== - dependencies: - yallist "^4.0.0" - -lru_map@^0.3.3: - version "0.3.3" - resolved "https://registry.yarnpkg.com/lru_map/-/lru_map-0.3.3.tgz#b5c8351b9464cbd750335a79650a0ec0e56118dd" - integrity sha1-tcg1G5Rky9dQM1p5ZQoOwOVhGN0= - -ltgt@^2.1.2, ltgt@~2.2.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/ltgt/-/ltgt-2.2.1.tgz#f35ca91c493f7b73da0e07495304f17b31f87ee5" - integrity sha1-81ypHEk/e3PaDgdJUwTxezH4fuU= - -ltgt@~2.1.1: - version "2.1.3" - resolved "https://registry.yarnpkg.com/ltgt/-/ltgt-2.1.3.tgz#10851a06d9964b971178441c23c9e52698eece34" - integrity sha1-EIUaBtmWS5cReEQcI8nlJpjuzjQ= - -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-cache@^0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" - integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= - -map-visit@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" - integrity sha1-7Nyo8TFE5mDxtb1B8S80edmN+48= - dependencies: - object-visit "^1.0.0" - -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== - -md5.js@^1.3.4: - version "1.3.5" - resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" - integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg== - dependencies: - hash-base "^3.0.0" - inherits "^2.0.1" - safe-buffer "^5.1.2" - -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= - -memdown@^1.0.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/memdown/-/memdown-1.4.1.tgz#b4e4e192174664ffbae41361aa500f3119efe215" - integrity sha1-tOThkhdGZP+65BNhqlAPMRnv4hU= - dependencies: - abstract-leveldown "~2.7.1" - functional-red-black-tree "^1.0.1" - immediate "^3.2.3" - inherits "~2.0.1" - ltgt "~2.2.0" - safe-buffer "~5.1.1" - -memdown@~3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/memdown/-/memdown-3.0.0.tgz#93aca055d743b20efc37492e9e399784f2958309" - integrity sha512-tbV02LfZMWLcHcq4tw++NuqMO+FZX8tNJEiD2aNRm48ZZusVg5N8NART+dmBkepJVye986oixErf7jfXboMGMA== - dependencies: - abstract-leveldown "~5.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" - -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= - -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= - -merge-stream@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" - integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== - -merge2@^1.2.3, merge2@^1.3.0, merge2@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" - integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== - -merkle-patricia-tree@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/merkle-patricia-tree/-/merkle-patricia-tree-3.0.0.tgz#448d85415565df72febc33ca362b8b614f5a58f8" - integrity sha512-soRaMuNf/ILmw3KWbybaCjhx86EYeBbD8ph0edQCTed0JN/rxDt1EBN52Ajre3VyGo+91f8+/rfPIRQnnGMqmQ== - dependencies: - async "^2.6.1" - ethereumjs-util "^5.2.0" - level-mem "^3.0.1" - level-ws "^1.0.0" - readable-stream "^3.0.6" - rlp "^2.0.0" - semaphore ">=1.0.1" - -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= - -micro-ftch@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/micro-ftch/-/micro-ftch-0.3.1.tgz#6cb83388de4c1f279a034fb0cf96dfc050853c5f" - integrity sha512-/0LLxhzP0tfiR5hcQebtudP56gUurs2CLkGarnCiB/OqEyUFQ6U3paQi/tgLv0hBJYt2rnr9MNpxz4fiiugstg== - -micromatch@^3.1.4: - version "3.1.10" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" - integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== - dependencies: - arr-diff "^4.0.0" - array-unique "^0.3.2" - braces "^2.3.1" - define-property "^2.0.2" - extend-shallow "^3.0.2" - extglob "^2.0.4" - fragment-cache "^0.2.1" - kind-of "^6.0.2" - nanomatch "^1.2.9" - object.pick "^1.3.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.2" - -micromatch@^4.0.2, micromatch@^4.0.4, micromatch@^4.0.5: - version "4.0.5" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" - integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== - dependencies: - braces "^3.0.2" - picomatch "^2.3.1" - -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== - dependencies: - bn.js "^4.0.0" - brorand "^1.0.1" - -mime-db@1.52.0: - version "1.52.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" - integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== - -mime-types@^2.1.12, mime-types@^2.1.16, mime-types@~2.1.19, mime-types@~2.1.24, mime-types@~2.1.34: - version "2.1.35" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" - integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== - dependencies: - mime-db "1.52.0" - -mime@1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" - integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== - -mimic-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.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" - integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== - -mimic-fn@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-4.0.0.tgz#60a90550d5cb0b239cca65d893b1a53b29871ecc" - integrity sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw== - -mimic-response@^1.0.0, mimic-response@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" - integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== - -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= - dependencies: - dom-walk "^0.1.0" - -minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" - integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== - -minimalistic-crypto-utils@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" - integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= - -"minimatch@2 || 3", minimatch@^3.0.4, minimatch@^3.0.5, 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@3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" - integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== - dependencies: - brace-expansion "^1.1.7" - -minimatch@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@9.0.3: - version "9.0.3" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.3.tgz#a6e00c3de44c3a542bfaae70abfc22420a6da825" - integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg== - 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@^1.2.0, minimist@^1.2.5, minimist@^1.2.6, minimist@~1.2.6: - version "1.2.6" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44" - integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q== - -minipass@^2.6.0, minipass@^2.9.0: - version "2.9.0" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.9.0.tgz#e713762e7d3e32fed803115cf93e04bca9fcc9a6" - integrity sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg== - dependencies: - safe-buffer "^5.1.2" - yallist "^3.0.0" - -minizlib@^1.3.3: - version "1.3.3" - resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.3.3.tgz#2290de96818a34c29551c8a8d301216bd65a861d" - integrity sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q== - dependencies: - minipass "^2.9.0" - -mixin-deep@^1.2.0: - version "1.3.2" - resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" - integrity sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA== - dependencies: - for-in "^1.0.2" - is-extendable "^1.0.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= - dependencies: - mkdirp "*" - -mkdirp@*, mkdirp@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" - integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== - -mkdirp@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" - -mkdirp@0.5.x, mkdirp@^0.5.1, 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" - -mnemonist@^0.38.0: - version "0.38.5" - resolved "https://registry.yarnpkg.com/mnemonist/-/mnemonist-0.38.5.tgz#4adc7f4200491237fe0fa689ac0b86539685cade" - integrity sha512-bZTFT5rrPKtPJxj8KSV0WkPyNxl72vQepqqVUAW2ARUpUSF2qXMB6jZj7hW5/k7C1rtpzqbD/IIbJwLXUjCHeg== - dependencies: - obliterator "^2.0.0" - -mocha@^10.0.0, 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.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 "3.5.0" - escape-string-regexp "1.0.5" - find-up "3.0.0" - glob "7.1.3" - growl "1.10.5" - he "1.2.0" - js-yaml "3.13.1" - log-symbols "3.0.0" - minimatch "3.0.4" - mkdirp "0.5.5" - ms "2.1.1" - node-environment-flags "1.0.6" - object.assign "4.1.0" - strip-json-comments "2.0.1" - supports-color "6.0.0" - which "1.3.1" - wide-align "1.1.3" - yargs "13.3.2" - yargs-parser "13.1.2" - yargs-unparser "1.6.0" - -mocha@^8.2.1: - version "8.4.0" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-8.4.0.tgz#677be88bf15980a3cae03a73e10a0fc3997f0cff" - integrity sha512-hJaO0mwDXmZS4ghXsvPVriOhsxQ7ofcpQdm8dE+jISUOKopitvnXFQmpRR7jd2K6VBG6E26gU3IAbXXGIbu4sQ== - dependencies: - "@ungap/promise-all-settled" "1.1.2" - ansi-colors "4.1.1" - browser-stdout "1.3.1" - chokidar "3.5.1" - debug "4.3.1" - diff "5.0.0" - escape-string-regexp "4.0.0" - find-up "5.0.0" - glob "7.1.6" - growl "1.10.5" - he "1.2.0" - js-yaml "4.0.0" - log-symbols "4.0.0" - minimatch "3.0.4" - ms "2.1.3" - nanoid "3.1.20" - serialize-javascript "5.0.1" - strip-json-comments "3.1.1" - supports-color "8.1.1" - which "2.0.2" - wide-align "1.1.3" - workerpool "6.1.0" - yargs "16.2.0" - yargs-parser "20.2.4" - yargs-unparser "2.0.0" - -mock-fs@^4.1.0: - version "4.14.0" - resolved "https://registry.yarnpkg.com/mock-fs/-/mock-fs-4.14.0.tgz#ce5124d2c601421255985e6e94da80a7357b1b18" - integrity sha512-qYvlv/exQ4+svI3UOvPUpLDF0OMX5euvUH0Ny4N5QyRyhNdgAgUrVH3iUINSzEPLvx0kbo/Bp28GJKIqvE7URw== - -ms@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= - -ms@2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" - integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== - -ms@2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" - 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" - integrity sha512-TW8q03O0f6PNFTQDvh3xxH03c8CjGaaYrjkl9UQPG6rz53TQzzxJVCIWVjzcbN/Q5Y53Zd0IBQBMVktVgNx4Fg== - dependencies: - base-x "^3.0.8" - buffer "^5.5.0" - -multibase@~0.6.0: - version "0.6.1" - resolved "https://registry.yarnpkg.com/multibase/-/multibase-0.6.1.tgz#b76df6298536cc17b9f6a6db53ec88f85f8cc12b" - integrity sha512-pFfAwyTjbbQgNc3G7D48JkJxWtoJoBMaR4xQUOuB8RnCgRqaYmWNFeJTTvrJ2w51bjLq2zTby6Rqj9TQ9elSUw== - dependencies: - base-x "^3.0.8" - buffer "^5.5.0" - -multicodec@^0.5.5: - version "0.5.7" - resolved "https://registry.yarnpkg.com/multicodec/-/multicodec-0.5.7.tgz#1fb3f9dd866a10a55d226e194abba2dcc1ee9ffd" - integrity sha512-PscoRxm3f+88fAtELwUnZxGDkduE2HD9Q6GHUOywQLjOGT/HAdhjLDYNZ1e7VR0s0TP0EwZ16LNUTFpoBGivOA== - dependencies: - varint "^5.0.0" - -multicodec@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/multicodec/-/multicodec-1.0.4.tgz#46ac064657c40380c28367c90304d8ed175a714f" - integrity sha512-NDd7FeS3QamVtbgfvu5h7fd1IlbaC4EQ0/pgU4zqE2vdHCmBGsUa0TiM8/TdSeG6BMPC92OOCf8F1ocE/Wkrrg== - dependencies: - buffer "^5.6.0" - varint "^5.0.0" - -multihashes@^0.4.15, multihashes@~0.4.15: - version "0.4.21" - resolved "https://registry.yarnpkg.com/multihashes/-/multihashes-0.4.21.tgz#dc02d525579f334a7909ade8a122dabb58ccfcb5" - integrity sha512-uVSvmeCWf36pU2nB4/1kzYZjsXD9vofZKpgudqkceYY5g2aZZXJ5r9lxuzoRLl1OAp28XljXsEJ/X/85ZsKmKw== - dependencies: - buffer "^5.5.0" - multibase "^0.7.0" - varint "^5.0.0" - -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= - -nan@^2.2.1: - version "2.17.0" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.17.0.tgz#c0150a2368a182f033e9aa5195ec76ea41a199cb" - integrity sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ== - -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= - -nanoassert@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/nanoassert/-/nanoassert-2.0.0.tgz#a05f86de6c7a51618038a620f88878ed1e490c09" - integrity sha512-7vO7n28+aYO4J+8w96AzhmU8G+Y/xpPDJz/se19ICsqj/momRbb9mh9ZUtkoJ5X3nTnPdhEJyc0qnM6yAsHBaA== - -nanoid@3.1.20: - version "3.1.20" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.20.tgz#badc263c6b1dcf14b71efaa85f6ab4c1d6cfc788" - integrity sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw== - -nanomatch@^1.2.9: - version "1.2.13" - resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" - integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== - dependencies: - arr-diff "^4.0.0" - array-unique "^0.3.2" - define-property "^2.0.2" - extend-shallow "^3.0.2" - fragment-cache "^0.2.1" - is-windows "^1.0.2" - kind-of "^6.0.2" - object.pick "^1.3.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - -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= - -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.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== - -node-addon-api@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-2.0.2.tgz#432cfa82962ce494b132e9d72a15b29f71ff5d32" - integrity sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA== - -node-emoji@^1.10.0: - 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 "^4.17.21" - -node-environment-flags@1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/node-environment-flags/-/node-environment-flags-1.0.6.tgz#a30ac13621f6f7d674260a54dede048c3982c088" - integrity sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw== - dependencies: - object.getownpropertydescriptors "^2.0.3" - semver "^5.7.0" - -node-fetch@^2.6.1, node-fetch@^2.6.7: - version "2.6.7" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" - integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== - 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== - dependencies: - encoding "^0.1.11" - is-stream "^1.0.1" - -node-gyp-build@^4.2.0, node-gyp-build@^4.3.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.4.0.tgz#42e99687ce87ddeaf3a10b99dc06abc11021f3f4" - integrity sha512-amJnQCcgtRVw9SvoebO3BKGESClrfXGCUTX9hSn1OuGQTQBOZmVd0Z0OlecpuRksKvbsUqALE8jls/ErClAPuQ== - -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= - dependencies: - abbrev "1" - -normalize-package-data@^2.3.2: - version "2.5.0" - resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" - integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== - dependencies: - hosted-git-info "^2.1.4" - resolve "^1.10.0" - semver "2 || 3 || 4 || 5" - validate-npm-package-license "^3.0.1" - -normalize-path@^3.0.0, normalize-path@~3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" - integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== - -normalize-url@^4.1.0: - version "4.5.1" - resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.1.tgz#0dd90cf1288ee1d1313b87081c9a5932ee48518a" - integrity sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA== - -npm-run-path@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-5.1.0.tgz#bc62f7f3f6952d9894bd08944ba011a6ee7b7e00" - integrity sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q== - dependencies: - path-key "^4.0.0" - -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 sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= - -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= - dependencies: - bn.js "4.11.6" - strip-hex-prefix "1.0.0" - -oauth-sign@~0.9.0: - version "0.9.0" - resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" - integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== - -object-assign@^4, object-assign@^4.0.0, 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-copy@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" - integrity sha1-fn2Fi3gb18mRpBupde04EnVOmYw= - dependencies: - copy-descriptor "^0.1.0" - define-property "^0.2.5" - kind-of "^3.0.3" - -object-inspect@^1.12.0, object-inspect@^1.9.0, object-inspect@~1.12.0: - version "1.12.0" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.0.tgz#6e2c120e868fd1fd18cb4f18c31741d0d6e776f0" - integrity sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g== - -object-inspect@^1.12.2: - version "1.12.2" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.2.tgz#c0641f26394532f28ab8d796ab954e43c009a8ea" - integrity sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ== - -object-is@^1.0.1: - version "1.1.5" - resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.5.tgz#b9deeaa5fc7f1846a0faecdceec138e5778f53ac" - integrity sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - -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-visit@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" - integrity sha1-95xEk68MU3e1n+OdOV5BBC3QRbs= - dependencies: - isobject "^3.0.0" - -object.assign@4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da" - integrity sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w== - dependencies: - define-properties "^1.1.2" - function-bind "^1.1.1" - has-symbols "^1.0.0" - object-keys "^1.0.11" - -object.assign@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940" - integrity sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ== - dependencies: - call-bind "^1.0.0" - define-properties "^1.1.3" - has-symbols "^1.0.1" - object-keys "^1.1.1" - -object.getownpropertydescriptors@^2.0.3, object.getownpropertydescriptors@^2.1.1: - version "2.1.3" - resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.3.tgz#b223cf38e17fefb97a63c10c91df72ccb386df9e" - integrity sha512-VdDoCwvJI4QdC6ndjpqFmoL3/+HxffFBbcJzKi5hwLLqqx3mdbedRpfZDdK0SrOSauj8X4GzBvnDZl4vTN7dOw== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.1" - -object.pick@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" - integrity sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c= - dependencies: - isobject "^3.0.1" - -object.values@^1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.5.tgz#959f63e3ce9ef108720333082131e4a459b716ac" - integrity sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.1" - -obliterator@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/obliterator/-/obliterator-2.0.3.tgz#17a7840d562c7c61eb399f4905f0e4d3b22d1d3f" - integrity sha512-qN5lHhArxl/789Bp3XCpssAYy7cvOdRzxzflmGEJaiipAT2b/USr1XvKjYyssPOwQ/3KjV1e8Ed9po9rie6E6A== - -oboe@2.1.4: - version "2.1.4" - resolved "https://registry.yarnpkg.com/oboe/-/oboe-2.1.4.tgz#20c88cdb0c15371bb04119257d4fdd34b0aa49f6" - integrity sha1-IMiM2wwVNxuwQRklfU/dNLCqSfY= - dependencies: - http-https "^1.0.0" - -on-finished@2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" - integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== - dependencies: - ee-first "1.1.1" - -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= - 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= - 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" - -onetime@^5.1.0: - version "5.1.2" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" - integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== - dependencies: - mimic-fn "^2.1.0" - -onetime@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-6.0.0.tgz#7c24c18ed1fd2e9bca4bd26806a33613c77d34b4" - integrity sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ== - dependencies: - mimic-fn "^4.0.0" - -open@^7.4.2: - version "7.4.2" - resolved "https://registry.yarnpkg.com/open/-/open-7.4.2.tgz#b8147e26dcf3e426316c730089fd71edd29c2321" - integrity sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q== - dependencies: - is-docker "^2.0.0" - is-wsl "^2.1.1" - -optionator@^0.8.1, optionator@^0.8.2: - version "0.8.3" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" - integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== - dependencies: - deep-is "~0.1.3" - fast-levenshtein "~2.0.6" - levn "~0.3.0" - prelude-ls "~1.1.2" - type-check "~0.3.2" - word-wrap "~1.2.3" - -optionator@^0.9.3: - version "0.9.3" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.3.tgz#007397d44ed1872fdc6ed31360190f81814e2c64" - integrity sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg== - dependencies: - "@aashutoshrathi/word-wrap" "^1.2.3" - deep-is "^0.1.3" - fast-levenshtein "^2.0.6" - levn "^0.4.1" - prelude-ls "^1.2.1" - type-check "^0.4.0" - -ordinal@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/ordinal/-/ordinal-1.0.3.tgz#1a3c7726a61728112f50944ad7c35c06ae3a0d4d" - integrity sha512-cMddMgb2QElm8G7vdaa02jhUNbTSrhsgAGUz1OokD83uJTwSUn+nKoNoKVVaRa08yF6sgfO7Maou1+bgLd9rdQ== - -os-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= - -os-locale@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-1.4.0.tgz#20f9f17ae29ed345e8bde583b13d2009803c14d9" - integrity sha1-IPnxeuKe00XoveWDsT0gCYA8FNk= - dependencies: - lcid "^1.0.0" - -os-tmpdir@^1.0.1, 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== - -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-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-limit@^1.1.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" - integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== - dependencies: - p-try "^1.0.0" - -p-limit@^2.0.0, p-limit@^2.2.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" - integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== - dependencies: - p-try "^2.0.0" - -p-limit@^3.0.2: - version "3.1.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" - 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= - dependencies: - p-limit "^1.1.0" - -p-locate@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" - integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== - dependencies: - p-limit "^2.0.0" - -p-locate@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" - integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== - dependencies: - p-limit "^2.2.0" - -p-locate@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" - integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== - dependencies: - p-limit "^3.0.2" - -p-map@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b" - integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== - dependencies: - aggregate-error "^3.0.0" - -p-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= - dependencies: - p-finally "^1.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= - -p-try@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" - integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== - -parent-module@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" - integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== - dependencies: - callsites "^3.0.0" - -parse-asn1@^5.0.0, parse-asn1@^5.1.5: - version "5.1.6" - resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.6.tgz#385080a3ec13cb62a62d39409cb3e88844cdaed4" - integrity sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw== - dependencies: - asn1.js "^5.2.0" - browserify-aes "^1.0.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 sha1-juqz5U+laSD+Fro493+iGqzC104= - -parse-headers@^2.0.0: - version "2.0.5" - resolved "https://registry.yarnpkg.com/parse-headers/-/parse-headers-2.0.5.tgz#069793f9356a54008571eb7f9761153e6c770da9" - integrity sha512-ft3iAoLOB/MlwbNXgzy43SWGP6sQki2jQvAyBg/zDFAgr9bfNWZIUj42Kw2eJIl8kEi4PbgE6U1Zau/HwI75HA== - -parse-json@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" - integrity sha1-9ID0BDTvgHQfhGkJn43qGPVaTck= - 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= - dependencies: - error-ex "^1.3.1" - json-parse-better-errors "^1.0.1" - -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== - -pascalcase@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" - integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= - -patch-package@6.2.2: - version "6.2.2" - resolved "https://registry.yarnpkg.com/patch-package/-/patch-package-6.2.2.tgz#71d170d650c65c26556f0d0fbbb48d92b6cc5f39" - integrity sha512-YqScVYkVcClUY0v8fF0kWOjDYopzIM8e3bj/RU1DPeEF14+dCGm6UeOYm4jvCyxqIEQ5/eJzmbWfDWnUleFNMg== - dependencies: - "@yarnpkg/lockfile" "^1.1.0" - chalk "^2.4.2" - cross-spawn "^6.0.5" - find-yarn-workspace-root "^1.2.1" - fs-extra "^7.0.1" - is-ci "^2.0.0" - klaw-sync "^6.0.0" - minimist "^1.2.0" - rimraf "^2.6.3" - semver "^5.6.0" - slash "^2.0.0" - tmp "^0.0.33" - -patch-package@^6.2.2: - version "6.4.7" - resolved "https://registry.yarnpkg.com/patch-package/-/patch-package-6.4.7.tgz#2282d53c397909a0d9ef92dae3fdeb558382b148" - integrity sha512-S0vh/ZEafZ17hbhgqdnpunKDfzHQibQizx9g8yEf5dcVk3KOflOfdufRXQX8CSEkyOQwuM/bNz1GwKvFj54kaQ== - dependencies: - "@yarnpkg/lockfile" "^1.1.0" - chalk "^2.4.2" - cross-spawn "^6.0.5" - find-yarn-workspace-root "^2.0.0" - fs-extra "^7.0.1" - is-ci "^2.0.0" - klaw-sync "^6.0.0" - minimist "^1.2.0" - open "^7.4.2" - rimraf "^2.6.3" - semver "^5.6.0" - slash "^2.0.0" - tmp "^0.0.33" - -path-browserify@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-1.0.1.tgz#d98454a9c3753d5790860f16f68867b9e46be1fd" - integrity sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g== - -path-exists@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" - integrity sha1-D+tsZPD8UY2adU3V77YscCJ2H0s= - 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= - -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: - 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.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" - integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= - -path-key@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" - integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== - -path-key@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-4.0.0.tgz#295588dc3aee64154f877adb9d780b81c554bf18" - integrity sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ== - -path-parse@^1.0.6, path-parse@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" - integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== - -path-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= - -path-type@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" - integrity sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE= - 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.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, pbkdf2@^3.0.9: - version "3.1.2" - resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.2.tgz#dd822aa0887580e52f1a039dc3eda108efae3075" - integrity sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA== - dependencies: - create-hash "^1.1.2" - create-hmac "^1.1.4" - ripemd160 "^2.0.1" - safe-buffer "^5.0.1" - sha.js "^2.4.8" - -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= - -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== - -pidtree@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/pidtree/-/pidtree-0.6.0.tgz#90ad7b6d42d5841e69e0a2419ef38f8883aa057c" - integrity sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g== - -pify@^2.0.0, pify@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" - integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= - -pify@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" - integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== - -pinkie-promise@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" - integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o= - 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= - -posix-character-classes@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" - integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= - -postinstall-postinstall@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/postinstall-postinstall/-/postinstall-postinstall-2.1.0.tgz#4f7f77441ef539d1512c40bd04c71b06a4704ca3" - integrity sha512-7hQX6ZlZXIoRiWNrbMQaLzUUfH+sSx39u8EJ9HYuDc1kLo9IXKWjM5RSquZN1ad5GnH8CGFM78fsAAQi3OKEEQ== - -precond@0.2: - version "0.2.3" - resolved "https://registry.yarnpkg.com/precond/-/precond-0.2.3.tgz#aa9591bcaa24923f1e0f4849d240f47efc1075ac" - integrity sha1-qpWRvKokkj8eD0hJ0kD0fvwQdaw= - -prelude-ls@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" - integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== - -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= - -prettier-linter-helpers@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b" - integrity sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w== - dependencies: - fast-diff "^1.1.2" - -prettier-plugin-solidity@^1.0.0-beta.13: - version "1.0.0-beta.19" - resolved "https://registry.yarnpkg.com/prettier-plugin-solidity/-/prettier-plugin-solidity-1.0.0-beta.19.tgz#7c3607fc4028f5e6a425259ff03e45eedf733df3" - integrity sha512-xxRQ5ZiiZyUoMFLE9h7HnUDXI/daf1tnmL1msEdcKmyh7ZGQ4YklkYLC71bfBpYU2WruTb5/SFLUaEb3RApg5g== - dependencies: - "@solidity-parser/parser" "^0.14.0" - emoji-regex "^10.0.0" - escape-string-regexp "^4.0.0" - semver "^7.3.5" - solidity-comments-extractor "^0.0.7" - string-width "^4.2.3" - -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== - -prettier@^2.1.2, prettier@^2.3.2: - version "2.6.2" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.6.2.tgz#e26d71a18a74c3d0f0597f55f01fb6c06c206032" - integrity sha512-PkUpF+qoXTqhOeWL9fu7As8LXsIUZ1WYaJiY/a7McAQzxjk82OF0tibkFXVCDImZtWxbvojFjerkiLb0/q8mew== - -prettier@^2.3.1: - version "2.8.8" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da" - integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q== - -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== - -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.11.10: - version "0.11.10" - resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" - integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI= - -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@^8.0.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/promise/-/promise-8.1.0.tgz#697c25c3dfe7435dd79fcd58c38a135888eaf05e" - integrity sha512-W04AqnILOL/sPRXziNicCjSNRruLAuIHEOVBazepu0545DDNGYHz7ar9ZgZ1fMU8/MA4mVxp5rkBWRi6OXIy3Q== - dependencies: - asap "~2.0.6" - -proxy-addr@~2.0.7: - version "2.0.7" - resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" - integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== - dependencies: - forwarded "0.2.0" - ipaddr.js "1.9.1" - -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= - -pseudomap@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" - integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= - -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" - -pull-cat@^1.1.9: - version "1.1.11" - resolved "https://registry.yarnpkg.com/pull-cat/-/pull-cat-1.1.11.tgz#b642dd1255da376a706b6db4fa962f5fdb74c31b" - integrity sha1-tkLdElXaN2pwa220+pYvX9t0wxs= - -pull-defer@^0.2.2: - version "0.2.3" - resolved "https://registry.yarnpkg.com/pull-defer/-/pull-defer-0.2.3.tgz#4ee09c6d9e227bede9938db80391c3dac489d113" - integrity sha512-/An3KE7mVjZCqNhZsr22k1Tx8MACnUnHZZNPSJ0S62td8JtYr/AiRG42Vz7Syu31SoTLUzVIe61jtT/pNdjVYA== - -pull-level@^2.0.3: - version "2.0.4" - resolved "https://registry.yarnpkg.com/pull-level/-/pull-level-2.0.4.tgz#4822e61757c10bdcc7cf4a03af04c92734c9afac" - integrity sha512-fW6pljDeUThpq5KXwKbRG3X7Ogk3vc75d5OQU/TvXXui65ykm+Bn+fiktg+MOx2jJ85cd+sheufPL+rw9QSVZg== - dependencies: - level-post "^1.0.7" - pull-cat "^1.1.9" - pull-live "^1.0.1" - pull-pushable "^2.0.0" - pull-stream "^3.4.0" - pull-window "^2.1.4" - stream-to-pull-stream "^1.7.1" - -pull-live@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/pull-live/-/pull-live-1.0.1.tgz#a4ecee01e330155e9124bbbcf4761f21b38f51f5" - integrity sha1-pOzuAeMwFV6RJLu89HYfIbOPUfU= - dependencies: - pull-cat "^1.1.9" - pull-stream "^3.4.0" - -pull-pushable@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/pull-pushable/-/pull-pushable-2.2.0.tgz#5f2f3aed47ad86919f01b12a2e99d6f1bd776581" - integrity sha1-Xy867UethpGfAbEqLpnW8b13ZYE= - -pull-stream@^3.2.3, pull-stream@^3.4.0, pull-stream@^3.6.8: - version "3.6.14" - resolved "https://registry.yarnpkg.com/pull-stream/-/pull-stream-3.6.14.tgz#529dbd5b86131f4a5ed636fdf7f6af00781357ee" - integrity sha512-KIqdvpqHHaTUA2mCYcLG1ibEbu/LCKoJZsBWyv9lSYtPkJPBq8m3Hxa103xHi6D2thj5YXa0TqK3L3GUkwgnew== - -pull-window@^2.1.4: - version "2.1.4" - resolved "https://registry.yarnpkg.com/pull-window/-/pull-window-2.1.4.tgz#fc3b86feebd1920c7ae297691e23f705f88552f0" - integrity sha1-/DuG/uvRkgx64pdpHiP3BfiFUvA= - dependencies: - looper "^2.0.0" - -pump@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" - integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== - dependencies: - end-of-stream "^1.1.0" - once "^1.3.1" - -punycode@1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" - integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= - -punycode@2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.0.tgz#5f863edc89b96db09074bad7947bf09056ca4e7d" - integrity sha1-X4Y+3Im5bbCQdLrXlHvwkFbKTn0= - -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== - -qs@6.10.3, qs@^6.4.0: - version "6.10.3" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.10.3.tgz#d6cde1b2ffca87b5aa57889816c5f81535e22e8e" - integrity sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ== - dependencies: - side-channel "^1.0.4" - -qs@6.9.7: - version "6.9.7" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.7.tgz#4610846871485e1e048f44ae3b94033f0e675afe" - integrity sha512-IhMFgUmuNpyRfxA90umL7ByLlgRXu6tIfKPpF5TmcfRLlLCckfP/g3IQmju6jjpu+Hh8rA+2p6A27ZSPOOHdKw== - -qs@~6.5.2: - version "6.5.3" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.3.tgz#3aeeffc91967ef6e35c0e488ef46fb296ab76aad" - integrity sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA== - -query-string@^5.0.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/query-string/-/query-string-5.1.1.tgz#a78c012b71c17e05f2e3fa2319dd330682efb3cb" - integrity sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw== - dependencies: - decode-uri-component "^0.2.0" - object-assign "^4.1.0" - strict-uri-encode "^1.0.0" - -querystring@0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" - integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= - -queue-microtask@^1.2.2: - version "1.2.3" - resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" - integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== - -r-json@^1.2.10: - version "1.2.10" - resolved "https://registry.yarnpkg.com/r-json/-/r-json-1.2.10.tgz#62a73d9cafa7eabf670e5c2812c27bdb220a968b" - integrity sha512-hu9vyLjSlHXT62NAS7DjI9WazDlvjN0lgp3n431dCVnirVcLkZIpzSwA3orhZEKzdDD2jqNYI+w0yG0aFf4kpA== - -r1csfile@0.0.16: - version "0.0.16" - resolved "https://registry.yarnpkg.com/r1csfile/-/r1csfile-0.0.16.tgz#53c66a79b50eebc2d15a1048e39d548ce9da7ccd" - integrity sha512-A2jRVWzGgmXeG2lVAc0H4suJmzt50it5UvBnycJgBCpMXM3tH/M6RguP7nvs6suY/yYnkN6jX6iTScSiDUF3FA== - dependencies: - "@iden3/bigarray" "0.0.2" - fastfile "0.0.18" - ffjavascript "0.2.22" - -randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5, randombytes@^2.0.6, 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" - -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.3: - version "2.4.3" - resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.3.tgz#8f80305d11c2a0a545c2d9d89d7a0286fcead43c" - integrity sha512-UlTNLIcu0uzb4D2f4WltY6cVjLi+/jEN4lgEUj3E04tpMDpUlkBo/eSn6zou9hum2VMNpCCUone0O0WeJim07g== - dependencies: - bytes "3.1.2" - http-errors "1.8.1" - iconv-lite "0.4.24" - unpipe "1.0.0" - -raw-body@2.5.1, raw-body@^2.4.1: - version "2.5.1" - resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.1.tgz#fe1b1628b181b700215e5fd42389f98b71392857" - integrity sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig== - dependencies: - bytes "3.1.2" - http-errors "2.0.0" - iconv-lite "0.4.24" - unpipe "1.0.0" - -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 sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI= - dependencies: - find-up "^1.0.0" - read-pkg "^1.0.0" - -read-pkg@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" - integrity sha1-9f+qXs0pyzHAR0vKfXVra7KePyg= - dependencies: - load-json-file "^1.0.0" - normalize-package-data "^2.3.2" - 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= - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.1" - isarray "0.0.1" - string_decoder "~0.10.x" - -readable-stream@^2.0.0, readable-stream@^2.0.5, readable-stream@^2.2.2, readable-stream@^2.2.8, readable-stream@^2.2.9, readable-stream@^2.3.6, readable-stream@~2.3.6: - version "2.3.7" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" - integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.3" - isarray "~1.0.0" - process-nextick-args "~2.0.0" - safe-buffer "~5.1.1" - string_decoder "~1.1.1" - util-deprecate "~1.0.1" - -readable-stream@^3.0.6, readable-stream@^3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" - integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== - 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= - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.1" - isarray "0.0.1" - string_decoder "~0.10.x" - -readdirp@~3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.2.0.tgz#c30c33352b12c96dfb4b895421a49fd5a9593839" - integrity sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ== - dependencies: - picomatch "^2.0.4" - -readdirp@~3.5.0: - version "3.5.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.5.0.tgz#9ba74c019b15d365278d2e91bb8c48d7b4d42c9e" - integrity sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ== - dependencies: - picomatch "^2.2.1" - -readdirp@~3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" - integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== - dependencies: - picomatch "^2.2.1" - -rechoir@^0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" - integrity sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q= - 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== - dependencies: - minimatch "3.0.4" - -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== - -regenerate@^1.2.1: - version "1.4.2" - resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a" - integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== - -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== - -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" - -regex-not@^1.0.0, regex-not@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" - integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== - dependencies: - extend-shallow "^3.0.2" - safe-regex "^1.1.0" - -regexp.prototype.flags@^1.2.0: - version "1.4.3" - resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz#87cab30f80f66660181a3bb7bf5981a872b367ac" - integrity sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - functions-have-names "^1.2.2" - -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== - -regexpp@^3.0.0: - 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: - version "2.0.0" - resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-2.0.0.tgz#49d038837b8dcf8bfa5b9a42139938e6ea2ae240" - integrity sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA= - dependencies: - regenerate "^1.2.1" - regjsgen "^0.2.0" - regjsparser "^0.1.4" - -regjsgen@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.2.0.tgz#6c016adeac554f75823fe37ac05b92d5a4edb1f7" - integrity sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc= - -regjsparser@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.1.5.tgz#7ee8f84dc6fa792d3fd0ae228d24bd949ead205c" - integrity sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw= - dependencies: - jsesc "~0.5.0" - -repeat-element@^1.1.2: - version "1.1.4" - resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.4.tgz#be681520847ab58c7568ac75fbfad28ed42d39e9" - integrity sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ== - -repeat-string@^1.6.1: - version "1.6.1" - resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" - integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= - -repeating@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" - integrity sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo= - dependencies: - is-finite "^1.0.0" - -req-cwd@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/req-cwd/-/req-cwd-2.0.0.tgz#d4082b4d44598036640fb73ddea01ed53db49ebc" - integrity sha1-1AgrTURZgDZkD7c93qAe1T20nrw= - dependencies: - req-from "^2.0.0" - -req-from@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/req-from/-/req-from-2.0.0.tgz#d74188e47f93796f4aa71df6ee35ae689f3e0e70" - integrity sha1-10GI5H+TeW9Kpx327jWuaJ8+DnA= - dependencies: - resolve-from "^3.0.0" - -request-promise-core@1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.4.tgz#3eedd4223208d419867b78ce815167d10593a22f" - integrity sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw== - dependencies: - lodash "^4.17.19" - -request-promise-native@^1.0.5: - version "1.0.9" - resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.9.tgz#e407120526a5efdc9a39b28a5679bf47b9d9dc28" - integrity sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g== - dependencies: - request-promise-core "1.1.4" - stealthy-require "^1.1.1" - tough-cookie "^2.3.3" - -request@^2.79.0, request@^2.85.0, request@^2.88.0: - version "2.88.2" - resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" - integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== - dependencies: - aws-sign2 "~0.7.0" - aws4 "^1.8.0" - caseless "~0.12.0" - combined-stream "~1.0.6" - extend "~3.0.2" - forever-agent "~0.6.1" - form-data "~2.3.2" - har-validator "~5.1.3" - http-signature "~1.2.0" - is-typedarray "~1.0.0" - isstream "~0.1.2" - json-stringify-safe "~5.0.1" - mime-types "~2.1.19" - oauth-sign "~0.9.0" - performance-now "^2.1.0" - qs "~6.5.2" - safe-buffer "^5.1.2" - tough-cookie "~2.5.0" - tunnel-agent "^0.6.0" - uuid "^3.3.2" - -require-directory@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" - integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= - -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 sha1-UpyczvJzgK3+yaL5ZbZJu+5jZBg= - -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 sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE= - -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-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= - -resolve-from@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" - integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== - -resolve-pkg-maps@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz#616b3dc2c57056b5588c31cdf4b3d64db133720f" - integrity sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw== - -resolve-url@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" - integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= - -resolve@1.1.x: - version "1.1.7" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" - integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs= - -resolve@1.17.0: - version "1.17.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.17.0.tgz#b25941b54968231cc2d1bb76a79cb7f2c0bf8444" - integrity sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w== - dependencies: - path-parse "^1.0.6" - -resolve@^1.1.6, resolve@^1.10.0, resolve@^1.20.0, resolve@^1.22.0, resolve@^1.8.1, resolve@~1.22.0: - version "1.22.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.0.tgz#5e0b8c67c15df57a89bdbabe603a002f21731198" - integrity sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw== - dependencies: - is-core-module "^2.8.1" - path-parse "^1.0.7" - supports-preserve-symlinks-flag "^1.0.0" - -resolve@^1.10.1, resolve@^1.22.2: - version "1.22.8" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d" - integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== - dependencies: - is-core-module "^2.13.0" - path-parse "^1.0.7" - supports-preserve-symlinks-flag "^1.0.0" - -responselike@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7" - integrity sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec= - dependencies: - lowercase-keys "^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= - dependencies: - onetime "^2.0.0" - signal-exit "^3.0.2" - -restore-cursor@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" - integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== - dependencies: - onetime "^5.1.0" - signal-exit "^3.0.2" - -resumer@~0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/resumer/-/resumer-0.0.0.tgz#f1e8f461e4064ba39e82af3cdc2a8c893d076759" - integrity sha1-8ej0YeQGS6Oegq883CqMiT0HZ1k= - dependencies: - through "~2.3.4" - -ret@~0.1.10: - version "0.1.15" - resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" - integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== - -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== - -rfdc@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.0.tgz#d0b7c441ab2720d05dc4cf26e01c89631d9da08b" - integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA== - -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, rimraf@^2.6.3: - version "2.7.1" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" - integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== - dependencies: - glob "^7.1.3" - -rimraf@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" - integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== - dependencies: - glob "^7.1.3" - -ripemd160@^2.0.0, ripemd160@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" - integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== - dependencies: - hash-base "^3.0.0" - inherits "^2.0.1" - -rlp@^2.0.0, rlp@^2.2.1, rlp@^2.2.2, 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 "^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@^1.1.9: - version "1.2.0" - resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" - integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== - dependencies: - queue-microtask "^1.2.2" - -rustbn.js@~0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/rustbn.js/-/rustbn.js-0.2.0.tgz#8082cb886e707155fd1cb6f23bd591ab8d55d0ca" - integrity sha512-4VlvkRUuCJvr2J6Y0ImW7NvTCriMi7ErOAqWk1y69vAdoNIzCF3yPmgeNzx+RQTLEDFq5sHfscn1MwHxP9hNfA== - -rxjs@^6.4.0: - version "6.6.7" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.7.tgz#90ac018acabf491bf65044235d5863c4dab804c9" - integrity sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ== - dependencies: - tslib "^1.9.0" - -rxjs@^7.5.5: - version "7.5.5" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.5.5.tgz#2ebad89af0f560f460ad5cc4213219e1f7dd4e9f" - integrity sha512-sy+H0pQofO95VDmFLzyaw9xNJU4KTRSwQIGM6+iG3SypAtCiLDzpeG8sJrNCWn2Up9km+KhkvTdbkrdy+yzZdw== - dependencies: - tslib "^2.1.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-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-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== - dependencies: - events "^3.0.0" - -safe-regex@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" - integrity sha1-QKNmnzsHfR6UPURinhV91IAjvy4= - dependencies: - ret "~0.1.10" - -"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: - version "2.1.2" - resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" - integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== - -sc-istanbul@^0.4.5: - 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" - escodegen "1.8.x" - esprima "2.7.x" - glob "^5.0.15" - handlebars "^4.0.1" - js-yaml "3.x" - mkdirp "0.5.x" - nopt "3.x" - once "1.x" - resolve "1.1.x" - supports-color "^3.1.0" - which "^1.1.1" - wordwrap "^1.0.0" - -scrypt-js@2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-2.0.4.tgz#32f8c5149f0797672e551c07e230f834b6af5f16" - integrity sha512-4KsaGcPnuhtCZQCxFxN3GVYIhKFPTdLd8PLC552XwbMndtD0cjRFAhDuuydXQ0h08ZfPgzqe6EKHozpuH74iDw== - -scrypt-js@3.0.1, scrypt-js@^3.0.0, scrypt-js@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-3.0.1.tgz#d314a57c2aef69d1ad98a138a21fe9eafa9ee312" - integrity sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA== - -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@^4.0.1: - version "4.0.3" - resolved "https://registry.yarnpkg.com/secp256k1/-/secp256k1-4.0.3.tgz#c4559ecd1b8d3c1827ed2d1b94190d69ce267303" - integrity sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA== - dependencies: - elliptic "^6.5.4" - node-addon-api "^2.0.0" - node-gyp-build "^4.2.0" - -seedrandom@3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/seedrandom/-/seedrandom-3.0.1.tgz#eb3dde015bcf55df05a233514e5df44ef9dce083" - integrity sha512-1/02Y/rUeU1CJBAGLebiC5Lbo5FnB22gQbIFFYTLkwvp1xdABZJH1sn4ZT1MzXmPpzv+Rf/Lu2NcsLJiK4rcDg== - -semaphore@>=1.0.1, semaphore@^1.0.3, semaphore@^1.1.0: - 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, semver@^5.6.0, semver@^5.7.0: - version "5.7.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" - integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== - -semver@^6.1.0: - version "6.3.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" - integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== - -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.0.0, semver@^7.5.3, semver@^7.5.4: - version "7.6.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.0.tgz#1a46a4db4bffcccd97b743b5005c8325f23d4e2d" - integrity sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg== - dependencies: - lru-cache "^6.0.0" - -semver@^7.3.4, semver@^7.3.5: - version "7.3.7" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f" - integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g== - dependencies: - lru-cache "^6.0.0" - -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== - -send@0.17.2: - version "0.17.2" - resolved "https://registry.yarnpkg.com/send/-/send-0.17.2.tgz#926622f76601c41808012c8bf1688fe3906f7820" - integrity sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww== - dependencies: - debug "2.6.9" - depd "~1.1.2" - destroy "~1.0.4" - encodeurl "~1.0.2" - escape-html "~1.0.3" - etag "~1.8.1" - fresh "0.5.2" - http-errors "1.8.1" - mime "1.6.0" - ms "2.1.3" - on-finished "~2.3.0" - range-parser "~1.2.1" - statuses "~1.5.0" - -serialize-javascript@5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-5.0.1.tgz#7886ec848049a462467a97d3d918ebb2aaf934f4" - integrity sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA== - dependencies: - randombytes "^2.1.0" - -serialize-javascript@6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" - integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== - dependencies: - randombytes "^2.1.0" - -serve-static@1.14.2: - version "1.14.2" - resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.2.tgz#722d6294b1d62626d41b43a013ece4598d292bfa" - integrity sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ== - dependencies: - encodeurl "~1.0.2" - escape-html "~1.0.3" - parseurl "~1.3.3" - send "0.17.2" - -servify@^0.1.12: - version "0.1.12" - resolved "https://registry.yarnpkg.com/servify/-/servify-0.1.12.tgz#142ab7bee1f1d033b66d0707086085b17c06db95" - integrity sha512-/xE6GvsKKqyo1BAY+KxOWXcLpPsUUyji7Qg3bVD7hh1eRze5bR1uYiuDA/k3Gof1s9BTzQZEJK8sNcNGFIzeWw== - dependencies: - body-parser "^1.16.0" - cors "^2.8.1" - express "^4.14.0" - request "^2.79.0" - xhr "^2.3.3" - -set-blocking@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" - integrity 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= - -set-value@^2.0.0, set-value@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b" - integrity sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw== - dependencies: - extend-shallow "^2.0.1" - is-extendable "^0.1.1" - is-plain-object "^2.0.3" - split-string "^3.0.1" - -set-value@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/set-value/-/set-value-4.1.0.tgz#aa433662d87081b75ad88a4743bd450f044e7d09" - integrity sha512-zTEg4HL0RwVrqcWs3ztF+x1vkxfm0lP+MQQFPiMJTKVceBwEV0A569Ou8l9IYQG8jOZdMVI1hGsc0tmeD2o/Lw== - dependencies: - is-plain-object "^2.0.4" - is-primitive "^3.0.1" - -setimmediate@1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.4.tgz#20e81de622d4a02588ce0c8da8973cbcf1d3138f" - integrity sha1-IOgd5iLUoCWIzgyNqJc8vPHTE48= - -setimmediate@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" - integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU= - -setprototypeof@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" - integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== - -sha.js@^2.4.0, sha.js@^2.4.8: - version "2.4.11" - resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" - integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== - dependencies: - inherits "^2.0.1" - safe-buffer "^5.0.1" - -sha1@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/sha1/-/sha1-1.1.1.tgz#addaa7a93168f393f19eb2b15091618e2700f848" - integrity sha1-rdqnqTFo85PxnrKxUJFhjicA+Eg= - dependencies: - charenc ">= 0.0.1" - crypt ">= 0.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= - dependencies: - shebang-regex "^1.0.0" - -shebang-command@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" - integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== - dependencies: - shebang-regex "^3.0.0" - -shebang-regex@^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.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" - -side-channel@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" - integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== - dependencies: - call-bind "^1.0.0" - get-intrinsic "^1.0.2" - object-inspect "^1.9.0" - -signal-exit@^3.0.2, signal-exit@^3.0.7: - version "3.0.7" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" - integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== - -simple-concat@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.1.tgz#f46976082ba35c2263f1c8ab5edfe26c41c9552f" - integrity sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q== - -simple-get@^2.7.0: - version "2.8.2" - resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-2.8.2.tgz#5708fb0919d440657326cd5fe7d2599d07705019" - integrity sha512-Ijd/rV5o+mSBBs4F/x9oDPtTx9Zb6X9brmnXvMW4J7IR15ngi9q5xxqWBKU744jTZiaXtxaPL7uHG6vtN8kUkw== - dependencies: - decompress-response "^3.3.0" - once "^1.3.1" - simple-concat "^1.0.0" - -slash@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" - integrity sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU= - -slash@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" - integrity sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A== - -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: - version "2.1.0" - resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636" - integrity sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ== - dependencies: - ansi-styles "^3.2.0" - astral-regex "^1.0.0" - is-fullwidth-code-point "^2.0.0" - -slice-ansi@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-3.0.0.tgz#31ddc10930a1b7e0b67b08c96c2f49b77a789787" - integrity sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ== - dependencies: - ansi-styles "^4.0.0" - astral-regex "^2.0.0" - is-fullwidth-code-point "^3.0.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" - -slice-ansi@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-5.0.0.tgz#b73063c57aa96f9cd881654b15294d95d285c42a" - integrity sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ== - dependencies: - ansi-styles "^6.0.0" - is-fullwidth-code-point "^4.0.0" - -snapdragon-node@^2.0.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" - integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== - dependencies: - define-property "^1.0.0" - isobject "^3.0.0" - snapdragon-util "^3.0.1" - -snapdragon-util@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" - integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== - dependencies: - kind-of "^3.2.0" - -snapdragon@^0.8.1: - version "0.8.2" - resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" - integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== - dependencies: - base "^0.11.1" - debug "^2.2.0" - define-property "^0.2.5" - extend-shallow "^2.0.1" - map-cache "^0.2.2" - source-map "^0.5.6" - source-map-resolve "^0.5.0" - use "^3.1.0" - -solc@0.7.3: - version "0.7.3" - resolved "https://registry.yarnpkg.com/solc/-/solc-0.7.3.tgz#04646961bd867a744f63d2b4e3c0701ffdc7d78a" - integrity sha512-GAsWNAjGzIDg7VxzP6mPjdurby3IkGCjQcM8GFYZT6RyaoUZKmMU6Y7YwG+tFGhv7dwZ8rmR4iwFDrrD99JwqA== - dependencies: - command-exists "^1.2.8" - commander "3.0.2" - follow-redirects "^1.12.1" - fs-extra "^0.30.0" - js-sha3 "0.8.0" - memorystream "^0.3.1" - require-from-string "^2.0.0" - semver "^5.5.0" - tmp "0.0.33" - -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" - -solc@^0.6.3: - version "0.6.12" - resolved "https://registry.yarnpkg.com/solc/-/solc-0.6.12.tgz#48ac854e0c729361b22a7483645077f58cba080e" - integrity sha512-Lm0Ql2G9Qc7yPP2Ba+WNmzw2jwsrd3u4PobHYlSOxaut3TtUbj9+5ZrT6f4DUpNPEoBaFUOEg9Op9C0mk7ge9g== - dependencies: - command-exists "^1.2.8" - commander "3.0.2" - fs-extra "^0.30.0" - js-sha3 "0.8.0" - memorystream "^0.3.1" - require-from-string "^2.0.0" - semver "^5.5.0" - tmp "0.0.33" - -solhint@^3.3.6: - version "3.3.7" - resolved "https://registry.yarnpkg.com/solhint/-/solhint-3.3.7.tgz#b5da4fedf7a0fee954cb613b6c55a5a2b0063aa7" - integrity sha512-NjjjVmXI3ehKkb3aNtRJWw55SUVJ8HMKKodwe0HnejA+k0d2kmhw7jvpa+MCTbcEgt8IWSwx0Hu6aCo/iYOZzQ== - dependencies: - "@solidity-parser/parser" "^0.14.1" - 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" - semver "^6.3.0" - optionalDependencies: - prettier "^1.14.3" - -solidity-comments-extractor@^0.0.7: - version "0.0.7" - resolved "https://registry.yarnpkg.com/solidity-comments-extractor/-/solidity-comments-extractor-0.0.7.tgz#99d8f1361438f84019795d928b931f4e5c39ca19" - integrity sha512-wciNMLg/Irp8OKGrh3S2tfvZiZ0NEyILfcRCXCD4mp7SgK/i9gzLfhY2hY7VMCQJ3kH9UB9BzNdibIVMchzyYw== - -solidity-coverage@^0.8.11: - version "0.8.11" - resolved "https://registry.yarnpkg.com/solidity-coverage/-/solidity-coverage-0.8.11.tgz#c95798f2c3e885c49dcfc9c43ee570d112214785" - integrity sha512-yy0Yk+olovBbXn0Me8BWULmmv7A69ZKkP5aTOJGOO8u61Tu2zS989erfjtFlUjDnfWtxRAVkd8BsQD704yLWHw== - dependencies: - "@ethersproject/abi" "^5.0.9" - "@solidity-parser/parser" "^0.18.0" - chalk "^2.4.2" - death "^1.1.0" - difflib "^0.2.4" - fs-extra "^8.1.0" - ghost-testrpc "^0.0.2" - global-modules "^2.0.0" - globby "^10.0.1" - jsonschema "^1.2.4" - lodash "^4.17.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-utils "^1.3.6" - -source-map-resolve@^0.5.0: - version "0.5.3" - resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a" - integrity sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw== - dependencies: - atob "^2.1.2" - decode-uri-component "^0.2.0" - resolve-url "^0.2.1" - source-map-url "^0.4.0" - urix "^0.1.0" - -source-map-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" - -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.13: - version "0.5.21" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" - integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - -source-map-url@^0.4.0: - version "0.4.1" - resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.1.tgz#0af66605a745a5a2f91cf1bbf8a7afbc283dec56" - integrity sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw== - -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" - integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== - -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= - dependencies: - amdefine ">=0.0.4" - -spdx-correct@^3.0.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9" - integrity sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w== - dependencies: - spdx-expression-parse "^3.0.0" - spdx-license-ids "^3.0.0" - -spdx-exceptions@^2.1.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" - integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== - -spdx-expression-parse@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" - integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== - dependencies: - spdx-exceptions "^2.1.0" - spdx-license-ids "^3.0.0" - -spdx-license-ids@^3.0.0: - version "3.0.11" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz#50c0d8c40a14ec1bf449bae69a0ea4685a9d9f95" - integrity sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g== - -split-string@^3.0.1, split-string@^3.0.2: - version "3.1.0" - resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" - integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== - dependencies: - extend-shallow "^3.0.0" - -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= - -squirrelly@8.0.8, squirrelly@^8.0.8: - version "8.0.8" - resolved "https://registry.yarnpkg.com/squirrelly/-/squirrelly-8.0.8.tgz#d6704650b2170b8040d5de5bff9fa69cb62b5e0f" - integrity sha512-7dyZJ9Gw86MmH0dYLiESsjGOTj6KG8IWToTaqBuB6LwPI+hyNb6mbQaZwrfnAQ4cMDnSWMUvX/zAYDLTSWLk/w== - -sshpk@^1.7.0: - 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" - bcrypt-pbkdf "^1.0.0" - dashdash "^1.12.0" - ecc-jsbn "~0.1.1" - getpass "^0.1.1" - jsbn "~0.1.0" - safer-buffer "^2.0.2" - tweetnacl "~0.14.0" - -stacktrace-parser@^0.1.10: - version "0.1.10" - resolved "https://registry.yarnpkg.com/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz#29fb0cae4e0d0b85155879402857a1639eb6051a" - integrity sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg== - dependencies: - type-fest "^0.7.1" - -static-extend@^0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" - integrity sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY= - dependencies: - define-property "^0.2.5" - object-copy "^0.1.0" - -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== - -"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= - -stealthy-require@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" - integrity sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks= - -stream-to-pull-stream@^1.7.1: - version "1.7.3" - resolved "https://registry.yarnpkg.com/stream-to-pull-stream/-/stream-to-pull-stream-1.7.3.tgz#4161aa2d2eb9964de60bfa1af7feaf917e874ece" - integrity sha512-6sNyqJpr5dIOQdgNy/xcDWwDuzAsAwVzhzrWlAPAQ7Lkjx/rv0wgvxEyKwTq6FmNd5rjTrELt/CLmaSw7crMGg== - dependencies: - looper "^3.0.0" - pull-stream "^3.2.3" - -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= - -string-argv@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.1.tgz#95e2fbec0427ae19184935f816d74aaa4c5c19da" - integrity sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg== - -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 sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= - 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@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" - integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== - dependencies: - is-fullwidth-code-point "^2.0.0" - strip-ansi "^4.0.0" - -string-width@^3.0.0, string-width@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" - integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== - dependencies: - emoji-regex "^7.0.1" - is-fullwidth-code-point "^2.0.0" - strip-ansi "^5.1.0" - -string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3: - version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -string-width@^5.0.0: - version "5.1.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" - integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== - dependencies: - eastasianwidth "^0.2.0" - emoji-regex "^9.2.2" - strip-ansi "^7.0.1" - -string.prototype.trim@~1.2.5: - version "1.2.5" - resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.5.tgz#a587bcc8bfad8cb9829a577f5de30dd170c1682c" - integrity sha512-Lnh17webJVsD6ECeovpVN17RlAKjmz4rF9S+8Y45CkMc/ufVpTkU3vZIyIC7sllQ1FCvObZnnCdNs/HXTUOTlg== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.1" - -string.prototype.trimend@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz#e75ae90c2942c63504686c18b287b4a0b1a45f80" - integrity sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - -string.prototype.trimstart@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz#b36399af4ab2999b4c9c648bd7a3fb2bb26feeed" - integrity sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - -string_decoder@^1.1.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" - integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== - dependencies: - safe-buffer "~5.2.0" - -string_decoder@~0.10.x: - version "0.10.31" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" - integrity 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" - integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== - dependencies: - safe-buffer "~5.1.0" - -strip-ansi@^3.0.0, strip-ansi@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" - integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= - 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= - dependencies: - ansi-regex "^3.0.0" - -strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" - integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== - dependencies: - ansi-regex "^4.1.0" - -strip-ansi@^6.0.0, strip-ansi@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - -strip-ansi@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.0.1.tgz#61740a08ce36b61e50e65653f07060d000975fb2" - integrity sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw== - dependencies: - ansi-regex "^6.0.1" - -strip-bom@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" - integrity sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4= - dependencies: - 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-final-newline@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-3.0.0.tgz#52894c313fbff318835280aed60ff71ebf12b8fd" - integrity sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw== - -strip-hex-prefix@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz#0c5f155fef1151373377de9dbb588da05500e36f" - integrity sha1-DF8VX+8RUTczd96du1iNoFUA428= - dependencies: - is-hex-prefixed "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= - -strip-json-comments@3.1.1, strip-json-comments@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" - integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== - -supports-color@6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.0.0.tgz#76cfe742cf1f41bb9b1c29ad03068c05b4c0e40a" - integrity sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg== - dependencies: - has-flag "^3.0.0" - -supports-color@8.1.1: - version "8.1.1" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" - integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== - dependencies: - has-flag "^4.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@^3.1.0: - version "3.2.3" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6" - integrity sha1-ZawFBLOVQXHYpklGsq48u4pfVPY= - dependencies: - has-flag "^1.0.0" - -supports-color@^5.3.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" - integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== - dependencies: - has-flag "^3.0.0" - -supports-color@^7.1.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" - integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== - dependencies: - has-flag "^4.0.0" - -supports-preserve-symlinks-flag@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" - integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== - -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== - dependencies: - bluebird "^3.5.0" - buffer "^5.0.5" - 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 "^1.0.1" - -sync-request@^6.0.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/sync-request/-/sync-request-6.1.0.tgz#e96217565b5e50bbffe179868ba75532fb597e68" - integrity sha512-8fjNkrNlNCrVc/av+Jn+xxqfCjYaBoHqCsDz6mt030UMxJGr+GSfCV1dQt2gRtlL63+VPidwDVLr7V2OcTSdRw== - dependencies: - http-response-object "^3.0.1" - sync-rpc "^1.2.1" - then-request "^6.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" - -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" - -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== - dependencies: - ajv "^6.10.2" - lodash "^4.17.14" - slice-ansi "^2.1.0" - string-width "^3.0.0" - -table@^6.8.0: - 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" - -tape@^4.6.3: - version "4.15.1" - resolved "https://registry.yarnpkg.com/tape/-/tape-4.15.1.tgz#88fb662965a11f9be1bddb04c11662d7eceb129e" - integrity sha512-k7F5pyr91n9D/yjSJwbLLYDCrTWXxMSXbbmHX2n334lSIc2rxeXyFkaBv4UuUd2gBYMrAOalPutAiCxC6q1qbw== - dependencies: - call-bind "~1.0.2" - deep-equal "~1.1.1" - defined "~1.0.0" - dotignore "~0.1.2" - for-each "~0.3.3" - glob "~7.2.0" - has "~1.0.3" - inherits "~2.0.4" - is-regex "~1.1.4" - minimist "~1.2.6" - object-inspect "~1.12.0" - resolve "~1.22.0" - resumer "~0.0.0" - string.prototype.trim "~1.2.5" - through "~2.3.8" - -tar@^4.0.2: - version "4.4.19" - resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.19.tgz#2e4d7263df26f2b914dee10c825ab132123742f3" - integrity sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA== - dependencies: - chownr "^1.1.4" - fs-minipass "^1.2.7" - minipass "^2.9.0" - minizlib "^1.3.3" - mkdirp "^0.5.5" - safe-buffer "^5.2.1" - yallist "^3.1.1" - -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= - dependencies: - array-back "^1.0.3" - typical "^2.6.0" - -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= - -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: - "@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" - -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== - 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: - version "4.0.1" - resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" - integrity sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8= - -tmp-promise@^2.0.2: - version "2.1.1" - resolved "https://registry.yarnpkg.com/tmp-promise/-/tmp-promise-2.1.1.tgz#eb97c038995af74efbfe8156f5e07fdd0c935539" - integrity sha512-Z048AOz/w9b6lCbJUpevIJpRpUztENl8zdv1bmAKVHimfqRFl92ROkmT9rp7TVBnrEw2gtMTol/2Cp2S2kJa4Q== - dependencies: - tmp "0.1.0" - -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" - -tmp@0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.1.0.tgz#ee434a4e22543082e294ba6201dcc6eafefa2877" - integrity sha512-J7Z2K08jbGcdA1kkQpJSqLF6T0tdQqpR2pnSUXsIchbPdTI9v3e85cLW0d6WDhwuAleOV71j2xWs8qMPfK7nKw== - dependencies: - rimraf "^2.6.3" - -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-object-path@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" - integrity sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68= - dependencies: - kind-of "^3.0.2" - -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@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" - integrity sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg= - dependencies: - is-number "^3.0.0" - repeat-string "^1.6.1" - -to-regex-range@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" - integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== - dependencies: - is-number "^7.0.0" - -to-regex@^3.0.1, to-regex@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" - integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== - dependencies: - define-property "^2.0.2" - extend-shallow "^3.0.2" - regex-not "^1.0.2" - safe-regex "^1.1.0" - -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== - -toml@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/toml/-/toml-3.0.0.tgz#342160f1af1904ec9d204d03a5d61222d762c5ee" - integrity sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w== - -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== - dependencies: - psl "^1.1.28" - punycode "^2.1.1" - -tr46@~0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" - integrity sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o= - -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= - -ts-api-utils@^1.0.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.3.0.tgz#4b490e27129f1e8e686b45cc4ab63714dc60eea1" - integrity sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ== - -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@^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-essentials@^7.0.1: - version "7.0.3" - resolved "https://registry.yarnpkg.com/ts-essentials/-/ts-essentials-7.0.3.tgz#686fd155a02133eedcc5362dc8b5056cde3e5a38" - integrity sha512-8+gr5+lqO3G84KdiTSMRLtuyJ+nTBVRKuCrK4lidMPdVeEp0uqC875uE5NMcaA7YYMN7XsNiFQuMvasF8HT/xQ== - -ts-generator@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/ts-generator/-/ts-generator-0.1.1.tgz#af46f2fb88a6db1f9785977e9590e7bcd79220ab" - integrity sha512-N+ahhZxTLYu1HNTQetwWcx3so8hcYbkKBHTr4b4/YgObFTIKkOSSsaa+nal12w8mfrJAyzJfETXawbNjSfP2gQ== - dependencies: - "@types/mkdirp" "^0.5.2" - "@types/prettier" "^2.1.1" - "@types/resolve" "^0.0.8" - chalk "^2.4.1" - glob "^7.1.2" - mkdirp "^0.5.1" - prettier "^2.1.2" - resolve "^1.8.1" - ts-essentials "^1.0.0" - -ts-node@^10.1.0: - version "10.7.0" - resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.7.0.tgz#35d503d0fab3e2baa672a0e94f4b40653c2463f5" - integrity sha512-TbIGS4xgJoX2i3do417KSaep1uRAW/Lu+WAL2doDHC0D6ummjirVOXU5/7aiZotbQ5p1Zp9tP7U6cYhA0O7M8A== - dependencies: - "@cspotcode/source-map-support" "0.7.0" - "@tsconfig/node10" "^1.0.7" - "@tsconfig/node12" "^1.0.7" - "@tsconfig/node14" "^1.0.0" - "@tsconfig/node16" "^1.0.2" - acorn "^8.4.1" - acorn-walk "^8.1.1" - arg "^4.1.0" - create-require "^1.1.0" - diff "^4.0.1" - make-error "^1.1.1" - v8-compile-cache-lib "^3.0.0" - yn "3.1.1" - -tsconfig-paths@^3.14.1: - version "3.14.1" - resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz#ba0734599e8ea36c862798e920bcf163277b137a" - integrity sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ== - dependencies: - "@types/json5" "^0.0.29" - json5 "^1.0.1" - minimist "^1.2.6" - strip-bom "^3.0.0" - -tslib@2.4.0, tslib@^2.1.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" - integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== - -tslib@^1.9.0, tslib@^1.9.3: - version "1.14.1" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" - integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== - -tsort@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/tsort/-/tsort-0.0.1.tgz#e2280f5e817f8bf4275657fd0f9aebd44f5a2786" - integrity sha1-4igPXoF/i/QnVlf9D5rr1E9aJ4Y= - -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= - dependencies: - safe-buffer "^5.0.1" - -tweetnacl-util@^0.15.0, 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= - -tweetnacl@^1.0.0, tweetnacl@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-1.0.3.tgz#ac0af71680458d8a6378d0d0d050ab1407d35596" - integrity sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw== - -type-check@^0.4.0, type-check@~0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" - integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== - dependencies: - prelude-ls "^1.2.1" - -type-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= - dependencies: - prelude-ls "~1.1.2" - -type-detect@^4.0.0, type-detect@^4.0.5: - version "4.0.8" - resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" - integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== - -type-fest@^0.20.2: - version "0.20.2" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" - integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== - -type-fest@^0.21.3: - version "0.21.3" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" - integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== - -type-fest@^0.7.1: - version "0.7.1" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.7.1.tgz#8dda65feaf03ed78f0a3f9678f1869147f7c5c48" - integrity sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg== - -type-is@~1.6.18: - version "1.6.18" - resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" - integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== - dependencies: - media-typer "0.3.0" - mime-types "~2.1.24" - -type@^1.0.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0" - integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg== - -type@^2.5.0: - version "2.6.0" - resolved "https://registry.yarnpkg.com/type/-/type-2.6.0.tgz#3ca6099af5981d36ca86b78442973694278a219f" - integrity sha512-eiDBDOmkih5pMbo9OqsqPRGMljLodLcwd5XD5JbtNB0o89xZAwynY9EdCDsJU7LtcVCClu9DvM7/0Ep1hYX3EQ== - -typechain@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/typechain/-/typechain-3.0.0.tgz#d5a47700831f238e43f7429b987b4bb54849b92e" - integrity sha512-ft4KVmiN3zH4JUFu2WJBrwfHeDf772Tt2d8bssDTo/YcckKW2D+OwFrHXRC6hJvO3mHjFQTihoMV6fJOi0Hngg== - dependencies: - command-line-args "^4.0.7" - debug "^4.1.1" - fs-extra "^7.0.0" - js-sha3 "^0.8.0" - lodash "^4.17.15" - ts-essentials "^6.0.3" - ts-generator "^0.1.1" - -typechain@^8.3.2: - version "8.3.2" - resolved "https://registry.yarnpkg.com/typechain/-/typechain-8.3.2.tgz#1090dd8d9c57b6ef2aed3640a516bdbf01b00d73" - integrity sha512-x/sQYr5w9K7yv3es7jo4KTX05CLxOf7TRWwoHlrjRh8H82G64g+k7VuWPJlgMo6qrjfCulOdfBjiaDtmhFYD/Q== - dependencies: - "@types/prettier" "^2.1.1" - debug "^4.3.1" - fs-extra "^7.0.0" - glob "7.1.7" - js-sha3 "^0.8.0" - lodash "^4.17.15" - mkdirp "^1.0.4" - prettier "^2.3.1" - ts-command-line-args "^2.2.0" - ts-essentials "^7.0.1" - -typedarray-to-buffer@^3.1.5: - version "3.1.5" - resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" - integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== - dependencies: - is-typedarray "^1.0.0" - -typedarray@^0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" - integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= - -typescript@^5.4.2: - version "5.4.2" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.4.2.tgz#0ae9cebcfae970718474fe0da2c090cad6577372" - integrity sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ== - -typewise-core@^1.2, typewise-core@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/typewise-core/-/typewise-core-1.2.0.tgz#97eb91805c7f55d2f941748fa50d315d991ef195" - integrity sha1-l+uRgFx/VdL5QXSPpQ0xXZke8ZU= - -typewise@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/typewise/-/typewise-1.0.3.tgz#1067936540af97937cc5dcf9922486e9fa284651" - integrity sha1-EGeTZUCvl5N8xdz5kiSG6fooRlE= - dependencies: - typewise-core "^1.2.0" - -typewiselite@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/typewiselite/-/typewiselite-1.0.0.tgz#c8882fa1bb1092c06005a97f34ef5c8508e3664e" - integrity sha1-yIgvobsQksBgBal/NO9chQjjZk4= - -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@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/typical/-/typical-4.0.0.tgz#cbeaff3b9d7ae1e2bbfaf5a4e6f11eccfde94fc4" - integrity sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw== - -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.15.4" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.15.4.tgz#fa95c257e88f85614915b906204b9623d4fa340d" - integrity sha512-vMOPGDuvXecPs34V74qDKk4iJ/SN4vL3Ow/23ixafENYvtrNvtbcgUeugTcUGRGsOF/5fU8/NYSL5Hyb3l1OJA== - -ultron@~1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.1.1.tgz#9fe1536a10a664a65266a1e3ccf85fd36302bc9c" - integrity sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og== - -unbox-primitive@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.1.tgz#085e215625ec3162574dc8859abee78a59b14471" - integrity sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw== - dependencies: - function-bind "^1.1.1" - has-bigints "^1.0.1" - has-symbols "^1.0.2" - 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== - -undici-types@~5.26.4: - version "5.26.5" - resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" - integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== - -undici@^5.14.0: - version "5.28.3" - resolved "https://registry.yarnpkg.com/undici/-/undici-5.28.3.tgz#a731e0eff2c3fcfd41c1169a869062be222d1e5b" - integrity sha512-3ItfzbrhDlINjaP0duwnNsKpDQk3acHI3gVJ1z4fmwMK31k5G9OVIAMLSIaP6w4FaGkaAkN6zaQO9LUvZ1t7VA== - dependencies: - "@fastify/busboy" "^2.0.0" - -union-value@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" - integrity sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg== - dependencies: - arr-union "^3.1.0" - get-value "^2.0.6" - is-extendable "^0.1.1" - set-value "^2.0.1" - -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== - -unorm@^1.3.3: - version "1.6.0" - resolved "https://registry.yarnpkg.com/unorm/-/unorm-1.6.0.tgz#029b289661fba714f1a9af439eb51d9b16c205af" - integrity sha512-b2/KCUlYZUeA7JFUuRJZPUtr4gZvBh7tavtv4fvk4+KV9pfGiR6CQAQAWl49ZpR3ts2dk4FYkP7EIgDJoiOLDA== - -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= - -unset-value@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" - integrity sha1-g3aHP30jNRef+x5vw6jtDfyKtVk= - dependencies: - has-value "^0.3.1" - isobject "^3.0.0" - -uri-js@^4.2.2: - version "4.4.1" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" - integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== - dependencies: - punycode "^2.1.0" - -urix@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" - integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= - -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" - -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= - dependencies: - prepend-http "^2.0.0" - -url-set-query@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/url-set-query/-/url-set-query-1.0.0.tgz#016e8cfd7c20ee05cafe7795e892bd0702faa339" - integrity sha1-AW6M/Xwg7gXK/neV6JK9BwL6ozk= - -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= - -url@^0.11.0: - version "0.11.0" - resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" - integrity sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE= - dependencies: - punycode "1.3.2" - querystring "0.2.0" - -use@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" - integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== - -utf-8-validate@^5.0.2: - version "5.0.9" - resolved "https://registry.yarnpkg.com/utf-8-validate/-/utf-8-validate-5.0.9.tgz#ba16a822fbeedff1a58918f2a6a6b36387493ea3" - integrity sha512-Yek7dAy0v3Kl0orwMlvi7TPtiCNrdfHNd7Gcc/pLq4BLXqfAmd0J7OWMizUQnTTJsyjKn02mU7anqwfmUP4J8Q== - dependencies: - node-gyp-build "^4.3.0" - -utf8@3.0.0, utf8@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/utf8/-/utf8-3.0.0.tgz#f052eed1364d696e769ef058b183df88c87f69d1" - integrity sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ== - -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= - -util.promisify@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.1.1.tgz#77832f57ced2c9478174149cae9b96e9918cd54b" - integrity sha512-/s3UsZUrIfa6xDhr7zZhnE9SLQ5RIXyYfiVnMMyMDzOc8WhWN4Nbh36H842OyurKbCDAesZOJaVyvmSl6fhGQw== - dependencies: - call-bind "^1.0.0" - define-properties "^1.1.3" - for-each "^0.3.3" - has-symbols "^1.0.1" - object.getownpropertydescriptors "^2.1.1" - -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= - -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== - -uuid@^3.3.2: - version "3.4.0" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" - integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== - -uuid@^8.3.2: - version "8.3.2" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" - integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== - -v8-compile-cache-lib@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf" - integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg== - -validate-npm-package-license@^3.0.1: - version "3.0.4" - resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" - integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== - dependencies: - spdx-correct "^3.0.0" - spdx-expression-parse "^3.0.0" - -varint@^5.0.0: - version "5.0.2" - resolved "https://registry.yarnpkg.com/varint/-/varint-5.0.2.tgz#5b47f8a947eb668b848e034dcfa87d0ff8a7f7a4" - integrity sha512-lKxKYG6H03yCZUpAGOPOsMcGxd1RHCu1iKvEHYDPmTyq2HueGhD73ssNBqqQWfvYs04G9iUFRvmAVLW20Jw6ow== - -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= - -verror@1.10.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" - integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= - dependencies: - assert-plus "^1.0.0" - core-util-is "1.0.2" - extsprintf "^1.2.0" - -w-json@^1.3.10: - version "1.3.10" - resolved "https://registry.yarnpkg.com/w-json/-/w-json-1.3.10.tgz#ac448a19ca22376e2753a684b52369c7b1e83313" - integrity sha512-XadVyw0xE+oZ5FGApXsdswv96rOhStzKqL53uSe5UaTadABGkWIg1+DTx8kiZ/VqTZTBneoL0l65RcPe4W3ecw== - -wasmbuilder@0.0.10: - version "0.0.10" - resolved "https://registry.yarnpkg.com/wasmbuilder/-/wasmbuilder-0.0.10.tgz#b8298b2095ef9979d32f3881d1feef1705ec868a" - integrity sha512-zQSvZ7d74d9OvN+mCN6ucNne4QS5/cBBYTHldX0Oe+u9gStY21orapvuX1ajisA7RVIpuFhYg+ZgdySsPfeh0A== - dependencies: - big-integer "^1.6.48" - -wasmcurves@0.0.12: - version "0.0.12" - resolved "https://registry.yarnpkg.com/wasmcurves/-/wasmcurves-0.0.12.tgz#1496e2219ac07f9a420f527803ae13b1d7a89246" - integrity sha512-1Jl9mkatyHSNj80ILjf85SZUNuZQBCkTjJlhzqHnZQXUmIimCIWkugaVaYNjozLs1Gun4h/keZe1MBeBN0sRpg== - dependencies: - big-integer "^1.6.42" - blakejs "^1.1.0" - -wasmcurves@0.0.14: - version "0.0.14" - resolved "https://registry.yarnpkg.com/wasmcurves/-/wasmcurves-0.0.14.tgz#cbe0f19650d9554937154afdbed66b305bd2a348" - integrity sha512-G1iMkxlRaQSdqQ1JrwHcU+awLmwyH6kFKfT8g9obd8MWe+u5oSdFXrODB0zmSI5aGGvJPG+4cAmqCGYv9R+7qg== - dependencies: - big-integer "^1.6.42" - blakejs "^1.1.0" - -wasmcurves@0.0.5: - version "0.0.5" - resolved "https://registry.yarnpkg.com/wasmcurves/-/wasmcurves-0.0.5.tgz#d0b58e803c0b1c09c966b7dc0fad6dd405d18547" - integrity sha512-BmI4GXLjLawGg2YkvHa8zRsnWec+d1uwoxE+Iov8cqOpDL7GA5XO2pk2yuDbXHMzwIug2exnKot3baRZ86R0pA== - dependencies: - big-integer "^1.6.42" - blakejs "^1.1.0" - -web-worker@^1.0.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/web-worker/-/web-worker-1.2.0.tgz#5d85a04a7fbc1e7db58f66595d7a3ac7c9c180da" - integrity sha512-PgF341avzqyx60neE9DD+XS26MMNMoUQRz9NOZwW32nPQrF6p77f1htcnjBSEV8BGMKZ16choqUG4hyI0Hx7mA== - -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== - dependencies: - "@types/node" "^12.12.6" - got "9.6.0" - swarm-js "^0.1.40" - underscore "1.9.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-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-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== - dependencies: - eventemitter3 "4.0.4" - -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-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== - dependencies: - eventemitter3 "4.0.4" - underscore "1.9.1" - web3-core-helpers "1.2.11" - -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== - dependencies: - "@types/bn.js" "^4.11.5" - "@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-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== - dependencies: - "@ethersproject/abi" "5.0.0-beta.153" - underscore "1.9.1" - web3-utils "1.2.11" - -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" - eth-lib "0.2.8" - ethereumjs-common "^1.3.2" - ethereumjs-tx "^2.1.1" - 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-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-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== - 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-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-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== - 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@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-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-provider-engine@14.2.1: - version "14.2.1" - resolved "https://registry.yarnpkg.com/web3-provider-engine/-/web3-provider-engine-14.2.1.tgz#ef351578797bf170e08d529cb5b02f8751329b95" - integrity sha512-iSv31h2qXkr9vrL6UZDm4leZMc32SjWJFGOp/D92JXfcEboCqraZyuExDkpxKw8ziTufXieNM7LSXNHzszYdJw== - dependencies: - async "^2.5.0" - backoff "^2.5.0" - clone "^2.0.0" - cross-fetch "^2.1.0" - eth-block-tracker "^3.0.0" - eth-json-rpc-infura "^3.1.0" - eth-sig-util "^1.4.2" - 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" - -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-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== - dependencies: - oboe "2.1.4" - underscore "1.9.1" - web3-core-helpers "1.2.11" - -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== - dependencies: - eventemitter3 "4.0.4" - underscore "1.9.1" - web3-core-helpers "1.2.11" - websocket "^1.0.31" - -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== - dependencies: - web3-core "1.2.11" - web3-core-method "1.2.11" - web3-core-subscriptions "1.2.11" - web3-net "1.2.11" - -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== - dependencies: - bn.js "^4.11.9" - eth-lib "0.2.8" - 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-utils@^1.0.0-beta.31, web3-utils@^1.3.0: - version "1.7.3" - resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.7.3.tgz#b214d05f124530d8694ad364509ac454d05f207c" - integrity sha512-g6nQgvb/bUpVUIxJE+ezVN+rYwYmlFyMvMIRSuqpi1dk6ApDD00YNArrk7sPcZnjvxOJ76813Xs2vIN2rgh4lg== - dependencies: - bn.js "^4.11.9" - ethereum-bloom-filters "^1.0.6" - ethereumjs-util "^7.1.0" - ethjs-unit "0.1.6" - number-to-bn "1.7.0" - randombytes "^2.1.0" - utf8 "3.0.0" - -web3-utils@^1.3.6: - version "1.10.4" - resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.10.4.tgz#0daee7d6841641655d8b3726baf33b08eda1cbec" - integrity sha512-tsu8FiKJLk2PzhDl9fXbGUWTkkVXYhtTA+SmEFkKft+9BgwLxfCRpU96sWv7ICC8zixBNd3JURVoiR3dUXgP8A== - dependencies: - "@ethereumjs/util" "^8.1.0" - bn.js "^5.2.1" - ethereum-bloom-filters "^1.0.6" - ethereum-cryptography "^2.1.2" - ethjs-unit "0.1.6" - number-to-bn "1.7.0" - randombytes "^2.1.0" - utf8 "3.0.0" - -web3@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" - -webidl-conversions@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" - integrity sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE= - -websocket@1.0.32: - version "1.0.32" - resolved "https://registry.yarnpkg.com/websocket/-/websocket-1.0.32.tgz#1f16ddab3a21a2d929dec1687ab21cfdc6d3dbb1" - integrity sha512-i4yhcllSP4wrpoPMU2N0TQ/q0O94LRG/eUQjEAamRltjQ1oT1PFFKOG4i877OlJgCG8rw6LrrowJp+TYCEWF7Q== - dependencies: - bufferutil "^4.0.1" - debug "^2.2.0" - es5-ext "^0.10.50" - typedarray-to-buffer "^3.1.5" - utf-8-validate "^5.0.2" - yaeti "^0.0.6" - -websocket@^1.0.31: - version "1.0.34" - resolved "https://registry.yarnpkg.com/websocket/-/websocket-1.0.34.tgz#2bdc2602c08bf2c82253b730655c0ef7dcab3111" - integrity sha512-PRDso2sGwF6kM75QykIesBijKSVceR6jL2G8NGYyq2XrItNC2P5/qL5XeR056GhA+Ly7JMFvJb9I312mJfmqnQ== - dependencies: - bufferutil "^4.0.1" - debug "^2.2.0" - es5-ext "^0.10.50" - typedarray-to-buffer "^3.1.5" - utf-8-validate "^5.0.2" - yaeti "^0.0.6" - -whatwg-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== - -whatwg-url@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" - integrity sha1-lmRU6HZUYuN2RNNib2dCzotwll0= - dependencies: - tr46 "~0.0.3" - webidl-conversions "^3.0.0" - -which-boxed-primitive@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" - integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== - dependencies: - is-bigint "^1.0.1" - is-boolean-object "^1.1.0" - is-number-object "^1.0.4" - is-string "^1.0.5" - is-symbol "^1.0.3" - -which-module@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f" - integrity sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8= - -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= - -which@1.3.1, which@^1.1.1, which@^1.2.9, which@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" - integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== - dependencies: - isexe "^2.0.0" - -which@2.0.2, which@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" - integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== - dependencies: - isexe "^2.0.0" - -wide-align@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" - integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== - dependencies: - string-width "^1.0.2 || 2" - -widest-line@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-3.1.0.tgz#8292333bbf66cb45ff0de1603b136b7ae1496eca" - integrity sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg== - dependencies: - string-width "^4.0.0" - -window-size@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.2.0.tgz#b4315bb4214a3d7058ebeee892e13fa24d98b075" - integrity sha1-tDFbtCFKPXBY6+7okuE/ok2YsHU= - -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: - version "1.0.0" - resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" - integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= - -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" - -worker-threads@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/worker-threads/-/worker-threads-1.0.0.tgz#2b49ea7c9692ba737d9148f2c9b2be65e14e3470" - integrity sha512-vK6Hhvph8oLxocEJIlc3YfGAZhm210uGzjZsXSu+JYLAQ/s/w4Tqgl60JrdH58hW8NSGP4m3bp8a92qPXgX05w== - -workerpool@6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.1.0.tgz#a8e038b4c94569596852de7a8ea4228eefdeb37b" - integrity sha512-toV7q9rWNYha963Pl/qyeZ6wG+3nnsyvolaNUS8+R5Wtw6qJPTxIlOP1ZSvcGhEJw+l3HMMmtiNo9Gl61G4GVg== - -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 sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU= - dependencies: - string-width "^1.0.1" - strip-ansi "^3.0.1" - -wrap-ansi@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09" - integrity sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q== - dependencies: - ansi-styles "^3.2.0" - string-width "^3.0.0" - strip-ansi "^5.0.0" - -wrap-ansi@^6.2.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" - integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.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= - -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" - resolved "https://registry.yarnpkg.com/ws/-/ws-3.3.3.tgz#f1cf84fe2d5e901ebce94efaece785f187a228f2" - integrity sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA== - dependencies: - async-limiter "~1.0.0" - safe-buffer "~5.1.0" - ultron "~1.1.0" - -ws@^5.1.1: - version "5.2.3" - resolved "https://registry.yarnpkg.com/ws/-/ws-5.2.3.tgz#05541053414921bc29c63bee14b8b0dd50b07b3d" - integrity sha512-jZArVERrMsKUatIdnLzqvcfydI85dvd/Fp1u/VOpfdDWQ4c9qWXe+VIeAbQ5FrDwciAkr+lzofXLz3Kuf26AOA== - dependencies: - async-limiter "~1.0.0" - -ws@^7.4.6: - version "7.5.7" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.7.tgz#9e0ac77ee50af70d58326ecff7e85eb3fa375e67" - integrity sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A== - -xhr-request-promise@^0.1.2: - version "0.1.3" - resolved "https://registry.yarnpkg.com/xhr-request-promise/-/xhr-request-promise-0.1.3.tgz#2d5f4b16d8c6c893be97f1a62b0ed4cf3ca5f96c" - integrity sha512-YUBytBsuwgitWtdRzXDDkWAXzhdGB8bYm0sSzMPZT7Z2MBjMSTHFsyCT1yCRATY+XC69DUrQraRAEgcoCRaIPg== - dependencies: - xhr-request "^1.1.0" - -xhr-request@^1.0.1, xhr-request@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/xhr-request/-/xhr-request-1.1.0.tgz#f4a7c1868b9f198723444d82dcae317643f2e2ed" - integrity sha512-Y7qzEaR3FDtL3fP30k9wO/e+FBnBByZeybKOhASsGP30NIkRAAkKD/sCnLvgEfAIEC1rcmK7YG8f4oEnIrrWzA== - dependencies: - buffer-to-arraybuffer "^0.0.5" - object-assign "^4.1.1" - query-string "^5.0.1" - simple-get "^2.7.0" - timed-out "^4.0.1" - url-set-query "^1.0.0" - xhr "^2.0.4" - -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.6.0" - resolved "https://registry.yarnpkg.com/xhr/-/xhr-2.6.0.tgz#b69d4395e792b4173d6b7df077f0fc5e4e2b249d" - integrity sha512-/eCGLb5rxjx5e3mF1A7s+pLlR6CGyqWN91fv1JgER5mVWg1MZmlhBvy9kjcsOdRk8RrIujotWyJamfyrp+WIcA== - dependencies: - global "~4.4.0" - is-function "^1.0.1" - parse-headers "^2.0.0" - xtend "^4.0.0" - -xmlhttprequest@1.8.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz#67fe075c5c24fef39f9d65f5f7b7fe75171968fc" - integrity sha1-Z/4HXFwk/vOfnWX197f+dRcZaPw= - -xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.0, xtend@~4.0.1: - 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.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= - -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== - -yallist@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" - integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== - -yaml@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.1.1.tgz#1e06fb4ca46e60d9da07e4f786ea370ed3c3cfec" - integrity sha512-o96x3OPo8GjWeSLF+wOAbrPfhFOGY0W00GNaxCDv+9hkcDJEnev1yh8S7pgHF0ik6zc8sQLuL8hjHjJULZp8bw== - -yargs-parser@13.1.2, yargs-parser@^13.1.2: - version "13.1.2" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.2.tgz#130f09702ebaeef2650d54ce6e3e5706f7a4fb38" - integrity sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg== - dependencies: - camelcase "^5.0.0" - decamelize "^1.2.0" - -yargs-parser@20.2.4: - version "20.2.4" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" - integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== - -yargs-parser@^18.1.2: - version "18.1.3" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.3.tgz#be68c4975c6b2abf469236b0c870362fab09a7b0" - integrity sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ== - dependencies: - camelcase "^5.0.0" - decamelize "^1.2.0" - -yargs-parser@^2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-2.4.1.tgz#85568de3cf150ff49fa51825f03a8c880ddcc5c4" - integrity sha1-hVaN488VD/SfpRgl8DqMiA3cxcQ= - dependencies: - camelcase "^3.0.0" - lodash.assign "^4.0.6" - -yargs-parser@^20.2.2: - version "20.2.9" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" - integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== - -yargs-unparser@1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-1.6.0.tgz#ef25c2c769ff6bd09e4b0f9d7c605fb27846ea9f" - integrity sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw== - dependencies: - flat "^4.1.0" - lodash "^4.17.15" - yargs "^13.3.0" - -yargs-unparser@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb" - integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== - dependencies: - camelcase "^6.0.0" - decamelize "^4.0.0" - flat "^5.0.2" - is-plain-obj "^2.1.0" - -yargs@13.3.2, yargs@^13.3.0: - version "13.3.2" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.2.tgz#ad7ffefec1aa59565ac915f82dccb38a9c31a2dd" - integrity sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw== - dependencies: - cliui "^5.0.0" - find-up "^3.0.0" - get-caller-file "^2.0.1" - require-directory "^2.1.1" - require-main-filename "^2.0.0" - set-blocking "^2.0.0" - string-width "^3.0.0" - which-module "^2.0.0" - y18n "^4.0.0" - yargs-parser "^13.1.2" - -yargs@16.2.0: - version "16.2.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" - integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== - dependencies: - cliui "^7.0.2" - escalade "^3.1.1" - get-caller-file "^2.0.5" - require-directory "^2.1.1" - string-width "^4.2.0" - y18n "^5.0.5" - yargs-parser "^20.2.2" - -yargs@^15.3.1: - version "15.4.1" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.4.1.tgz#0d87a16de01aee9d8bec2bfbf74f67851730f4f8" - integrity sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A== - dependencies: - cliui "^6.0.0" - decamelize "^1.2.0" - find-up "^4.1.0" - get-caller-file "^2.0.1" - require-directory "^2.1.1" - require-main-filename "^2.0.0" - set-blocking "^2.0.0" - string-width "^4.2.0" - which-module "^2.0.0" - y18n "^4.0.0" - yargs-parser "^18.1.2" - -yargs@^4.7.1: - version "4.8.1" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-4.8.1.tgz#c0c42924ca4aaa6b0e6da1739dfb216439f9ddc0" - integrity sha1-wMQpJMpKqmsObaFznfshZDn53cA= - 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== diff --git a/l2geth b/l2geth deleted file mode 160000 index 246955a4d..000000000 --- a/l2geth +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 246955a4df944afb48dcbb0d02343e4baf58126b diff --git a/rollup/Makefile b/rollup/Makefile index c1287b727..05e5397e7 100644 --- a/rollup/Makefile +++ b/rollup/Makefile @@ -4,6 +4,7 @@ IMAGE_VERSION=latest REPO_ROOT_DIR=./.. mock_abi: + git submodule update --init --recursive cd .. && solc --evm-version cancun --bin --abi --optimize --overwrite -o ./build/bin ./rollup/mock_bridge/MockBridge.sol cd .. && go run github.com/scroll-tech/go-ethereum/cmd/abigen --bin=./build/bin/MockBridge.bin --abi=./build/bin/MockBridge.abi --pkg=mock_bridge --out=./rollup/mock_bridge/MockBridge.go diff --git a/rollup/abi/build_abi.sh b/rollup/abi/build_abi.sh index 217c707d0..4a18deca8 100755 --- a/rollup/abi/build_abi.sh +++ b/rollup/abi/build_abi.sh @@ -24,7 +24,7 @@ gen_name=("L1GatewayRouter" "L2GatewayRouter" "L1ScrollMessenger" "L2ScrollMesse for i in "${!abi_name[@]}"; do mkdir -p tmp abi="tmp/${abi_name[$i]}.json" - cat ../contracts/artifacts/src/${abi_name[$i]}.sol/${abi_name[$i]}.json | jq '.abi' > $abi + cat ../scroll-contracts/artifacts/src/${abi_name[$i]}.sol/${abi_name[$i]}.json | jq '.abi' > $abi pkg="${pkg_name[$i]}_abi" out="contracts/${pkg}/${gen_name[$i]}.go" echo "generating ${out} from ${abi}" diff --git a/rollup/mock_bridge/MockBridge.sol b/rollup/mock_bridge/MockBridge.sol index 5b7ec5cf6..f9dc85201 100644 --- a/rollup/mock_bridge/MockBridge.sol +++ b/rollup/mock_bridge/MockBridge.sol @@ -1,10 +1,10 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.24; -import {BatchHeaderV0Codec} from "../../../contracts/src/libraries/codec/BatchHeaderV0Codec.sol"; -import {BatchHeaderV1Codec} from "../../../contracts/src/libraries/codec/BatchHeaderV1Codec.sol"; -import {ChunkCodecV0} from "../../../contracts/src/libraries/codec/ChunkCodecV0.sol"; -import {ChunkCodecV1} from "../../../contracts/src/libraries/codec/ChunkCodecV1.sol"; +import {BatchHeaderV0Codec} from "../../../scroll-contracts/src/libraries/codec/BatchHeaderV0Codec.sol"; +import {BatchHeaderV1Codec} from "../../../scroll-contracts/src/libraries/codec/BatchHeaderV1Codec.sol"; +import {ChunkCodecV0} from "../../../scroll-contracts/src/libraries/codec/ChunkCodecV0.sol"; +import {ChunkCodecV1} from "../../../scroll-contracts/src/libraries/codec/ChunkCodecV1.sol"; contract MockBridge { /// @dev Thrown when committing a committed batch. diff --git a/scroll-contracts b/scroll-contracts new file mode 160000 index 000000000..ca7f0768b --- /dev/null +++ b/scroll-contracts @@ -0,0 +1 @@ +Subproject commit ca7f0768b6640dc10b19f3d4da3943a87bdf11b1