├── .env.example ├── .gitattributes ├── .github ├── ISSUE_TEMPLATE │ ├── bug.md │ └── feature.md ├── pull_request_template.md └── workflows │ └── ci.yml ├── .gitignore ├── .gitmodules ├── .solhint.json ├── .vscode └── settings.json ├── CHANGELOG.md ├── LICENSE ├── Makefile ├── README.md ├── foundry.toml ├── package.json ├── remappings.txt ├── src ├── MockProvider.sol ├── MockProvider.t.sol └── test │ └── utils │ ├── Caller.sol │ ├── Hevm.sol │ └── tokens │ ├── TokenERC20.sol │ └── TokenERC721.sol └── yarn.lock /.env.example: -------------------------------------------------------------------------------- 1 | export ALCHEMY_API_KEY=YOUR_API_KEY 2 | export ETH_FROM=YOUR_DEFAULT_SENDER_ACCOUNT 3 | export RPC_ON=no 4 | export ETH_NODE=http://eth-node:8545 5 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | .dapprc linguist-language=Shell 2 | *.sol linguist-language=Solidity 3 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 🐜 Bug report 3 | about: If something isn't working 🔧 4 | title: "[BUG NAME]" 5 | labels: bug, help wanted 6 | --- 7 | 8 | **What is the expected behavior?** 9 | 10 | **What is the actual behavior?** 11 | 12 | **Please provide a proof of concept that demonstrates the bug.** 13 | 14 | **Other notes on how to reproduce the issue?** 15 | 16 | **Any possible solutions?** 17 | 18 | **Can you identify the location in the source code where the problem exists?** 19 | 20 | **If the bug is confirmed, would you be willing to submit a PR?** 21 | 22 | Yes / No _(Help can be provided if you need assistance submitting a PR)_ -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 🚀 Feature request 3 | about: If you have a feature request 💡 4 | title: "[FEATURE NAME]" 5 | labels: enhancement, help wanted 6 | --- 7 | 8 | **Context** 9 | 10 | 11 | 12 | **Details** 13 | 14 | 15 | 16 | **Alternatives** 17 | 18 | 19 | 20 | **Has the feature been requested before?** 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | ### Description 2 | 3 | 10 | 11 | ### Issues 12 | 13 | 16 | 17 | - Closes #ISSUE 18 | 19 | ### Todo 20 | 21 | - [ ] Link issues 22 | - [ ] Link projects 23 | - [ ] Update tests 24 | - [ ] Update code 25 | - [ ] Comment code 26 | - [ ] Test locally 27 | - [ ] Update changelog 28 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: Tests 2 | 3 | on: 4 | - push 5 | - pull_request 6 | 7 | jobs: 8 | tests: 9 | runs-on: ubuntu-latest 10 | 11 | steps: 12 | - name: Install Foundry 13 | uses: onbjerg/foundry-toolchain@v1.0.6 14 | with: 15 | version: nightly 16 | 17 | - name: Install node 18 | uses: actions/setup-node@v2 19 | 20 | - name: Clone repo with submodules 21 | uses: actions/checkout@v2 22 | with: 23 | submodules: recursive 24 | 25 | - name: Install yarn 26 | run: npm i -g yarn 27 | 28 | - name: Install dependencies 29 | run: make 30 | 31 | - name: Show Foundry config 32 | run: forge config 33 | 34 | - name: Check contracts are linted 35 | run: yarn lint:check 36 | 37 | - name: Run tests 38 | run: make test 39 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Environment variables 2 | .env 3 | 4 | # MacOS 5 | .DS_Store 6 | 7 | # Node 8 | node_modules 9 | 10 | # Dapptools 11 | out/ 12 | 13 | # Foundry 14 | cache/ 15 | 16 | # VSCode 17 | .vscode/ -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "lib/openzeppelin-contracts"] 2 | path = lib/openzeppelin-contracts 3 | url = https://github.com/OpenZeppelin/openzeppelin-contracts 4 | ignore = dirty 5 | [submodule "lib/ds-test"] 6 | path = lib/ds-test 7 | url = https://github.com/dapphub/ds-test 8 | [submodule "lib/forge-std"] 9 | path = lib/forge-std 10 | url = https://github.com/foundry-rs/forge-std 11 | -------------------------------------------------------------------------------- /.solhint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "solhint:recommended", 3 | "plugins": ["prettier"], 4 | "rules": { 5 | "code-complexity": ["error", 8], 6 | "compiler-version": ["error", ">=0.5.8"], 7 | "const-name-snakecase": "off", 8 | "constructor-syntax": "error", 9 | "func-visibility": ["error", { "ignoreConstructors": true }], 10 | "max-line-length": ["error", 140], 11 | "not-rely-on-time": "off", 12 | "prettier/prettier": [ 13 | "error", 14 | { 15 | "endOfLine": "auto" 16 | } 17 | ], 18 | "reason-string": ["warn", { "maxLength": 64 }] 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "makefile.extensionOutputFolder": "./.vscode" 3 | } -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | All notable changes to this project will be documented in this file. 3 | 4 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), 5 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 6 | 7 | ## Unreleased 8 | 9 | ### Added 10 | 11 | - Methods to consume all gas for a given query or function selector: `givenSelectorConsumeGas(bytes4 selector_)` and `givenQueryConsumeGas(bytes memory query_)` 12 | - Add methods to enable/disable global logging: `disableLogging` / `enableLogging`; mock provider is initialized to log arbitrary requests. 13 | 14 | ### Changed 15 | - Update config file to new Foundry version [#12](https://github.com/cleanunicorn/mockprovider/issues/12) 16 | 17 | ### Removed 18 | 19 | 20 | ## [2.0.0] - 2022-05-01 21 | 22 | ### Added 23 | 24 | - Comments for all code 25 | - `setDefault(bytes memory response_)` method to define a default response for arbitrary requests 26 | - `givenQueryReturn(bytes memory query_, bytes memory response_)` method to define a response for a specified query 27 | - `givenSelectorReturn(bytes4 selector_, bytes memory response_)` method to define a response for a specified selector (`msg.sig`) 28 | - More tests 29 | 30 | ### Changed 31 | 32 | - README.md to describe the current state of your project 33 | - `lib/ds-test` to `2c7dbcc8586b33f358e3307a443e524490c17666` 34 | - `getCallData(uint256 index_)` returns an error `MockProvider__getCallData_indexOutOfBounds(uint256 index)` if an out of bounds `index_` is provided; previously it was returning an empty response 35 | 36 | ## [1.0.0] - 2022-03-28 37 | 38 | ### Added 39 | 40 | - `getCallData` to return logged requests 41 | - `givenQueryReturnResponse` to make the provider return a specific response for a request 42 | - `setDefaultResponse` to make the provider return a default response for any request 43 | - Issue templates for feature and bug requests 44 | - `givenSelectorReturnResponse` to make the provider return a specific response for a request, without taking into consideration any given parameters. i.e., You can specify to return `42` for any call to `balanceOf(address who)` without having to specify the `who` parameter; it will return `42` for all calls to `balanceOf(address who)` 45 | 46 | ### Changed 47 | 48 | - Upgrade [`cachix/install-nix-action`](https://github.com/cachix/install-nix-action) from `v13` to `v16` 49 | - Downgrade Solidity test version from `0.8.10` to `0.8.7` since it cannot find `0.8.10` 50 | - Migrate repo to work with foundry instead of dapptools 51 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # include .env file and export its env vars 2 | # (-include to ignore error if it does not exist) 3 | -include .env 4 | 5 | # Update dependencies 6 | setup :; make update-libs ; make install-deps 7 | update-libs :; git submodule update --init --recursive 8 | install-deps :; yarn install 9 | 10 | # Build & test & deploy 11 | build :; forge build 12 | xclean :; forge clean 13 | lint :; yarn run lint 14 | test :; forge test 15 | test-gasreport :; forge test --gas-report 16 | # test-fork :; forge test --gas-report --fork-url ${ETH_NODE} 17 | watch :; forge test --watch src/ -vv 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MockProvider 2 | 3 | A library for mocking Solidity contracts. 4 | 5 | Instead of importing heavy contracts and making sure the setup is complete and correct, you might only need a library to return a value. This library is designed to be used in tests and return values for the contracts you are testing. 6 | 7 | ## Installation 8 | 9 | ### Dapptools project 10 | 11 | In your dapptools project folder, run: 12 | 13 | ```sh 14 | $ dapp install https://github.com/cleanunicorn/mockprovider 15 | ``` 16 | 17 | It will create a new folder in `lib` named `mockprovider`. 18 | 19 | 20 | ## Usage 21 | 22 | `MockProvider` is created to be used in Solidity based tests. In your test, you can create a `MockProvider` instance and pass it to your contract. Your contract will then be able to call the `MockProvider` instance and use its returned value. 23 | 24 | ### Return default response for any request 25 | 26 | ```solidity 27 | MockProvider provider = new MockProvider(); 28 | 29 | // Make the provider successfully respond with 42 for any request 30 | provider.setDefault( 31 | abi.encode(uint256(42) 32 | ); 33 | ``` 34 | 35 | It will respond with 42 for any request. 36 | 37 | For example you could do a low level call to the contract and decode the expected answer. 38 | 39 | ```solidity 40 | // Do a low level call and check the response 41 | (bool success, bytes memory response) = address(provider).call( 42 | "0xdeadbeef" 43 | ); 44 | 45 | assertTrue(success, "Expected success"); 46 | 47 | (uint256 result) = abi.decode(response, (uint256)); 48 | assertEq(result, 42, "Expected 42"); 49 | ``` 50 | 51 | Alternatively, and most commonly, you will mock a contract's method that needs to return a value. 52 | 53 | Considering you have this contract you need to mock: 54 | 55 | ```solidity 56 | interface ITheAnswer { 57 | function theUltimateQuestionOfLifeTheUniverseAndEverything() external returns (uint); 58 | } 59 | ``` 60 | 61 | You can just call the method, once the provider was set to return a response: 62 | 63 | ```solidity 64 | // Cast the contract as `ITheAnswer` to easily call `.theUltimateQuestionOfLifeTheUniverseAndEverything()` 65 | ITheAnswer theAnswer = ITheAnswer(address(provider)); 66 | 67 | // Mock the answer to everything 68 | provider.setDefault( 69 | abi.encode(uint256(42) 70 | ); 71 | 72 | // Make the call 73 | uint256 theUltimateAnswer = theAnswer.theUltimateQuestionOfLifeTheUniverseAndEverything(); 74 | 75 | // Check the answer 76 | assertEq(theUltimateAnswer, 42, "Expected 42"); 77 | ``` 78 | 79 | ### Return specific response for specific request 80 | 81 | You can set different responses for different requests with `givenQueryReturn`. 82 | 83 | Consider you want to mock this interface 84 | 85 | ```solidity 86 | interface IOddEven { 87 | function isEven(uint256 x) external pure returns (bool); 88 | function isOdd(uint256 x) external pure returns (bool); 89 | function getOdd() external pure returns (uint256); 90 | function getEven() external pure returns (uint256); 91 | function expensiveFunction() external; 92 | } 93 | ``` 94 | 95 | You need to initialize your provider 96 | 97 | ```solidity 98 | provider = new MockProvider(); 99 | ``` 100 | 101 | You can make the provider return the number `1` when `getOdd` is called: 102 | 103 | ```solidity 104 | // Make it return 1 when calling .getOdd() 105 | provider.givenQueryReturn( 106 | // Respond to `.getOdd()` 107 | abi.encodePacked(IOddEven.getOdd.selector), 108 | // With `true` 109 | abi.encodePacked(uint256(1)) 110 | ); 111 | ``` 112 | 113 | And return the number `2` when `getEven` is called: 114 | 115 | ```solidity 116 | // Make it return 2 when calling .getEven() 117 | provider.givenQueryReturn( 118 | // Respond to `.getEven()` 119 | abi.encodePacked(IOddEven.getEven.selector), 120 | // With `2` 121 | abi.encodePacked(uint256(2)) 122 | ); 123 | ``` 124 | 125 | You could check the responses to be correct in your tests: 126 | 127 | ```solidity 128 | // Cast the mock provider as IOddEven to get easy access to 129 | // the methods `getOdd()` and `getEven()` 130 | IOddEven mockOddEven = IOddEven(address(provider)); 131 | 132 | // Check if it returns odd and even numbers 133 | uint256 oddNumber = mockOddEven.getOdd(); 134 | assertTrue(oddNumber % 2 == 1, "Expected odd number"); 135 | uint256 evenNumber = mockOddEven.getEven(); 136 | assertTrue(evenNumber % 2 == 0, "Expected even number"); 137 | ``` 138 | 139 | ### Return specific response for a given function selector 140 | 141 | You can set different responses for different selectors with `givenSelectorReturnResponse`. 142 | 143 | Mocking the same interface as the previous example 144 | 145 | You can make the provider return the `false` whenever `isEven` is called: 146 | 147 | ```solidity 148 | // Make it return false whenever calling .isEven(anything) 149 | provider.givenSelectorReturnResponse( 150 | // Respond to `.isEven()` 151 | abi.encodePacked(IOddEven.isEven.selector), 152 | // Encode the response 153 | MockProvider.ReturnData({ 154 | success: true, 155 | data: abi.encodePacked(bool(false)) 156 | }), 157 | // Log the event 158 | false 159 | ); 160 | ``` 161 | 162 | Setting `givenSelectorReturnResponse` will make the provider return `false` for any call to `isEven`, without the need to specify *all* the numbers. 163 | 164 | ```solidity 165 | provider.isEven(1) == false 166 | provider.isEven(42) == false 167 | ``` 168 | 169 | ### Consume all gas for a given query or function selector 170 | 171 | You can ask the mock provider to consume all the forwarded gas with `givenSelectorConsumeGas` or `givenQueryConsumeGas`. 172 | 173 | ```solidity 174 | // Make it consume all the provided gas when calling .expensiveFunction() 175 | provider.givenSelectorConsumeGas( 176 | // Respond to `.expensiveFunction()` 177 | IOddEven.expensiveFunction.selector, 178 | ); 179 | ``` 180 | 181 | Setting `givenSelectorConsumeGas` or `givenQueryConsumeGas` will make the calls to `expensiveFunction` fail and consume all the gas. 182 | 183 | ### Logging requests 184 | 185 | When using `givenQueryReturnResponse` or `givenSelectorReturnResponse` you can also log the requests. The 3rd parameter is a boolean that indicates if the request should be logged. 186 | 187 | Let's assume you want to test a contract that makes a call into an external contract. The external contract could be a smart contract that you do not develop, or one that already exists on the blockchain, or even a contract that you develop but needs a complex deployment system. Thus, you want that contract to be mocked and you need to know if it was called. 188 | 189 | ## Testing 190 | 191 | ```sh 192 | make test 193 | ``` 194 | -------------------------------------------------------------------------------- /foundry.toml: -------------------------------------------------------------------------------- 1 | # Full reference 2 | # https://onbjerg.github.io/foundry-book/reference/config.html 3 | 4 | [profile.default] 5 | solc_version = "0.8.14" 6 | optimizer = true 7 | optimizer_runs = 20000 8 | gas_reports = ["*"] 9 | 10 | [profile.ci] 11 | verbosity = 4 12 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "magnus", 3 | "author": "Daniel Luca (@CleanUnicorn)", 4 | "license": "Apache-2.0", 5 | "version": "1.0.0", 6 | "description": "Sweeper contracts", 7 | "files": [ 8 | "*.sol" 9 | ], 10 | "devDependencies": { 11 | "copyfiles": "^2.4.1", 12 | "prettier": "^2.4.1", 13 | "prettier-plugin-solidity": "^1.0.0-beta.18", 14 | "rimraf": "^3.0.2", 15 | "solhint": "^3.3.6", 16 | "solhint-plugin-prettier": "^0.0.5" 17 | }, 18 | "scripts": { 19 | "lint": "yarn prettier && yarn solhint", 20 | "lint:check": "yarn prettier:check && yarn solhint:check", 21 | "prettier": "yarn prettier:check --write", 22 | "prettier:check": "prettier --check \"src/**/*.sol\"", 23 | "solhint": "yarn solhint:check --fix", 24 | "solhint:check": "solhint --config ./.solhint.json \"src/**/*.sol\"" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /remappings.txt: -------------------------------------------------------------------------------- 1 | @openzeppelin/=lib/openzeppelin-contracts/ 2 | ds-test/=lib/ds-test/src/ 3 | -------------------------------------------------------------------------------- /src/MockProvider.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | pragma solidity ^0.8.0; 3 | 4 | import "forge-std/Test.sol"; 5 | 6 | /// @title Mocking contract for testing 7 | /// @notice You can use this contract to mock functionality in your tests 8 | /// @dev All function calls are currently implemented without side effects 9 | contract MockProvider is Test { 10 | /// @notice Emitted when an out of bounds calldata is received 11 | error MockProvider__getCallData_indexOutOfBounds(uint256 index); 12 | 13 | /// @notice Structure that logs calls to the provider 14 | struct CallData { 15 | // Who made the call 16 | address caller; 17 | // What function was called 18 | bytes4 functionSelector; 19 | // Contains called function and arguments 20 | bytes data; 21 | // How much ether was sent in the call 22 | uint256 value; 23 | } 24 | 25 | /// @notice State variable that contains logged calls to the provider 26 | CallData[] internal _callData; 27 | 28 | /// @notice Structure that defines the return data for a given call 29 | struct ReturnData { 30 | // Whether the call should be successful 31 | bool success; 32 | // The data to return 33 | // If the call is unsuccessful, this is the reason for failure 34 | bytes data; 35 | } 36 | 37 | /// @dev Define fallback response for all calls. 38 | ReturnData internal _defaultReturnData; 39 | 40 | /// @notice Contains the mapping from the expected query to the return data 41 | /// @dev keccak256(query) => ReturnData 42 | mapping(bytes32 => ReturnData) internal _givenQueryReturn; 43 | 44 | /// @notice Whether a query was set to return something 45 | /// @dev keccak256(query) => bool 46 | mapping(bytes32 => bool) internal _givenQuerySet; 47 | 48 | /// @notice Whether arbitrary queries should be logged 49 | /// @dev starts as enabled 50 | bool public loggingEnabled = true; 51 | 52 | /// @notice Whether the query should be logged 53 | /// @dev keccak256(query) => bool 54 | mapping(bytes32 => bool) internal _givenQueryLog; 55 | 56 | /// @notice Whether the query should consume all gas 57 | /// @dev keccak256(query) => bool 58 | mapping(bytes32 => bool) internal _givenQueryConsumeAllGas; 59 | 60 | /// @notice Returns the logged call data for a given index 61 | /// @dev If the provided index is out of bounds, it reverts 62 | /// @param index_ The index of the call data to return 63 | /// @return CallData structure containing the logged call data 64 | function getCallData(uint256 index_) public view returns (CallData memory) { 65 | if (index_ >= _callData.length) { 66 | revert MockProvider__getCallData_indexOutOfBounds(index_); 67 | } 68 | return _callData[index_]; 69 | } 70 | 71 | /// @notice Disables logging of arbitrary queries 72 | /// @dev Any query that isn't explicitly set, will not be logged 73 | function disableLogging() public { 74 | loggingEnabled = false; 75 | } 76 | 77 | /// @notice Enables logging of arbitrary queries 78 | /// @dev Any query that isn't explicitly set, will be logged 79 | function enableLogging() public { 80 | loggingEnabled = true; 81 | } 82 | 83 | /// @notice Defines the default return in case no query matches 84 | /// @param returnData_ The return data to return 85 | function setDefaultResponse(ReturnData memory returnData_) public { 86 | _defaultReturnData = returnData_; 87 | } 88 | 89 | /// @notice Defines the default return in case no query matches 90 | /// @param response_ The return data to return 91 | function setDefault(bytes memory response_) external { 92 | // Forward execution 93 | setDefaultResponse(ReturnData({success: true, data: response_})); 94 | } 95 | 96 | /// @notice Defines the return data for a given query 97 | /// @param query_ The query to match 98 | /// @param returnData_ The return data to return 99 | /// @param log_ Whether the query should be logged 100 | function givenQueryReturnResponse( 101 | bytes memory query_, 102 | ReturnData memory returnData_, 103 | bool log_ 104 | ) public { 105 | // Calculate the query key 106 | bytes32 queryKey = keccak256(query_); 107 | 108 | // Save the return data for this query 109 | _givenQueryReturn[queryKey] = returnData_; 110 | 111 | // Mark the query as set 112 | _givenQuerySet[queryKey] = true; 113 | 114 | // Save whether the query should be logged 115 | _givenQueryLog[queryKey] = log_; 116 | } 117 | 118 | /// @notice Defines the return data for a given query 119 | /// @dev Does not log the query 120 | /// @param query_ The query to match 121 | /// @param response_ The return data to return 122 | function givenQueryReturn(bytes memory query_, bytes memory response_) 123 | public 124 | { 125 | // Forward execution 126 | givenQueryReturnResponse( 127 | query_, 128 | ReturnData({success: true, data: response_}), 129 | false 130 | ); 131 | } 132 | 133 | /// @notice Defines the return data for a given selector (msg.sig) 134 | /// @param selector_ The `msg.data` function selector to match 135 | /// @param returnData_ The return data to return 136 | /// @param log_ Whether the query should be logged 137 | function givenSelectorReturnResponse( 138 | bytes4 selector_, 139 | ReturnData memory returnData_, 140 | bool log_ 141 | ) public { 142 | // Calculate the key based on the provided selector 143 | bytes32 queryKey = keccak256(abi.encode(selector_)); 144 | 145 | // Save the return data for this query 146 | _givenQueryReturn[queryKey] = returnData_; 147 | 148 | // Mark the query as set 149 | _givenQuerySet[queryKey] = true; 150 | 151 | // Save whether the query should be logged 152 | _givenQueryLog[queryKey] = log_; 153 | } 154 | 155 | /// @notice Defines the return data for a given selector (msg.sig) 156 | /// @param selector_ The `msg.data` function selector to match 157 | /// @param response_ The return data to return 158 | function givenSelectorReturn(bytes4 selector_, bytes memory response_) 159 | public 160 | { 161 | // Forward call 162 | givenSelectorReturnResponse( 163 | selector_, 164 | ReturnData({success: true, data: response_}), 165 | false 166 | ); 167 | } 168 | 169 | function givenSelectorExecuteConsumeGas( 170 | bytes4 selector_, 171 | ReturnData memory returnData_, 172 | bool log_ 173 | ) public { 174 | // Calculate the key based on the provided selector 175 | bytes32 queryKey = keccak256(abi.encode(selector_)); 176 | 177 | // Save the return data for this query 178 | _givenQueryReturn[queryKey] = returnData_; 179 | 180 | // Mark the query as set 181 | _givenQuerySet[queryKey] = true; 182 | 183 | // Save whether the query should be logged 184 | _givenQueryLog[queryKey] = log_; 185 | 186 | // Consume all gas 187 | _givenQueryConsumeAllGas[queryKey] = true; 188 | } 189 | 190 | function givenQueryExecuteConsumeGas( 191 | bytes memory query_, 192 | ReturnData memory returnData_, 193 | bool log_ 194 | ) internal { 195 | // Calculate the key based on the provided selector 196 | bytes32 queryKey = keccak256(query_); 197 | 198 | // Save the return data for this query 199 | _givenQueryReturn[queryKey] = returnData_; 200 | 201 | // Mark the query as set 202 | _givenQuerySet[queryKey] = true; 203 | 204 | // Save whether the query should be logged 205 | _givenQueryLog[queryKey] = log_; 206 | 207 | // Consume all gas 208 | _givenQueryConsumeAllGas[queryKey] = true; 209 | } 210 | 211 | function givenSelectorConsumeGas(bytes4 selector_) public { 212 | // Forward call 213 | givenSelectorExecuteConsumeGas( 214 | selector_, 215 | ReturnData({success: false, data: bytes("")}), 216 | false 217 | ); 218 | } 219 | 220 | function givenQueryConsumeGas(bytes memory query_) public { 221 | // Forward call 222 | givenQueryExecuteConsumeGas( 223 | query_, 224 | ReturnData({success: false, data: bytes("")}), 225 | false 226 | ); 227 | } 228 | 229 | /// @notice Handles the calls 230 | /// @dev Tries to match calls based on `msg.data` or `msg.sig` and returns the corresponding return data 231 | // prettier-ignore 232 | fallback(bytes calldata) external payable returns (bytes memory){ 233 | bytes32 queryKey = keccak256(msg.data); 234 | bytes32 selectorKey = keccak256(abi.encode(msg.sig)); 235 | // Check if any set query matches the current query 236 | if (_givenQuerySet[queryKey] || _givenQuerySet[selectorKey]) { 237 | bytes32 key = _givenQuerySet[queryKey] ? queryKey : selectorKey; 238 | 239 | // Log call 240 | if (_givenQueryLog[key]) { 241 | _logCall(); 242 | } 243 | 244 | // Check if the query should consume all gas 245 | if ( 246 | _givenQueryConsumeAllGas[key] 247 | ) { 248 | emit log_string("Should consume all the gas"); 249 | _consumeGas(); 250 | } 251 | 252 | // Return data as specified by the query 253 | ReturnData memory returnData = _givenQueryReturn[key]; 254 | require(returnData.success, string(returnData.data)); 255 | return returnData.data; 256 | } 257 | 258 | // Log the call 259 | if (loggingEnabled) { 260 | _logCall(); 261 | } 262 | 263 | // Default to sending the default response 264 | return _defaultReturnData.data; 265 | } 266 | 267 | /// @notice Logs the call if logging is enabled or a default response is matched 268 | function _logCall() internal { 269 | // Log query 270 | _callData.push( 271 | CallData({ 272 | caller: msg.sender, 273 | functionSelector: msg.sig, 274 | data: msg.data, 275 | value: msg.value 276 | }) 277 | ); 278 | } 279 | 280 | /// @dev Taken from 281 | /// https://github.com/gnosis/mock-contract/blob/b0f735ddc62d5000b50667011d69142a4dee9c71/contracts/MockContract.sol#L300-L308 282 | function _consumeGas() internal { 283 | while (true) { 284 | bool s; 285 | assembly { 286 | // expensive call to EC multiply contract 287 | s := call(sub(gas(), 2000), 6, 0, 0x0, 0xc0, 0x0, 0x60) 288 | } 289 | } 290 | } 291 | } 292 | -------------------------------------------------------------------------------- /src/MockProvider.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | pragma solidity ^0.8.0; 3 | 4 | import "forge-std/Test.sol"; 5 | 6 | import {MockProvider} from "./MockProvider.sol"; 7 | 8 | // solhint-disable func-name-mixedcase 9 | contract MockProviderTest is Test { 10 | MockProvider internal mockProvider; 11 | 12 | function setUp() public { 13 | mockProvider = new MockProvider(); 14 | } 15 | 16 | function test_getCallData_Returns_CorrectData() public { 17 | bytes memory query = hex"1122334455667788"; 18 | uint256 queryValue = 1; 19 | 20 | // solhint-disable-next-line avoid-low-level-calls 21 | address(mockProvider).call{value: queryValue}(query); 22 | 23 | MockProvider.CallData memory rd = mockProvider.getCallData(0); 24 | 25 | assertEq(rd.caller, address(this), "Should match caller"); 26 | assertEq( 27 | rd.functionSelector, 28 | bytes4(query), 29 | "Should match function signature" 30 | ); 31 | assertEq(keccak256(rd.data), keccak256(query), "Should match query"); 32 | assertEq(rd.value, queryValue, "Should match ether amount"); 33 | } 34 | 35 | function testFail_getCallData_Fails_WhenIndexIsOutOfBounds() public view { 36 | mockProvider.getCallData(0); 37 | } 38 | 39 | function test_setDefaultResponse_Enables_ReturnResponseOnQuery( 40 | bytes memory response_ 41 | ) public { 42 | bytes memory query = hex"11223344"; 43 | 44 | mockProvider.setDefaultResponse( 45 | MockProvider.ReturnData({success: true, data: response_}) 46 | ); 47 | 48 | // solhint-disable-next-line avoid-low-level-calls 49 | (bool okReceived, bytes memory responseReceived) = address(mockProvider) 50 | .call(abi.encode(query)); 51 | 52 | assertTrue(okReceived, "Should not fail doing a call"); 53 | assertEq( 54 | keccak256(response_), 55 | keccak256(responseReceived), 56 | "Should match set default" 57 | ); 58 | } 59 | 60 | function test_setDefault_Enables_ReturnResponseOnQuery( 61 | bytes memory response_ 62 | ) public { 63 | bytes memory query = hex"11223344"; 64 | 65 | mockProvider.setDefault(response_); 66 | 67 | // solhint-disable-next-line avoid-low-level-calls 68 | (bool okReceived, bytes memory responseReceived) = address(mockProvider) 69 | .call(query); 70 | 71 | assertTrue(okReceived, "Should not fail doing a call"); 72 | assertEq( 73 | keccak256(response_), 74 | keccak256(responseReceived), 75 | "Should match set default" 76 | ); 77 | } 78 | 79 | function test_givenQueryReturnResponse_Enables_ReturnResponseOnQuery( 80 | bytes memory response_ 81 | ) public { 82 | bytes memory query = hex"11223344"; 83 | 84 | mockProvider.givenQueryReturnResponse( 85 | query, 86 | MockProvider.ReturnData({success: true, data: response_}), 87 | false 88 | ); 89 | 90 | // solhint-disable-next-line avoid-low-level-calls 91 | (bool okReceived, bytes memory responseReceived) = address(mockProvider) 92 | .call(query); 93 | 94 | assertTrue(okReceived, "Should not fail doing a call"); 95 | assertEq( 96 | keccak256(response_), 97 | keccak256(responseReceived), 98 | "Returned response should match" 99 | ); 100 | } 101 | 102 | function test_givenQueryReturn_Enables_ReturnResponseOnQuery( 103 | bytes memory response_ 104 | ) public { 105 | bytes memory query = hex"11223344"; 106 | 107 | mockProvider.givenQueryReturn(query, response_); 108 | 109 | // solhint-disable-next-line avoid-low-level-calls 110 | (bool okReceived, bytes memory responseReceived) = address(mockProvider) 111 | .call(query); 112 | 113 | assertTrue(okReceived, "Should not fail doing a call"); 114 | assertEq( 115 | keccak256(response_), 116 | keccak256(responseReceived), 117 | "Returned response should match" 118 | ); 119 | } 120 | 121 | function test_givenSelectorReturnResponse_Enables_ReturnResponseOnQuery( 122 | bytes memory params_, 123 | bytes memory response_ 124 | ) public { 125 | bytes4 selector = hex"11223344"; 126 | mockProvider.givenSelectorReturnResponse( 127 | selector, 128 | MockProvider.ReturnData({success: true, data: response_}), 129 | false 130 | ); 131 | 132 | bytes memory query = abi.encodePacked(selector, params_); 133 | 134 | // solhint-disable-next-line avoid-low-level-calls 135 | (bool okReceived, bytes memory responseReceived) = address(mockProvider) 136 | .call(query); 137 | 138 | assertTrue(okReceived, "Should not fail doing a call"); 139 | assertEq( 140 | keccak256(response_), 141 | keccak256(responseReceived), 142 | "Returned response should match" 143 | ); 144 | } 145 | 146 | function test_givenSelectorReturn_Enables_ReturnResponseOnQuery( 147 | bytes memory params_, 148 | bytes memory response_ 149 | ) public { 150 | bytes4 selector = hex"11223344"; 151 | mockProvider.givenSelectorReturn(selector, response_); 152 | 153 | bytes memory query = abi.encodePacked(selector, params_); 154 | 155 | // solhint-disable-next-line avoid-low-level-calls 156 | (bool okReceived, bytes memory responseReceived) = address(mockProvider) 157 | .call(query); 158 | 159 | assertTrue(okReceived, "Should not fail doing a call"); 160 | assertEq( 161 | keccak256(response_), 162 | keccak256(responseReceived), 163 | "Returned response should match" 164 | ); 165 | } 166 | 167 | function test_givenQueryReturnResponse_Fails_WithErrorMessage() public { 168 | bytes memory query = hex"11223344"; 169 | bytes memory reason = bytes("This is the error message"); 170 | mockProvider.givenQueryReturnResponse( 171 | query, 172 | MockProvider.ReturnData({success: false, data: reason}), 173 | false 174 | ); 175 | 176 | // solhint-disable-next-line avoid-low-level-calls 177 | (bool okReceived, bytes memory responseReceived) = address(mockProvider) 178 | .call(query); 179 | 180 | bytes memory reasonBytes = bytes.concat( 181 | // bytes4(keccak256("Error(string)")) 182 | hex"08c379a0", 183 | // encoded string reason 184 | abi.encode(reason) 185 | ); 186 | bytes32 reasonHash = keccak256(reasonBytes); 187 | bytes32 responseReceivedHash = keccak256(responseReceived); 188 | 189 | assertTrue(okReceived == false, "Should fail doing a call"); 190 | assertEq( 191 | responseReceivedHash, 192 | reasonHash, 193 | "Error message should match" 194 | ); 195 | } 196 | 197 | function test_givenQueryReturnResponse_Logs_Query(bytes memory response_) 198 | public 199 | { 200 | bytes memory query = hex"1122334455667788"; 201 | 202 | mockProvider.givenQueryReturnResponse( 203 | query, 204 | MockProvider.ReturnData({success: true, data: response_}), 205 | true 206 | ); 207 | 208 | // solhint-disable-next-line avoid-low-level-calls 209 | address(mockProvider).call(query); 210 | 211 | // Get logged query 212 | MockProvider.CallData memory cd = mockProvider.getCallData(0); 213 | 214 | // Check logged query 215 | assertEq(cd.caller, address(this), "Logged caller should match"); 216 | assertEq( 217 | cd.functionSelector, 218 | bytes4(query), 219 | "Logged query should match" 220 | ); 221 | assertEq( 222 | keccak256(cd.data), 223 | keccak256(query), 224 | "Logged query should match" 225 | ); 226 | assertEq(cd.value, 0, "Logged message value should match"); 227 | } 228 | 229 | function test_givenSelectorConsumeGas_Consumes_AllGas(bytes memory params_) 230 | public 231 | { 232 | bytes4 selector = hex"11223344"; 233 | mockProvider.givenSelectorConsumeGas(selector); 234 | 235 | bytes memory query = abi.encodePacked(selector, params_); 236 | 237 | uint256 initialGas = gasleft(); 238 | uint256 forwardGas = 100000; 239 | 240 | // This call has to consume all the provided gas 241 | (bool okReceived, bytes memory responseReceived) = address(mockProvider) 242 | .call{gas: forwardGas}(query); 243 | 244 | // Check that all sent gas was consumed as per definition below 245 | // remainingGas + forwardGas + c = initialGas 246 | // 247 | // initialGas - how much gas we started with before the call 248 | // remainingGas - how much gas we have right now 249 | // c - how much gas was consumed to set up the call and return; 250 | // this is difficult to hardcode or calculate, so we just 251 | // change the equality to be a bit more relaxed: 252 | // remainingGas + forwardGas < initialGas 253 | assertLt(gasleft() + forwardGas, initialGas, "Gas should be consumed"); 254 | 255 | assertFalse(okReceived, "Should fail when gas is consumed"); 256 | assertEq( 257 | keccak256(responseReceived), 258 | keccak256(bytes("")), 259 | "Should not return a message" 260 | ); 261 | } 262 | 263 | function test_givenQueryConsumeGas_Consumes_AllGas() public { 264 | bytes memory query = hex"1122334455667788"; 265 | mockProvider.givenQueryConsumeGas(query); 266 | 267 | uint256 initialGas = gasleft(); 268 | uint256 forwardGas = 100000; 269 | 270 | // This call has to consume all the provided gas 271 | (bool okReceived, bytes memory responseReceived) = address(mockProvider) 272 | .call{gas: forwardGas}(query); 273 | 274 | // Check that all sent gas was consumed 275 | assertLt(gasleft() + forwardGas, initialGas, "Gas should be consumed"); 276 | 277 | assertFalse(okReceived, "Should fail when gas is consumed"); 278 | assertEq( 279 | keccak256(responseReceived), 280 | keccak256(bytes("")), 281 | "Should not return a message" 282 | ); 283 | } 284 | 285 | function test_enableLogging_LogsRequests() public { 286 | bytes memory query = hex"11223344"; 287 | uint256 queryValue = 1; 288 | 289 | // Enable arbitrary logging 290 | mockProvider.enableLogging(); 291 | 292 | // solhint-disable-next-line avoid-low-level-calls 293 | address(mockProvider).call{value: queryValue}(query); 294 | 295 | // Get logged query 296 | MockProvider.CallData memory cd = mockProvider.getCallData(0); 297 | 298 | assertEq(cd.caller, address(this), "Logged caller should match"); 299 | assertEq( 300 | cd.functionSelector, 301 | bytes4(query), 302 | "Logged query should match" 303 | ); 304 | assertEq( 305 | keccak256(cd.data), 306 | keccak256(query), 307 | "Logged query should match" 308 | ); 309 | assertEq(cd.value, queryValue, "Logged message value should match"); 310 | } 311 | 312 | function testFail_disableLogging_DisablesLogging() public { 313 | // Disable logging 314 | mockProvider.disableLogging(); 315 | 316 | // Define arbitrary query 317 | bytes memory query = hex"11223344"; 318 | uint256 queryValue = 1; 319 | 320 | // solhint-disable-next-line avoid-low-level-calls 321 | address(mockProvider).call{value: queryValue}(query); 322 | 323 | // Get logged query should fail since logging is disabled and index 0 is out of bounds 324 | mockProvider.getCallData(0); 325 | } 326 | } 327 | -------------------------------------------------------------------------------- /src/test/utils/Caller.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | pragma solidity ^0.8.0; 3 | 4 | contract Caller { 5 | /// @dev Can use this method to call any other contract's function 6 | /// @param _contractAddress Address of the contract to call 7 | /// @param _callData Call data 8 | /// @return ok is `true` if the call was successful 9 | /// @return data is the encoded result of the call 10 | function externalCall(address _contractAddress, bytes calldata _callData) 11 | external 12 | returns (bool, bytes memory) 13 | { 14 | (bool ok, bytes memory data) = _contractAddress.call(_callData); 15 | return (ok, data); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/test/utils/Hevm.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Unlicense 2 | pragma solidity ^0.8.0; 3 | 4 | abstract contract Hevm { 5 | // sets the block timestamp to x 6 | function warp(uint256 x) public virtual; 7 | 8 | // sets the block number to x 9 | function roll(uint256 x) public virtual; 10 | 11 | // sets the slot loc of contract c to val 12 | function store( 13 | address c, 14 | bytes32 loc, 15 | bytes32 val 16 | ) public virtual; 17 | 18 | function ffi(string[] calldata) external virtual returns (bytes memory); 19 | } 20 | -------------------------------------------------------------------------------- /src/test/utils/tokens/TokenERC20.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | pragma solidity ^0.8.0; 3 | 4 | import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; 5 | 6 | contract TokenERC20 is ERC20 { 7 | constructor(string memory _name, string memory _symbol) 8 | ERC20(_name, _symbol) 9 | { 10 | this; 11 | } 12 | 13 | function mint(address _to, uint256 _amount) public { 14 | _mint(_to, _amount); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/test/utils/tokens/TokenERC721.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | pragma solidity ^0.8.0; 3 | 4 | import {ERC721} from "@openzeppelin/contracts/token/ERC721/ERC721.sol"; 5 | 6 | contract Token is ERC721 { 7 | constructor(string memory _name, string memory _symbol) 8 | ERC721(_name, _symbol) 9 | { 10 | this; 11 | } 12 | 13 | function mint(address _to, uint256 _id) public { 14 | _mint(_to, _id); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@babel/code-frame@^7.0.0": 6 | version "7.15.8" 7 | resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.15.8.tgz#45990c47adadb00c03677baa89221f7cc23d2503" 8 | integrity sha512-2IAnmn8zbvC/jKYhq5Ki9I+DwjlrtMPUCH/CpHvqI4dNnlwHwsxoIhlc8WcYY5LSYknXQtAlFYuHfqAFCvQ4Wg== 9 | dependencies: 10 | "@babel/highlight" "^7.14.5" 11 | 12 | "@babel/helper-validator-identifier@^7.14.5": 13 | version "7.15.7" 14 | resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz#220df993bfe904a4a6b02ab4f3385a5ebf6e2389" 15 | integrity sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w== 16 | 17 | "@babel/highlight@^7.14.5": 18 | version "7.14.5" 19 | resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.14.5.tgz#6861a52f03966405001f6aa534a01a24d99e8cd9" 20 | integrity sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg== 21 | dependencies: 22 | "@babel/helper-validator-identifier" "^7.14.5" 23 | chalk "^2.0.0" 24 | js-tokens "^4.0.0" 25 | 26 | "@solidity-parser/parser@^0.13.2": 27 | version "0.13.2" 28 | resolved "https://registry.yarnpkg.com/@solidity-parser/parser/-/parser-0.13.2.tgz#b6c71d8ca0b382d90a7bbed241f9bc110af65cbe" 29 | integrity sha512-RwHnpRnfrnD2MSPveYoPh8nhofEvX7fgjHk1Oq+NNvCcLx4r1js91CO9o+F/F3fBzOCyvm8kKRTriFICX/odWw== 30 | dependencies: 31 | antlr4ts "^0.5.0-alpha.4" 32 | 33 | acorn-jsx@^5.0.0: 34 | version "5.3.2" 35 | resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" 36 | integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== 37 | 38 | acorn@^6.0.7: 39 | version "6.4.2" 40 | resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.2.tgz#35866fd710528e92de10cf06016498e47e39e1e6" 41 | integrity sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ== 42 | 43 | ajv@^6.10.2, ajv@^6.6.1, ajv@^6.9.1: 44 | version "6.12.6" 45 | resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" 46 | integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== 47 | dependencies: 48 | fast-deep-equal "^3.1.1" 49 | fast-json-stable-stringify "^2.0.0" 50 | json-schema-traverse "^0.4.1" 51 | uri-js "^4.2.2" 52 | 53 | ansi-escapes@^3.2.0: 54 | version "3.2.0" 55 | resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b" 56 | integrity sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ== 57 | 58 | ansi-regex@^3.0.0: 59 | version "3.0.0" 60 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" 61 | integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= 62 | 63 | ansi-regex@^4.1.0: 64 | version "4.1.0" 65 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" 66 | integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== 67 | 68 | ansi-regex@^5.0.1: 69 | version "5.0.1" 70 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" 71 | integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== 72 | 73 | ansi-styles@^3.2.0, ansi-styles@^3.2.1: 74 | version "3.2.1" 75 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" 76 | integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== 77 | dependencies: 78 | color-convert "^1.9.0" 79 | 80 | ansi-styles@^4.0.0: 81 | version "4.3.0" 82 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" 83 | integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== 84 | dependencies: 85 | color-convert "^2.0.1" 86 | 87 | antlr4@4.7.1: 88 | version "4.7.1" 89 | resolved "https://registry.yarnpkg.com/antlr4/-/antlr4-4.7.1.tgz#69984014f096e9e775f53dd9744bf994d8959773" 90 | integrity sha512-haHyTW7Y9joE5MVs37P2lNYfU2RWBLfcRDD8OWldcdZm5TiCE91B5Xl1oWSwiDUSd4rlExpt2pu1fksYQjRBYQ== 91 | 92 | antlr4ts@^0.5.0-alpha.4: 93 | version "0.5.0-alpha.4" 94 | resolved "https://registry.yarnpkg.com/antlr4ts/-/antlr4ts-0.5.0-alpha.4.tgz#71702865a87478ed0b40c0709f422cf14d51652a" 95 | integrity sha512-WPQDt1B74OfPv/IMS2ekXAKkTZIHl88uMetg6q3OTqgFxZ/dxDXI0EWLyZid/1Pe6hTftyg5N7gel5wNAGxXyQ== 96 | 97 | argparse@^1.0.7: 98 | version "1.0.10" 99 | resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" 100 | integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== 101 | dependencies: 102 | sprintf-js "~1.0.2" 103 | 104 | ast-parents@0.0.1: 105 | version "0.0.1" 106 | resolved "https://registry.yarnpkg.com/ast-parents/-/ast-parents-0.0.1.tgz#508fd0f05d0c48775d9eccda2e174423261e8dd3" 107 | integrity sha1-UI/Q8F0MSHddnszaLhdEIyYejdM= 108 | 109 | astral-regex@^1.0.0: 110 | version "1.0.0" 111 | resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" 112 | integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== 113 | 114 | balanced-match@^1.0.0: 115 | version "1.0.2" 116 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" 117 | integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== 118 | 119 | brace-expansion@^1.1.7: 120 | version "1.1.11" 121 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" 122 | integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== 123 | dependencies: 124 | balanced-match "^1.0.0" 125 | concat-map "0.0.1" 126 | 127 | caller-callsite@^2.0.0: 128 | version "2.0.0" 129 | resolved "https://registry.yarnpkg.com/caller-callsite/-/caller-callsite-2.0.0.tgz#847e0fce0a223750a9a027c54b33731ad3154134" 130 | integrity sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ= 131 | dependencies: 132 | callsites "^2.0.0" 133 | 134 | caller-path@^2.0.0: 135 | version "2.0.0" 136 | resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-2.0.0.tgz#468f83044e369ab2010fac5f06ceee15bb2cb1f4" 137 | integrity sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ= 138 | dependencies: 139 | caller-callsite "^2.0.0" 140 | 141 | callsites@^2.0.0: 142 | version "2.0.0" 143 | resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50" 144 | integrity sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA= 145 | 146 | callsites@^3.0.0: 147 | version "3.1.0" 148 | resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" 149 | integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== 150 | 151 | chalk@^2.0.0, chalk@^2.1.0, chalk@^2.4.2: 152 | version "2.4.2" 153 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" 154 | integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== 155 | dependencies: 156 | ansi-styles "^3.2.1" 157 | escape-string-regexp "^1.0.5" 158 | supports-color "^5.3.0" 159 | 160 | chardet@^0.7.0: 161 | version "0.7.0" 162 | resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" 163 | integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== 164 | 165 | cli-cursor@^2.1.0: 166 | version "2.1.0" 167 | resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" 168 | integrity sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU= 169 | dependencies: 170 | restore-cursor "^2.0.0" 171 | 172 | cli-width@^2.0.0: 173 | version "2.2.1" 174 | resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.1.tgz#b0433d0b4e9c847ef18868a4ef16fd5fc8271c48" 175 | integrity sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw== 176 | 177 | cliui@^7.0.2: 178 | version "7.0.4" 179 | resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" 180 | integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== 181 | dependencies: 182 | string-width "^4.2.0" 183 | strip-ansi "^6.0.0" 184 | wrap-ansi "^7.0.0" 185 | 186 | color-convert@^1.9.0: 187 | version "1.9.3" 188 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" 189 | integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== 190 | dependencies: 191 | color-name "1.1.3" 192 | 193 | color-convert@^2.0.1: 194 | version "2.0.1" 195 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" 196 | integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== 197 | dependencies: 198 | color-name "~1.1.4" 199 | 200 | color-name@1.1.3: 201 | version "1.1.3" 202 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" 203 | integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= 204 | 205 | color-name@~1.1.4: 206 | version "1.1.4" 207 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" 208 | integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== 209 | 210 | commander@2.18.0: 211 | version "2.18.0" 212 | resolved "https://registry.yarnpkg.com/commander/-/commander-2.18.0.tgz#2bf063ddee7c7891176981a2cc798e5754bc6970" 213 | integrity sha512-6CYPa+JP2ftfRU2qkDK+UTVeQYosOg/2GbcjIcKPHfinyOLPVGXu/ovN86RP49Re5ndJK1N0kuiidFFuepc4ZQ== 214 | 215 | concat-map@0.0.1: 216 | version "0.0.1" 217 | resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" 218 | integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= 219 | 220 | copyfiles@^2.4.1: 221 | version "2.4.1" 222 | resolved "https://registry.yarnpkg.com/copyfiles/-/copyfiles-2.4.1.tgz#d2dcff60aaad1015f09d0b66e7f0f1c5cd3c5da5" 223 | integrity sha512-fereAvAvxDrQDOXybk3Qu3dPbOoKoysFMWtkY3mv5BsL8//OSZVL5DCLYqgRfY5cWirgRzlC+WSrxp6Bo3eNZg== 224 | dependencies: 225 | glob "^7.0.5" 226 | minimatch "^3.0.3" 227 | mkdirp "^1.0.4" 228 | noms "0.0.0" 229 | through2 "^2.0.1" 230 | untildify "^4.0.0" 231 | yargs "^16.1.0" 232 | 233 | core-util-is@~1.0.0: 234 | version "1.0.3" 235 | resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" 236 | integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== 237 | 238 | cosmiconfig@^5.0.7: 239 | version "5.2.1" 240 | resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.2.1.tgz#040f726809c591e77a17c0a3626ca45b4f168b1a" 241 | integrity sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA== 242 | dependencies: 243 | import-fresh "^2.0.0" 244 | is-directory "^0.3.1" 245 | js-yaml "^3.13.1" 246 | parse-json "^4.0.0" 247 | 248 | cross-spawn@^6.0.5: 249 | version "6.0.5" 250 | resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" 251 | integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== 252 | dependencies: 253 | nice-try "^1.0.4" 254 | path-key "^2.0.1" 255 | semver "^5.5.0" 256 | shebang-command "^1.2.0" 257 | which "^1.2.9" 258 | 259 | debug@^4.0.1: 260 | version "4.3.2" 261 | resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b" 262 | integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw== 263 | dependencies: 264 | ms "2.1.2" 265 | 266 | deep-is@~0.1.3: 267 | version "0.1.4" 268 | resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" 269 | integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== 270 | 271 | doctrine@^3.0.0: 272 | version "3.0.0" 273 | resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" 274 | integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== 275 | dependencies: 276 | esutils "^2.0.2" 277 | 278 | emoji-regex@^7.0.1: 279 | version "7.0.3" 280 | resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" 281 | integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== 282 | 283 | emoji-regex@^8.0.0: 284 | version "8.0.0" 285 | resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" 286 | integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== 287 | 288 | emoji-regex@^9.2.2: 289 | version "9.2.2" 290 | resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" 291 | integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== 292 | 293 | error-ex@^1.3.1: 294 | version "1.3.2" 295 | resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" 296 | integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== 297 | dependencies: 298 | is-arrayish "^0.2.1" 299 | 300 | escalade@^3.1.1: 301 | version "3.1.1" 302 | resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" 303 | integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== 304 | 305 | escape-string-regexp@^1.0.5: 306 | version "1.0.5" 307 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" 308 | integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= 309 | 310 | escape-string-regexp@^4.0.0: 311 | version "4.0.0" 312 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" 313 | integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== 314 | 315 | eslint-scope@^4.0.3: 316 | version "4.0.3" 317 | resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.3.tgz#ca03833310f6889a3264781aa82e63eb9cfe7848" 318 | integrity sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg== 319 | dependencies: 320 | esrecurse "^4.1.0" 321 | estraverse "^4.1.1" 322 | 323 | eslint-utils@^1.3.1: 324 | version "1.4.3" 325 | resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.3.tgz#74fec7c54d0776b6f67e0251040b5806564e981f" 326 | integrity sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q== 327 | dependencies: 328 | eslint-visitor-keys "^1.1.0" 329 | 330 | eslint-visitor-keys@^1.0.0, eslint-visitor-keys@^1.1.0: 331 | version "1.3.0" 332 | resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" 333 | integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== 334 | 335 | eslint@^5.6.0: 336 | version "5.16.0" 337 | resolved "https://registry.yarnpkg.com/eslint/-/eslint-5.16.0.tgz#a1e3ac1aae4a3fbd8296fcf8f7ab7314cbb6abea" 338 | integrity sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg== 339 | dependencies: 340 | "@babel/code-frame" "^7.0.0" 341 | ajv "^6.9.1" 342 | chalk "^2.1.0" 343 | cross-spawn "^6.0.5" 344 | debug "^4.0.1" 345 | doctrine "^3.0.0" 346 | eslint-scope "^4.0.3" 347 | eslint-utils "^1.3.1" 348 | eslint-visitor-keys "^1.0.0" 349 | espree "^5.0.1" 350 | esquery "^1.0.1" 351 | esutils "^2.0.2" 352 | file-entry-cache "^5.0.1" 353 | functional-red-black-tree "^1.0.1" 354 | glob "^7.1.2" 355 | globals "^11.7.0" 356 | ignore "^4.0.6" 357 | import-fresh "^3.0.0" 358 | imurmurhash "^0.1.4" 359 | inquirer "^6.2.2" 360 | js-yaml "^3.13.0" 361 | json-stable-stringify-without-jsonify "^1.0.1" 362 | levn "^0.3.0" 363 | lodash "^4.17.11" 364 | minimatch "^3.0.4" 365 | mkdirp "^0.5.1" 366 | natural-compare "^1.4.0" 367 | optionator "^0.8.2" 368 | path-is-inside "^1.0.2" 369 | progress "^2.0.0" 370 | regexpp "^2.0.1" 371 | semver "^5.5.1" 372 | strip-ansi "^4.0.0" 373 | strip-json-comments "^2.0.1" 374 | table "^5.2.3" 375 | text-table "^0.2.0" 376 | 377 | espree@^5.0.1: 378 | version "5.0.1" 379 | resolved "https://registry.yarnpkg.com/espree/-/espree-5.0.1.tgz#5d6526fa4fc7f0788a5cf75b15f30323e2f81f7a" 380 | integrity sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A== 381 | dependencies: 382 | acorn "^6.0.7" 383 | acorn-jsx "^5.0.0" 384 | eslint-visitor-keys "^1.0.0" 385 | 386 | esprima@^4.0.0: 387 | version "4.0.1" 388 | resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" 389 | integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== 390 | 391 | esquery@^1.0.1: 392 | version "1.4.0" 393 | resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.4.0.tgz#2148ffc38b82e8c7057dfed48425b3e61f0f24a5" 394 | integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w== 395 | dependencies: 396 | estraverse "^5.1.0" 397 | 398 | esrecurse@^4.1.0: 399 | version "4.3.0" 400 | resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" 401 | integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== 402 | dependencies: 403 | estraverse "^5.2.0" 404 | 405 | estraverse@^4.1.1: 406 | version "4.3.0" 407 | resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" 408 | integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== 409 | 410 | estraverse@^5.1.0, estraverse@^5.2.0: 411 | version "5.2.0" 412 | resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.2.0.tgz#307df42547e6cc7324d3cf03c155d5cdb8c53880" 413 | integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ== 414 | 415 | esutils@^2.0.2: 416 | version "2.0.3" 417 | resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" 418 | integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== 419 | 420 | external-editor@^3.0.3: 421 | version "3.1.0" 422 | resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" 423 | integrity sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew== 424 | dependencies: 425 | chardet "^0.7.0" 426 | iconv-lite "^0.4.24" 427 | tmp "^0.0.33" 428 | 429 | fast-deep-equal@^3.1.1: 430 | version "3.1.3" 431 | resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" 432 | integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== 433 | 434 | fast-diff@^1.1.2: 435 | version "1.2.0" 436 | resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.2.0.tgz#73ee11982d86caaf7959828d519cfe927fac5f03" 437 | integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w== 438 | 439 | fast-json-stable-stringify@^2.0.0: 440 | version "2.1.0" 441 | resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" 442 | integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== 443 | 444 | fast-levenshtein@~2.0.6: 445 | version "2.0.6" 446 | resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" 447 | integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= 448 | 449 | figures@^2.0.0: 450 | version "2.0.0" 451 | resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" 452 | integrity sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI= 453 | dependencies: 454 | escape-string-regexp "^1.0.5" 455 | 456 | file-entry-cache@^5.0.1: 457 | version "5.0.1" 458 | resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-5.0.1.tgz#ca0f6efa6dd3d561333fb14515065c2fafdf439c" 459 | integrity sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g== 460 | dependencies: 461 | flat-cache "^2.0.1" 462 | 463 | flat-cache@^2.0.1: 464 | version "2.0.1" 465 | resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-2.0.1.tgz#5d296d6f04bda44a4630a301413bdbc2ec085ec0" 466 | integrity sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA== 467 | dependencies: 468 | flatted "^2.0.0" 469 | rimraf "2.6.3" 470 | write "1.0.3" 471 | 472 | flatted@^2.0.0: 473 | version "2.0.2" 474 | resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.2.tgz#4575b21e2bcee7434aa9be662f4b7b5f9c2b5138" 475 | integrity sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA== 476 | 477 | fs.realpath@^1.0.0: 478 | version "1.0.0" 479 | resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" 480 | integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= 481 | 482 | functional-red-black-tree@^1.0.1: 483 | version "1.0.1" 484 | resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" 485 | integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= 486 | 487 | get-caller-file@^2.0.5: 488 | version "2.0.5" 489 | resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" 490 | integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== 491 | 492 | glob@^7.0.5, glob@^7.1.2, glob@^7.1.3: 493 | version "7.2.0" 494 | resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" 495 | integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== 496 | dependencies: 497 | fs.realpath "^1.0.0" 498 | inflight "^1.0.4" 499 | inherits "2" 500 | minimatch "^3.0.4" 501 | once "^1.3.0" 502 | path-is-absolute "^1.0.0" 503 | 504 | globals@^11.7.0: 505 | version "11.12.0" 506 | resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" 507 | integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== 508 | 509 | has-flag@^3.0.0: 510 | version "3.0.0" 511 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" 512 | integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= 513 | 514 | iconv-lite@^0.4.24: 515 | version "0.4.24" 516 | resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" 517 | integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== 518 | dependencies: 519 | safer-buffer ">= 2.1.2 < 3" 520 | 521 | ignore@^4.0.6: 522 | version "4.0.6" 523 | resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" 524 | integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== 525 | 526 | import-fresh@^2.0.0: 527 | version "2.0.0" 528 | resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-2.0.0.tgz#d81355c15612d386c61f9ddd3922d4304822a546" 529 | integrity sha1-2BNVwVYS04bGH53dOSLUMEgipUY= 530 | dependencies: 531 | caller-path "^2.0.0" 532 | resolve-from "^3.0.0" 533 | 534 | import-fresh@^3.0.0: 535 | version "3.3.0" 536 | resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" 537 | integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== 538 | dependencies: 539 | parent-module "^1.0.0" 540 | resolve-from "^4.0.0" 541 | 542 | imurmurhash@^0.1.4: 543 | version "0.1.4" 544 | resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" 545 | integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= 546 | 547 | inflight@^1.0.4: 548 | version "1.0.6" 549 | resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" 550 | integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= 551 | dependencies: 552 | once "^1.3.0" 553 | wrappy "1" 554 | 555 | inherits@2, inherits@^2.0.1, inherits@~2.0.1, inherits@~2.0.3: 556 | version "2.0.4" 557 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" 558 | integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== 559 | 560 | inquirer@^6.2.2: 561 | version "6.5.2" 562 | resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.5.2.tgz#ad50942375d036d327ff528c08bd5fab089928ca" 563 | integrity sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ== 564 | dependencies: 565 | ansi-escapes "^3.2.0" 566 | chalk "^2.4.2" 567 | cli-cursor "^2.1.0" 568 | cli-width "^2.0.0" 569 | external-editor "^3.0.3" 570 | figures "^2.0.0" 571 | lodash "^4.17.12" 572 | mute-stream "0.0.7" 573 | run-async "^2.2.0" 574 | rxjs "^6.4.0" 575 | string-width "^2.1.0" 576 | strip-ansi "^5.1.0" 577 | through "^2.3.6" 578 | 579 | is-arrayish@^0.2.1: 580 | version "0.2.1" 581 | resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" 582 | integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= 583 | 584 | is-directory@^0.3.1: 585 | version "0.3.1" 586 | resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1" 587 | integrity sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE= 588 | 589 | is-fullwidth-code-point@^2.0.0: 590 | version "2.0.0" 591 | resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" 592 | integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= 593 | 594 | is-fullwidth-code-point@^3.0.0: 595 | version "3.0.0" 596 | resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" 597 | integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== 598 | 599 | isarray@0.0.1: 600 | version "0.0.1" 601 | resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" 602 | integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= 603 | 604 | isarray@~1.0.0: 605 | version "1.0.0" 606 | resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" 607 | integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= 608 | 609 | isexe@^2.0.0: 610 | version "2.0.0" 611 | resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" 612 | integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= 613 | 614 | js-tokens@^4.0.0: 615 | version "4.0.0" 616 | resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" 617 | integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== 618 | 619 | js-yaml@^3.12.0, js-yaml@^3.13.0, js-yaml@^3.13.1: 620 | version "3.14.1" 621 | resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" 622 | integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== 623 | dependencies: 624 | argparse "^1.0.7" 625 | esprima "^4.0.0" 626 | 627 | json-parse-better-errors@^1.0.1: 628 | version "1.0.2" 629 | resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" 630 | integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== 631 | 632 | json-schema-traverse@^0.4.1: 633 | version "0.4.1" 634 | resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" 635 | integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== 636 | 637 | json-stable-stringify-without-jsonify@^1.0.1: 638 | version "1.0.1" 639 | resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" 640 | integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= 641 | 642 | levn@^0.3.0, levn@~0.3.0: 643 | version "0.3.0" 644 | resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" 645 | integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= 646 | dependencies: 647 | prelude-ls "~1.1.2" 648 | type-check "~0.3.2" 649 | 650 | lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.14: 651 | version "4.17.21" 652 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" 653 | integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== 654 | 655 | lru-cache@^6.0.0: 656 | version "6.0.0" 657 | resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" 658 | integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== 659 | dependencies: 660 | yallist "^4.0.0" 661 | 662 | mimic-fn@^1.0.0: 663 | version "1.2.0" 664 | resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" 665 | integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ== 666 | 667 | minimatch@^3.0.3, minimatch@^3.0.4: 668 | version "3.0.4" 669 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" 670 | integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== 671 | dependencies: 672 | brace-expansion "^1.1.7" 673 | 674 | minimist@^1.2.5: 675 | version "1.2.5" 676 | resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" 677 | integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== 678 | 679 | mkdirp@^0.5.1: 680 | version "0.5.5" 681 | resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" 682 | integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== 683 | dependencies: 684 | minimist "^1.2.5" 685 | 686 | mkdirp@^1.0.4: 687 | version "1.0.4" 688 | resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" 689 | integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== 690 | 691 | ms@2.1.2: 692 | version "2.1.2" 693 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" 694 | integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== 695 | 696 | mute-stream@0.0.7: 697 | version "0.0.7" 698 | resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" 699 | integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s= 700 | 701 | natural-compare@^1.4.0: 702 | version "1.4.0" 703 | resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" 704 | integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= 705 | 706 | nice-try@^1.0.4: 707 | version "1.0.5" 708 | resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" 709 | integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== 710 | 711 | noms@0.0.0: 712 | version "0.0.0" 713 | resolved "https://registry.yarnpkg.com/noms/-/noms-0.0.0.tgz#da8ebd9f3af9d6760919b27d9cdc8092a7332859" 714 | integrity sha1-2o69nzr51nYJGbJ9nNyAkqczKFk= 715 | dependencies: 716 | inherits "^2.0.1" 717 | readable-stream "~1.0.31" 718 | 719 | once@^1.3.0: 720 | version "1.4.0" 721 | resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" 722 | integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= 723 | dependencies: 724 | wrappy "1" 725 | 726 | onetime@^2.0.0: 727 | version "2.0.1" 728 | resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" 729 | integrity sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ= 730 | dependencies: 731 | mimic-fn "^1.0.0" 732 | 733 | optionator@^0.8.2: 734 | version "0.8.3" 735 | resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" 736 | integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== 737 | dependencies: 738 | deep-is "~0.1.3" 739 | fast-levenshtein "~2.0.6" 740 | levn "~0.3.0" 741 | prelude-ls "~1.1.2" 742 | type-check "~0.3.2" 743 | word-wrap "~1.2.3" 744 | 745 | os-tmpdir@~1.0.2: 746 | version "1.0.2" 747 | resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" 748 | integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= 749 | 750 | parent-module@^1.0.0: 751 | version "1.0.1" 752 | resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" 753 | integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== 754 | dependencies: 755 | callsites "^3.0.0" 756 | 757 | parse-json@^4.0.0: 758 | version "4.0.0" 759 | resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" 760 | integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA= 761 | dependencies: 762 | error-ex "^1.3.1" 763 | json-parse-better-errors "^1.0.1" 764 | 765 | path-is-absolute@^1.0.0: 766 | version "1.0.1" 767 | resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" 768 | integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= 769 | 770 | path-is-inside@^1.0.2: 771 | version "1.0.2" 772 | resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" 773 | integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM= 774 | 775 | path-key@^2.0.1: 776 | version "2.0.1" 777 | resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" 778 | integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= 779 | 780 | prelude-ls@~1.1.2: 781 | version "1.1.2" 782 | resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" 783 | integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= 784 | 785 | prettier-linter-helpers@^1.0.0: 786 | version "1.0.0" 787 | resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b" 788 | integrity sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w== 789 | dependencies: 790 | fast-diff "^1.1.2" 791 | 792 | prettier-plugin-solidity@^1.0.0-beta.18: 793 | version "1.0.0-beta.18" 794 | resolved "https://registry.yarnpkg.com/prettier-plugin-solidity/-/prettier-plugin-solidity-1.0.0-beta.18.tgz#9705453bacd55b3242110d472f23f624ae6777fc" 795 | integrity sha512-ezWdsG/jIeClmYBzg8V9Voy8jujt+VxWF8OS3Vld+C3c+3cPVib8D9l8ahTod7O5Df1anK9zo+WiiS5wb1mLmg== 796 | dependencies: 797 | "@solidity-parser/parser" "^0.13.2" 798 | emoji-regex "^9.2.2" 799 | escape-string-regexp "^4.0.0" 800 | semver "^7.3.5" 801 | solidity-comments-extractor "^0.0.7" 802 | string-width "^4.2.2" 803 | 804 | prettier@^1.14.3: 805 | version "1.19.1" 806 | resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.19.1.tgz#f7d7f5ff8a9cd872a7be4ca142095956a60797cb" 807 | integrity sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew== 808 | 809 | prettier@^2.4.1: 810 | version "2.4.1" 811 | resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.4.1.tgz#671e11c89c14a4cfc876ce564106c4a6726c9f5c" 812 | integrity sha512-9fbDAXSBcc6Bs1mZrDYb3XKzDLm4EXXL9sC1LqKP5rZkT6KRr/rf9amVUcODVXgguK/isJz0d0hP72WeaKWsvA== 813 | 814 | process-nextick-args@~2.0.0: 815 | version "2.0.1" 816 | resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" 817 | integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== 818 | 819 | progress@^2.0.0: 820 | version "2.0.3" 821 | resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" 822 | integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== 823 | 824 | punycode@^2.1.0: 825 | version "2.1.1" 826 | resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" 827 | integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== 828 | 829 | readable-stream@~1.0.31: 830 | version "1.0.34" 831 | resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" 832 | integrity sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw= 833 | dependencies: 834 | core-util-is "~1.0.0" 835 | inherits "~2.0.1" 836 | isarray "0.0.1" 837 | string_decoder "~0.10.x" 838 | 839 | readable-stream@~2.3.6: 840 | version "2.3.7" 841 | resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" 842 | integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== 843 | dependencies: 844 | core-util-is "~1.0.0" 845 | inherits "~2.0.3" 846 | isarray "~1.0.0" 847 | process-nextick-args "~2.0.0" 848 | safe-buffer "~5.1.1" 849 | string_decoder "~1.1.1" 850 | util-deprecate "~1.0.1" 851 | 852 | regexpp@^2.0.1: 853 | version "2.0.1" 854 | resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f" 855 | integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw== 856 | 857 | require-directory@^2.1.1: 858 | version "2.1.1" 859 | resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" 860 | integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= 861 | 862 | resolve-from@^3.0.0: 863 | version "3.0.0" 864 | resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" 865 | integrity sha1-six699nWiBvItuZTM17rywoYh0g= 866 | 867 | resolve-from@^4.0.0: 868 | version "4.0.0" 869 | resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" 870 | integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== 871 | 872 | restore-cursor@^2.0.0: 873 | version "2.0.0" 874 | resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" 875 | integrity sha1-n37ih/gv0ybU/RYpI9YhKe7g368= 876 | dependencies: 877 | onetime "^2.0.0" 878 | signal-exit "^3.0.2" 879 | 880 | rimraf@2.6.3: 881 | version "2.6.3" 882 | resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" 883 | integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== 884 | dependencies: 885 | glob "^7.1.3" 886 | 887 | rimraf@^3.0.2: 888 | version "3.0.2" 889 | resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" 890 | integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== 891 | dependencies: 892 | glob "^7.1.3" 893 | 894 | run-async@^2.2.0: 895 | version "2.4.1" 896 | resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455" 897 | integrity sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ== 898 | 899 | rxjs@^6.4.0: 900 | version "6.6.7" 901 | resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.7.tgz#90ac018acabf491bf65044235d5863c4dab804c9" 902 | integrity sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ== 903 | dependencies: 904 | tslib "^1.9.0" 905 | 906 | safe-buffer@~5.1.0, safe-buffer@~5.1.1: 907 | version "5.1.2" 908 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" 909 | integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== 910 | 911 | "safer-buffer@>= 2.1.2 < 3": 912 | version "2.1.2" 913 | resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" 914 | integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== 915 | 916 | semver@^5.5.0, semver@^5.5.1: 917 | version "5.7.1" 918 | resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" 919 | integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== 920 | 921 | semver@^6.3.0: 922 | version "6.3.0" 923 | resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" 924 | integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== 925 | 926 | semver@^7.3.5: 927 | version "7.3.5" 928 | resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" 929 | integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== 930 | dependencies: 931 | lru-cache "^6.0.0" 932 | 933 | shebang-command@^1.2.0: 934 | version "1.2.0" 935 | resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" 936 | integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= 937 | dependencies: 938 | shebang-regex "^1.0.0" 939 | 940 | shebang-regex@^1.0.0: 941 | version "1.0.0" 942 | resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" 943 | integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= 944 | 945 | signal-exit@^3.0.2: 946 | version "3.0.5" 947 | resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.5.tgz#9e3e8cc0c75a99472b44321033a7702e7738252f" 948 | integrity sha512-KWcOiKeQj6ZyXx7zq4YxSMgHRlod4czeBQZrPb8OKcohcqAXShm7E20kEMle9WBt26hFcAf0qLOcp5zmY7kOqQ== 949 | 950 | slice-ansi@^2.1.0: 951 | version "2.1.0" 952 | resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636" 953 | integrity sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ== 954 | dependencies: 955 | ansi-styles "^3.2.0" 956 | astral-regex "^1.0.0" 957 | is-fullwidth-code-point "^2.0.0" 958 | 959 | solhint-plugin-prettier@^0.0.5: 960 | version "0.0.5" 961 | resolved "https://registry.yarnpkg.com/solhint-plugin-prettier/-/solhint-plugin-prettier-0.0.5.tgz#e3b22800ba435cd640a9eca805a7f8bc3e3e6a6b" 962 | integrity sha512-7jmWcnVshIrO2FFinIvDQmhQpfpS2rRRn3RejiYgnjIE68xO2bvrYvjqVNfrio4xH9ghOqn83tKuTzLjEbmGIA== 963 | dependencies: 964 | prettier-linter-helpers "^1.0.0" 965 | 966 | solhint@^3.3.6: 967 | version "3.3.6" 968 | resolved "https://registry.yarnpkg.com/solhint/-/solhint-3.3.6.tgz#abe9af185a9a7defefba480047b3e42cbe9a1210" 969 | integrity sha512-HWUxTAv2h7hx3s3hAab3ifnlwb02ZWhwFU/wSudUHqteMS3ll9c+m1FlGn9V8ztE2rf3Z82fQZA005Wv7KpcFA== 970 | dependencies: 971 | "@solidity-parser/parser" "^0.13.2" 972 | ajv "^6.6.1" 973 | antlr4 "4.7.1" 974 | ast-parents "0.0.1" 975 | chalk "^2.4.2" 976 | commander "2.18.0" 977 | cosmiconfig "^5.0.7" 978 | eslint "^5.6.0" 979 | fast-diff "^1.1.2" 980 | glob "^7.1.3" 981 | ignore "^4.0.6" 982 | js-yaml "^3.12.0" 983 | lodash "^4.17.11" 984 | semver "^6.3.0" 985 | optionalDependencies: 986 | prettier "^1.14.3" 987 | 988 | solidity-comments-extractor@^0.0.7: 989 | version "0.0.7" 990 | resolved "https://registry.yarnpkg.com/solidity-comments-extractor/-/solidity-comments-extractor-0.0.7.tgz#99d8f1361438f84019795d928b931f4e5c39ca19" 991 | integrity sha512-wciNMLg/Irp8OKGrh3S2tfvZiZ0NEyILfcRCXCD4mp7SgK/i9gzLfhY2hY7VMCQJ3kH9UB9BzNdibIVMchzyYw== 992 | 993 | sprintf-js@~1.0.2: 994 | version "1.0.3" 995 | resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" 996 | integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= 997 | 998 | string-width@^2.1.0: 999 | version "2.1.1" 1000 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" 1001 | integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== 1002 | dependencies: 1003 | is-fullwidth-code-point "^2.0.0" 1004 | strip-ansi "^4.0.0" 1005 | 1006 | string-width@^3.0.0: 1007 | version "3.1.0" 1008 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" 1009 | integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== 1010 | dependencies: 1011 | emoji-regex "^7.0.1" 1012 | is-fullwidth-code-point "^2.0.0" 1013 | strip-ansi "^5.1.0" 1014 | 1015 | string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2: 1016 | version "4.2.3" 1017 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" 1018 | integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== 1019 | dependencies: 1020 | emoji-regex "^8.0.0" 1021 | is-fullwidth-code-point "^3.0.0" 1022 | strip-ansi "^6.0.1" 1023 | 1024 | string_decoder@~0.10.x: 1025 | version "0.10.31" 1026 | resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" 1027 | integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ= 1028 | 1029 | string_decoder@~1.1.1: 1030 | version "1.1.1" 1031 | resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" 1032 | integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== 1033 | dependencies: 1034 | safe-buffer "~5.1.0" 1035 | 1036 | strip-ansi@^4.0.0: 1037 | version "4.0.0" 1038 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" 1039 | integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= 1040 | dependencies: 1041 | ansi-regex "^3.0.0" 1042 | 1043 | strip-ansi@^5.1.0: 1044 | version "5.2.0" 1045 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" 1046 | integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== 1047 | dependencies: 1048 | ansi-regex "^4.1.0" 1049 | 1050 | strip-ansi@^6.0.0, strip-ansi@^6.0.1: 1051 | version "6.0.1" 1052 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" 1053 | integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== 1054 | dependencies: 1055 | ansi-regex "^5.0.1" 1056 | 1057 | strip-json-comments@^2.0.1: 1058 | version "2.0.1" 1059 | resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" 1060 | integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= 1061 | 1062 | supports-color@^5.3.0: 1063 | version "5.5.0" 1064 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" 1065 | integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== 1066 | dependencies: 1067 | has-flag "^3.0.0" 1068 | 1069 | table@^5.2.3: 1070 | version "5.4.6" 1071 | resolved "https://registry.yarnpkg.com/table/-/table-5.4.6.tgz#1292d19500ce3f86053b05f0e8e7e4a3bb21079e" 1072 | integrity sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug== 1073 | dependencies: 1074 | ajv "^6.10.2" 1075 | lodash "^4.17.14" 1076 | slice-ansi "^2.1.0" 1077 | string-width "^3.0.0" 1078 | 1079 | text-table@^0.2.0: 1080 | version "0.2.0" 1081 | resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" 1082 | integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= 1083 | 1084 | through2@^2.0.1: 1085 | version "2.0.5" 1086 | resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" 1087 | integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== 1088 | dependencies: 1089 | readable-stream "~2.3.6" 1090 | xtend "~4.0.1" 1091 | 1092 | through@^2.3.6: 1093 | version "2.3.8" 1094 | resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" 1095 | integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= 1096 | 1097 | tmp@^0.0.33: 1098 | version "0.0.33" 1099 | resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" 1100 | integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== 1101 | dependencies: 1102 | os-tmpdir "~1.0.2" 1103 | 1104 | tslib@^1.9.0: 1105 | version "1.14.1" 1106 | resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" 1107 | integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== 1108 | 1109 | type-check@~0.3.2: 1110 | version "0.3.2" 1111 | resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" 1112 | integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= 1113 | dependencies: 1114 | prelude-ls "~1.1.2" 1115 | 1116 | untildify@^4.0.0: 1117 | version "4.0.0" 1118 | resolved "https://registry.yarnpkg.com/untildify/-/untildify-4.0.0.tgz#2bc947b953652487e4600949fb091e3ae8cd919b" 1119 | integrity sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw== 1120 | 1121 | uri-js@^4.2.2: 1122 | version "4.4.1" 1123 | resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" 1124 | integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== 1125 | dependencies: 1126 | punycode "^2.1.0" 1127 | 1128 | util-deprecate@~1.0.1: 1129 | version "1.0.2" 1130 | resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" 1131 | integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= 1132 | 1133 | which@^1.2.9: 1134 | version "1.3.1" 1135 | resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" 1136 | integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== 1137 | dependencies: 1138 | isexe "^2.0.0" 1139 | 1140 | word-wrap@~1.2.3: 1141 | version "1.2.3" 1142 | resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" 1143 | integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== 1144 | 1145 | wrap-ansi@^7.0.0: 1146 | version "7.0.0" 1147 | resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" 1148 | integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== 1149 | dependencies: 1150 | ansi-styles "^4.0.0" 1151 | string-width "^4.1.0" 1152 | strip-ansi "^6.0.0" 1153 | 1154 | wrappy@1: 1155 | version "1.0.2" 1156 | resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" 1157 | integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= 1158 | 1159 | write@1.0.3: 1160 | version "1.0.3" 1161 | resolved "https://registry.yarnpkg.com/write/-/write-1.0.3.tgz#0800e14523b923a387e415123c865616aae0f5c3" 1162 | integrity sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig== 1163 | dependencies: 1164 | mkdirp "^0.5.1" 1165 | 1166 | xtend@~4.0.1: 1167 | version "4.0.2" 1168 | resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" 1169 | integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== 1170 | 1171 | y18n@^5.0.5: 1172 | version "5.0.8" 1173 | resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" 1174 | integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== 1175 | 1176 | yallist@^4.0.0: 1177 | version "4.0.0" 1178 | resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" 1179 | integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== 1180 | 1181 | yargs-parser@^20.2.2: 1182 | version "20.2.9" 1183 | resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" 1184 | integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== 1185 | 1186 | yargs@^16.1.0: 1187 | version "16.2.0" 1188 | resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" 1189 | integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== 1190 | dependencies: 1191 | cliui "^7.0.2" 1192 | escalade "^3.1.1" 1193 | get-caller-file "^2.0.5" 1194 | require-directory "^2.1.1" 1195 | string-width "^4.2.0" 1196 | y18n "^5.0.5" 1197 | yargs-parser "^20.2.2" 1198 | --------------------------------------------------------------------------------