├── .eslintrc.js ├── .github └── workflows │ └── node.js.yml ├── .gitignore ├── README.md ├── contracts ├── BundleExecutor.sol └── UniswapFlashQuery.sol ├── jasmine.json ├── package-lock.json ├── package.json ├── src ├── Arbitrage.ts ├── EthMarket.ts ├── UniswappyV2EthPair.ts ├── abi.ts ├── addresses.ts ├── index.ts └── utils.ts ├── test ├── Arbitrage.test.ts └── UniswappyV2EthPair.test.ts └── tsconfig.json /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "env": { 3 | "browser": true, 4 | "es2021": true 5 | }, 6 | "extends": [ 7 | "eslint:recommended", 8 | "plugin:@typescript-eslint/recommended" 9 | ], 10 | "parser": "@typescript-eslint/parser", 11 | "parserOptions": { 12 | "ecmaVersion": 12, 13 | "sourceType": "module" 14 | }, 15 | "plugins": [ 16 | "@typescript-eslint" 17 | ], 18 | "rules": { 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /.github/workflows/node.js.yml: -------------------------------------------------------------------------------- 1 | # This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions 3 | 4 | name: Node.js CI 5 | 6 | on: 7 | push: 8 | branches: [ master ] 9 | pull_request: 10 | branches: [ master ] 11 | 12 | jobs: 13 | build: 14 | 15 | runs-on: ubuntu-latest 16 | 17 | strategy: 18 | matrix: 19 | node-version: [10.x, 12.x, 14.x, 15.x] 20 | # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ 21 | 22 | steps: 23 | - uses: actions/checkout@v2 24 | - name: Use Node.js ${{ matrix.node-version }} 25 | uses: actions/setup-node@v1 26 | with: 27 | node-version: ${{ matrix.node-version }} 28 | - run: npm install 29 | - run: npm run lint 30 | - run: npm run build 31 | - run: npm test 32 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.idea 2 | /node_modules 3 | /build 4 | /tsconfig.tsbuildinfo 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | simple-arbitrage 2 | ================ 3 | This repository contains a simple, mechanical system for discovering, evaluating, rating, and submitting arbitrage opportunities to the Flashbots bundle endpoint. This script is very unlikely to be profitable, as many users have access to it, and it is targeting well-known Ethereum opportunities. 4 | 5 | We hope you will use this repository as an example of how to integrate Flashbots into your own Flashbot searcher (bot). For more information, see the [Flashbots Searcher FAQ](https://docs.flashbots.net/flashbots-auction/searchers/faq) 6 | 7 | Environment Variables 8 | ===================== 9 | - **ETHEREUM_RPC_URL** - Ethereum RPC endpoint. Can not be the same as FLASHBOTS_RPC_URL 10 | - **PRIVATE_KEY** - Private key for the Ethereum EOA that will be submitting Flashbots Ethereum transactions 11 | - **FLASHBOTS_RELAY_SIGNING_KEY** _[Optional, default: random]_ - Flashbots submissions require an Ethereum private key to sign transaction payloads. This newly-created account does not need to hold any funds or correlate to any on-chain activity, it just needs to be used across multiple Flashbots RPC requests to identify requests related to same searcher. Please see https://docs.flashbots.net/flashbots-auction/searchers/faq#do-i-need-authentication-to-access-the-flashbots-relay 12 | - **HEALTHCHECK_URL** _[Optional]_ - Health check URL, hit only after successfully submitting a bundle. 13 | - **MINER_REWARD_PERCENTAGE** _[Optional, default 80]_ - 0 -> 100, what percentage of overall profitability to send to miner. 14 | 15 | Usage 16 | ====================== 17 | 1. Generate a new bot wallet address and extract the private key into a raw 32-byte format. 18 | 2. Deploy the included BundleExecutor.sol to Ethereum, from a secured account, with the address of the newly created wallet as the constructor argument 19 | 3. Transfer WETH to the newly deployed BundleExecutor 20 | 21 | _It is important to keep both the bot wallet private key and bundleExecutor owner private key secure. The bot wallet attempts to not lose WETH inside an arbitrage, but a malicious user would be able to drain the contract._ 22 | 23 | ``` 24 | $ npm install 25 | $ PRIVATE_KEY=__PRIVATE_KEY_FROM_ABOVE__ \ 26 | BUNDLE_EXECUTOR_ADDRESS=__DEPLOYED_ADDRESS_FROM_ABOVE__ \ 27 | FLASHBOTS_RELAY_SIGNING_KEY=__RANDOM_ETHEREUM_PRIVATE_KEY__ \ 28 | npm run start 29 | ``` 30 | -------------------------------------------------------------------------------- /contracts/BundleExecutor.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: UNLICENSED 2 | pragma solidity 0.6.12; 3 | 4 | pragma experimental ABIEncoderV2; 5 | 6 | interface IERC20 { 7 | event Approval(address indexed owner, address indexed spender, uint value); 8 | event Transfer(address indexed from, address indexed to, uint value); 9 | 10 | function name() external view returns (string memory); 11 | function symbol() external view returns (string memory); 12 | function decimals() external view returns (uint8); 13 | function totalSupply() external view returns (uint); 14 | function balanceOf(address owner) external view returns (uint); 15 | function allowance(address owner, address spender) external view returns (uint); 16 | 17 | function approve(address spender, uint value) external returns (bool); 18 | function transfer(address to, uint value) external returns (bool); 19 | function transferFrom(address from, address to, uint value) external returns (bool); 20 | } 21 | 22 | interface IWETH is IERC20 { 23 | function deposit() external payable; 24 | function withdraw(uint) external; 25 | } 26 | 27 | // This contract simply calls multiple targets sequentially, ensuring WETH balance before and after 28 | 29 | contract FlashBotsMultiCall { 30 | address private immutable owner; 31 | address private immutable executor; 32 | IWETH private constant WETH = IWETH(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2); 33 | 34 | modifier onlyExecutor() { 35 | require(msg.sender == executor); 36 | _; 37 | } 38 | 39 | modifier onlyOwner() { 40 | require(msg.sender == owner); 41 | _; 42 | } 43 | 44 | constructor(address _executor) public payable { 45 | owner = msg.sender; 46 | executor = _executor; 47 | if (msg.value > 0) { 48 | WETH.deposit{value: msg.value}(); 49 | } 50 | } 51 | 52 | receive() external payable { 53 | } 54 | 55 | function uniswapWeth(uint256 _wethAmountToFirstMarket, uint256 _ethAmountToCoinbase, address[] memory _targets, bytes[] memory _payloads) external onlyExecutor payable { 56 | require (_targets.length == _payloads.length); 57 | uint256 _wethBalanceBefore = WETH.balanceOf(address(this)); 58 | WETH.transfer(_targets[0], _wethAmountToFirstMarket); 59 | for (uint256 i = 0; i < _targets.length; i++) { 60 | (bool _success, bytes memory _response) = _targets[i].call(_payloads[i]); 61 | require(_success); _response; 62 | } 63 | 64 | uint256 _wethBalanceAfter = WETH.balanceOf(address(this)); 65 | require(_wethBalanceAfter > _wethBalanceBefore + _ethAmountToCoinbase); 66 | if (_ethAmountToCoinbase == 0) return; 67 | 68 | uint256 _ethBalance = address(this).balance; 69 | if (_ethBalance < _ethAmountToCoinbase) { 70 | WETH.withdraw(_ethAmountToCoinbase - _ethBalance); 71 | } 72 | block.coinbase.transfer(_ethAmountToCoinbase); 73 | } 74 | 75 | function call(address payable _to, uint256 _value, bytes calldata _data) external onlyOwner payable returns (bytes memory) { 76 | require(_to != address(0)); 77 | (bool _success, bytes memory _result) = _to.call{value: _value}(_data); 78 | require(_success); 79 | return _result; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /contracts/UniswapFlashQuery.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: UNLICENSED 2 | pragma solidity 0.6.12; 3 | 4 | pragma experimental ABIEncoderV2; 5 | 6 | interface IUniswapV2Pair { 7 | function token0() external view returns (address); 8 | function token1() external view returns (address); 9 | function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast); 10 | } 11 | 12 | abstract contract UniswapV2Factory { 13 | mapping(address => mapping(address => address)) public getPair; 14 | address[] public allPairs; 15 | function allPairsLength() external view virtual returns (uint); 16 | } 17 | 18 | // In order to quickly load up data from Uniswap-like market, this contract allows easy iteration with a single eth_call 19 | contract FlashBotsUniswapQuery { 20 | function getReservesByPairs(IUniswapV2Pair[] calldata _pairs) external view returns (uint256[3][] memory) { 21 | uint256[3][] memory result = new uint256[3][](_pairs.length); 22 | for (uint i = 0; i < _pairs.length; i++) { 23 | (result[i][0], result[i][1], result[i][2]) = _pairs[i].getReserves(); 24 | } 25 | return result; 26 | } 27 | 28 | function getPairsByIndexRange(UniswapV2Factory _uniswapFactory, uint256 _start, uint256 _stop) external view returns (address[3][] memory) { 29 | uint256 _allPairsLength = _uniswapFactory.allPairsLength(); 30 | if (_stop > _allPairsLength) { 31 | _stop = _allPairsLength; 32 | } 33 | require(_stop >= _start, "start cannot be higher than stop"); 34 | uint256 _qty = _stop - _start; 35 | address[3][] memory result = new address[3][](_qty); 36 | for (uint i = 0; i < _qty; i++) { 37 | IUniswapV2Pair _uniswapPair = IUniswapV2Pair(_uniswapFactory.allPairs(_start + i)); 38 | result[i][0] = _uniswapPair.token0(); 39 | result[i][1] = _uniswapPair.token1(); 40 | result[i][2] = address(_uniswapPair); 41 | } 42 | return result; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /jasmine.json: -------------------------------------------------------------------------------- 1 | { 2 | "spec_dir": "test", 3 | "spec_files": ["**/*[tT]est.ts"] 4 | } 5 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@flashbots/simple-arbitrage", 3 | "version": "0.0.1", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@babel/code-frame": { 8 | "version": "7.12.11", 9 | "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", 10 | "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", 11 | "dev": true, 12 | "requires": { 13 | "@babel/highlight": "^7.10.4" 14 | } 15 | }, 16 | "@babel/core": { 17 | "version": "7.12.10", 18 | "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.12.10.tgz", 19 | "integrity": "sha512-eTAlQKq65zHfkHZV0sIVODCPGVgoo1HdBlbSLi9CqOzuZanMv2ihzY+4paiKr1mH+XmYESMAmJ/dpZ68eN6d8w==", 20 | "dev": true, 21 | "requires": { 22 | "@babel/code-frame": "^7.10.4", 23 | "@babel/generator": "^7.12.10", 24 | "@babel/helper-module-transforms": "^7.12.1", 25 | "@babel/helpers": "^7.12.5", 26 | "@babel/parser": "^7.12.10", 27 | "@babel/template": "^7.12.7", 28 | "@babel/traverse": "^7.12.10", 29 | "@babel/types": "^7.12.10", 30 | "convert-source-map": "^1.7.0", 31 | "debug": "^4.1.0", 32 | "gensync": "^1.0.0-beta.1", 33 | "json5": "^2.1.2", 34 | "lodash": "^4.17.19", 35 | "semver": "^5.4.1", 36 | "source-map": "^0.5.0" 37 | }, 38 | "dependencies": { 39 | "semver": { 40 | "version": "5.7.1", 41 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", 42 | "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", 43 | "dev": true 44 | }, 45 | "source-map": { 46 | "version": "0.5.7", 47 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", 48 | "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", 49 | "dev": true 50 | } 51 | } 52 | }, 53 | "@babel/generator": { 54 | "version": "7.12.11", 55 | "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.11.tgz", 56 | "integrity": "sha512-Ggg6WPOJtSi8yYQvLVjG8F/TlpWDlKx0OpS4Kt+xMQPs5OaGYWy+v1A+1TvxI6sAMGZpKWWoAQ1DaeQbImlItA==", 57 | "dev": true, 58 | "requires": { 59 | "@babel/types": "^7.12.11", 60 | "jsesc": "^2.5.1", 61 | "source-map": "^0.5.0" 62 | }, 63 | "dependencies": { 64 | "source-map": { 65 | "version": "0.5.7", 66 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", 67 | "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", 68 | "dev": true 69 | } 70 | } 71 | }, 72 | "@babel/helper-function-name": { 73 | "version": "7.12.11", 74 | "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.11.tgz", 75 | "integrity": "sha512-AtQKjtYNolKNi6nNNVLQ27CP6D9oFR6bq/HPYSizlzbp7uC1M59XJe8L+0uXjbIaZaUJF99ruHqVGiKXU/7ybA==", 76 | "dev": true, 77 | "requires": { 78 | "@babel/helper-get-function-arity": "^7.12.10", 79 | "@babel/template": "^7.12.7", 80 | "@babel/types": "^7.12.11" 81 | } 82 | }, 83 | "@babel/helper-get-function-arity": { 84 | "version": "7.12.10", 85 | "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.10.tgz", 86 | "integrity": "sha512-mm0n5BPjR06wh9mPQaDdXWDoll/j5UpCAPl1x8fS71GHm7HA6Ua2V4ylG1Ju8lvcTOietbPNNPaSilKj+pj+Ag==", 87 | "dev": true, 88 | "requires": { 89 | "@babel/types": "^7.12.10" 90 | } 91 | }, 92 | "@babel/helper-member-expression-to-functions": { 93 | "version": "7.12.7", 94 | "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.7.tgz", 95 | "integrity": "sha512-DCsuPyeWxeHgh1Dus7APn7iza42i/qXqiFPWyBDdOFtvS581JQePsc1F/nD+fHrcswhLlRc2UpYS1NwERxZhHw==", 96 | "dev": true, 97 | "requires": { 98 | "@babel/types": "^7.12.7" 99 | } 100 | }, 101 | "@babel/helper-module-imports": { 102 | "version": "7.12.5", 103 | "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.12.5.tgz", 104 | "integrity": "sha512-SR713Ogqg6++uexFRORf/+nPXMmWIn80TALu0uaFb+iQIUoR7bOC7zBWyzBs5b3tBBJXuyD0cRu1F15GyzjOWA==", 105 | "dev": true, 106 | "requires": { 107 | "@babel/types": "^7.12.5" 108 | } 109 | }, 110 | "@babel/helper-module-transforms": { 111 | "version": "7.12.1", 112 | "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.12.1.tgz", 113 | "integrity": "sha512-QQzehgFAZ2bbISiCpmVGfiGux8YVFXQ0abBic2Envhej22DVXV9nCFaS5hIQbkyo1AdGb+gNME2TSh3hYJVV/w==", 114 | "dev": true, 115 | "requires": { 116 | "@babel/helper-module-imports": "^7.12.1", 117 | "@babel/helper-replace-supers": "^7.12.1", 118 | "@babel/helper-simple-access": "^7.12.1", 119 | "@babel/helper-split-export-declaration": "^7.11.0", 120 | "@babel/helper-validator-identifier": "^7.10.4", 121 | "@babel/template": "^7.10.4", 122 | "@babel/traverse": "^7.12.1", 123 | "@babel/types": "^7.12.1", 124 | "lodash": "^4.17.19" 125 | } 126 | }, 127 | "@babel/helper-optimise-call-expression": { 128 | "version": "7.12.10", 129 | "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.10.tgz", 130 | "integrity": "sha512-4tpbU0SrSTjjt65UMWSrUOPZTsgvPgGG4S8QSTNHacKzpS51IVWGDj0yCwyeZND/i+LSN2g/O63jEXEWm49sYQ==", 131 | "dev": true, 132 | "requires": { 133 | "@babel/types": "^7.12.10" 134 | } 135 | }, 136 | "@babel/helper-replace-supers": { 137 | "version": "7.12.11", 138 | "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.11.tgz", 139 | "integrity": "sha512-q+w1cqmhL7R0FNzth/PLLp2N+scXEK/L2AHbXUyydxp828F4FEa5WcVoqui9vFRiHDQErj9Zof8azP32uGVTRA==", 140 | "dev": true, 141 | "requires": { 142 | "@babel/helper-member-expression-to-functions": "^7.12.7", 143 | "@babel/helper-optimise-call-expression": "^7.12.10", 144 | "@babel/traverse": "^7.12.10", 145 | "@babel/types": "^7.12.11" 146 | } 147 | }, 148 | "@babel/helper-simple-access": { 149 | "version": "7.12.1", 150 | "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.12.1.tgz", 151 | "integrity": "sha512-OxBp7pMrjVewSSC8fXDFrHrBcJATOOFssZwv16F3/6Xtc138GHybBfPbm9kfiqQHKhYQrlamWILwlDCeyMFEaA==", 152 | "dev": true, 153 | "requires": { 154 | "@babel/types": "^7.12.1" 155 | } 156 | }, 157 | "@babel/helper-split-export-declaration": { 158 | "version": "7.12.11", 159 | "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.11.tgz", 160 | "integrity": "sha512-LsIVN8j48gHgwzfocYUSkO/hjYAOJqlpJEc7tGXcIm4cubjVUf8LGW6eWRyxEu7gA25q02p0rQUWoCI33HNS5g==", 161 | "dev": true, 162 | "requires": { 163 | "@babel/types": "^7.12.11" 164 | } 165 | }, 166 | "@babel/helper-validator-identifier": { 167 | "version": "7.12.11", 168 | "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", 169 | "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", 170 | "dev": true 171 | }, 172 | "@babel/helpers": { 173 | "version": "7.12.5", 174 | "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.12.5.tgz", 175 | "integrity": "sha512-lgKGMQlKqA8meJqKsW6rUnc4MdUk35Ln0ATDqdM1a/UpARODdI4j5Y5lVfUScnSNkJcdCRAaWkspykNoFg9sJA==", 176 | "dev": true, 177 | "requires": { 178 | "@babel/template": "^7.10.4", 179 | "@babel/traverse": "^7.12.5", 180 | "@babel/types": "^7.12.5" 181 | } 182 | }, 183 | "@babel/highlight": { 184 | "version": "7.10.4", 185 | "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", 186 | "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", 187 | "dev": true, 188 | "requires": { 189 | "@babel/helper-validator-identifier": "^7.10.4", 190 | "chalk": "^2.0.0", 191 | "js-tokens": "^4.0.0" 192 | }, 193 | "dependencies": { 194 | "chalk": { 195 | "version": "2.4.2", 196 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", 197 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", 198 | "dev": true, 199 | "requires": { 200 | "ansi-styles": "^3.2.1", 201 | "escape-string-regexp": "^1.0.5", 202 | "supports-color": "^5.3.0" 203 | } 204 | } 205 | } 206 | }, 207 | "@babel/parser": { 208 | "version": "7.12.11", 209 | "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.11.tgz", 210 | "integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==", 211 | "dev": true 212 | }, 213 | "@babel/template": { 214 | "version": "7.12.7", 215 | "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.7.tgz", 216 | "integrity": "sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow==", 217 | "dev": true, 218 | "requires": { 219 | "@babel/code-frame": "^7.10.4", 220 | "@babel/parser": "^7.12.7", 221 | "@babel/types": "^7.12.7" 222 | } 223 | }, 224 | "@babel/traverse": { 225 | "version": "7.12.12", 226 | "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.12.tgz", 227 | "integrity": "sha512-s88i0X0lPy45RrLM8b9mz8RPH5FqO9G9p7ti59cToE44xFm1Q+Pjh5Gq4SXBbtb88X7Uy7pexeqRIQDDMNkL0w==", 228 | "dev": true, 229 | "requires": { 230 | "@babel/code-frame": "^7.12.11", 231 | "@babel/generator": "^7.12.11", 232 | "@babel/helper-function-name": "^7.12.11", 233 | "@babel/helper-split-export-declaration": "^7.12.11", 234 | "@babel/parser": "^7.12.11", 235 | "@babel/types": "^7.12.12", 236 | "debug": "^4.1.0", 237 | "globals": "^11.1.0", 238 | "lodash": "^4.17.19" 239 | }, 240 | "dependencies": { 241 | "globals": { 242 | "version": "11.12.0", 243 | "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", 244 | "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", 245 | "dev": true 246 | } 247 | } 248 | }, 249 | "@babel/types": { 250 | "version": "7.12.12", 251 | "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", 252 | "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", 253 | "dev": true, 254 | "requires": { 255 | "@babel/helper-validator-identifier": "^7.12.11", 256 | "lodash": "^4.17.19", 257 | "to-fast-properties": "^2.0.0" 258 | } 259 | }, 260 | "@eslint/eslintrc": { 261 | "version": "0.2.2", 262 | "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.2.2.tgz", 263 | "integrity": "sha512-EfB5OHNYp1F4px/LI/FEnGylop7nOqkQ1LRzCM0KccA2U8tvV8w01KBv37LbO7nW4H+YhKyo2LcJhRwjjV17QQ==", 264 | "dev": true, 265 | "requires": { 266 | "ajv": "^6.12.4", 267 | "debug": "^4.1.1", 268 | "espree": "^7.3.0", 269 | "globals": "^12.1.0", 270 | "ignore": "^4.0.6", 271 | "import-fresh": "^3.2.1", 272 | "js-yaml": "^3.13.1", 273 | "lodash": "^4.17.19", 274 | "minimatch": "^3.0.4", 275 | "strip-json-comments": "^3.1.1" 276 | }, 277 | "dependencies": { 278 | "ignore": { 279 | "version": "4.0.6", 280 | "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", 281 | "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", 282 | "dev": true 283 | } 284 | } 285 | }, 286 | "@ethersproject/abi": { 287 | "version": "5.0.9", 288 | "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.0.9.tgz", 289 | "integrity": "sha512-ily2OufA2DTrxkiHQw5GqbkMSnNKuwZBqKsajtT0ERhZy1r9w2CpW1bmtRMIGzaqQxCdn/GEoFogexk72cBBZQ==", 290 | "dev": true, 291 | "requires": { 292 | "@ethersproject/address": "^5.0.4", 293 | "@ethersproject/bignumber": "^5.0.7", 294 | "@ethersproject/bytes": "^5.0.4", 295 | "@ethersproject/constants": "^5.0.4", 296 | "@ethersproject/hash": "^5.0.4", 297 | "@ethersproject/keccak256": "^5.0.3", 298 | "@ethersproject/logger": "^5.0.5", 299 | "@ethersproject/properties": "^5.0.3", 300 | "@ethersproject/strings": "^5.0.4" 301 | } 302 | }, 303 | "@ethersproject/abstract-provider": { 304 | "version": "5.0.7", 305 | "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.0.7.tgz", 306 | "integrity": "sha512-NF16JGn6M0zZP5ZS8KtDL2Rh7yHxZbUjBIHLNHMm/0X0BephhjUWy8jqs/Zks6kDJRzNthgmPVy41Ec0RYWPYA==", 307 | "dev": true, 308 | "requires": { 309 | "@ethersproject/bignumber": "^5.0.7", 310 | "@ethersproject/bytes": "^5.0.4", 311 | "@ethersproject/logger": "^5.0.5", 312 | "@ethersproject/networks": "^5.0.3", 313 | "@ethersproject/properties": "^5.0.3", 314 | "@ethersproject/transactions": "^5.0.5", 315 | "@ethersproject/web": "^5.0.6" 316 | } 317 | }, 318 | "@ethersproject/abstract-signer": { 319 | "version": "5.0.9", 320 | "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.0.9.tgz", 321 | "integrity": "sha512-CM5UNmXQaA03MyYARFDDRjHWBxujO41tVle7glf5kHcQsDDULgqSVpkliLJMtPzZjOKFeCVZBHybTZDEZg5zzg==", 322 | "dev": true, 323 | "requires": { 324 | "@ethersproject/abstract-provider": "^5.0.4", 325 | "@ethersproject/bignumber": "^5.0.7", 326 | "@ethersproject/bytes": "^5.0.4", 327 | "@ethersproject/logger": "^5.0.5", 328 | "@ethersproject/properties": "^5.0.3" 329 | } 330 | }, 331 | "@ethersproject/address": { 332 | "version": "5.0.8", 333 | "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.0.8.tgz", 334 | "integrity": "sha512-V87DHiZMZR6hmFYmoGaHex0D53UEbZpW75uj8AqPbjYUmi65RB4N2LPRcJXuWuN2R0Y2CxkvW6ArijWychr5FA==", 335 | "dev": true, 336 | "requires": { 337 | "@ethersproject/bignumber": "^5.0.10", 338 | "@ethersproject/bytes": "^5.0.4", 339 | "@ethersproject/keccak256": "^5.0.3", 340 | "@ethersproject/logger": "^5.0.5", 341 | "@ethersproject/rlp": "^5.0.3" 342 | } 343 | }, 344 | "@ethersproject/base64": { 345 | "version": "5.0.6", 346 | "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.0.6.tgz", 347 | "integrity": "sha512-HwrGn8YMiUf7bcdVvB4NJ+eWT0BtEFpDtrYxVXEbR7p/XBSJjwiR7DEggIiRvxbualMKg+EZijQWJ3az2li0uw==", 348 | "dev": true, 349 | "requires": { 350 | "@ethersproject/bytes": "^5.0.4" 351 | } 352 | }, 353 | "@ethersproject/basex": { 354 | "version": "5.0.6", 355 | "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.0.6.tgz", 356 | "integrity": "sha512-Y/8dowRxBF3bsKkqEp7XN4kcFFQ0o5xxP1YyopfqkXejaOEGiD7ToQdQ0pIZpAJ5GreW56oFOTDDSO6ZcUCNYg==", 357 | "dev": true, 358 | "requires": { 359 | "@ethersproject/bytes": "^5.0.4", 360 | "@ethersproject/properties": "^5.0.3" 361 | } 362 | }, 363 | "@ethersproject/bignumber": { 364 | "version": "5.0.12", 365 | "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.0.12.tgz", 366 | "integrity": "sha512-mbFZjwthx6vFlHG9owXP/C5QkNvsA+xHpDCkPPPdG2n1dS9AmZAL5DI0InNLid60rQWL3MXpEl19tFmtL7Q9jw==", 367 | "dev": true, 368 | "requires": { 369 | "@ethersproject/bytes": "^5.0.8", 370 | "@ethersproject/logger": "^5.0.5", 371 | "bn.js": "^4.4.0" 372 | } 373 | }, 374 | "@ethersproject/bytes": { 375 | "version": "5.0.8", 376 | "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.0.8.tgz", 377 | "integrity": "sha512-O+sJNVGzzuy51g+EMK8BegomqNIg+C2RO6vOt0XP6ac4o4saiq69FnjlsrNslaiMFVO7qcEHBsWJ9hx1tj1lMw==", 378 | "dev": true, 379 | "requires": { 380 | "@ethersproject/logger": "^5.0.5" 381 | } 382 | }, 383 | "@ethersproject/constants": { 384 | "version": "5.0.7", 385 | "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.0.7.tgz", 386 | "integrity": "sha512-cbQK1UpE4hamB52Eg6DLhJoXeQ1plSzekh5Ujir1xdREdwdsZPPXKczkrWqBBR0KyywJZHN/o/hj0w8j7scSGg==", 387 | "dev": true, 388 | "requires": { 389 | "@ethersproject/bignumber": "^5.0.7" 390 | } 391 | }, 392 | "@ethersproject/contracts": { 393 | "version": "5.0.8", 394 | "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.0.8.tgz", 395 | "integrity": "sha512-PecBL4vnsrpuks2lzzkRsOts8csJy338HNDKDIivbFmx92BVzh3ohOOv3XsoYPSXIHQvobF959W+aSk3RCZL/g==", 396 | "dev": true, 397 | "requires": { 398 | "@ethersproject/abi": "^5.0.5", 399 | "@ethersproject/abstract-provider": "^5.0.4", 400 | "@ethersproject/abstract-signer": "^5.0.4", 401 | "@ethersproject/address": "^5.0.4", 402 | "@ethersproject/bignumber": "^5.0.7", 403 | "@ethersproject/bytes": "^5.0.4", 404 | "@ethersproject/constants": "^5.0.4", 405 | "@ethersproject/logger": "^5.0.5", 406 | "@ethersproject/properties": "^5.0.3" 407 | } 408 | }, 409 | "@ethersproject/hash": { 410 | "version": "5.0.9", 411 | "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.0.9.tgz", 412 | "integrity": "sha512-e8/i2ZDeGSgCxXT0vocL54+pMbw5oX5fNjb2E3bAIvdkh5kH29M7zz1jHu1QDZnptIuvCZepIbhUH8lxKE2/SQ==", 413 | "dev": true, 414 | "requires": { 415 | "@ethersproject/abstract-signer": "^5.0.6", 416 | "@ethersproject/address": "^5.0.5", 417 | "@ethersproject/bignumber": "^5.0.8", 418 | "@ethersproject/bytes": "^5.0.4", 419 | "@ethersproject/keccak256": "^5.0.3", 420 | "@ethersproject/logger": "^5.0.5", 421 | "@ethersproject/properties": "^5.0.4", 422 | "@ethersproject/strings": "^5.0.4" 423 | } 424 | }, 425 | "@ethersproject/hdnode": { 426 | "version": "5.0.7", 427 | "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.0.7.tgz", 428 | "integrity": "sha512-89tphqlji4y/LNE1cSaMQ3hrBtJ4lO1qWGi2hn54LiHym85DTw+zAKbA8QgmdSdJDLGR/kc9VHaIPQ+vZQ2LkQ==", 429 | "dev": true, 430 | "requires": { 431 | "@ethersproject/abstract-signer": "^5.0.4", 432 | "@ethersproject/basex": "^5.0.3", 433 | "@ethersproject/bignumber": "^5.0.7", 434 | "@ethersproject/bytes": "^5.0.4", 435 | "@ethersproject/logger": "^5.0.5", 436 | "@ethersproject/pbkdf2": "^5.0.3", 437 | "@ethersproject/properties": "^5.0.3", 438 | "@ethersproject/sha2": "^5.0.3", 439 | "@ethersproject/signing-key": "^5.0.4", 440 | "@ethersproject/strings": "^5.0.4", 441 | "@ethersproject/transactions": "^5.0.5", 442 | "@ethersproject/wordlists": "^5.0.4" 443 | } 444 | }, 445 | "@ethersproject/json-wallets": { 446 | "version": "5.0.9", 447 | "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.0.9.tgz", 448 | "integrity": "sha512-EWuFvJd8nu90dkmJwmJddxOYCvFvMkKBsZi8rxTme2XEZsHKOFnybVkoL23u7ZtApuEfTKmVcR2PTwgZwqDsKw==", 449 | "dev": true, 450 | "requires": { 451 | "@ethersproject/abstract-signer": "^5.0.4", 452 | "@ethersproject/address": "^5.0.4", 453 | "@ethersproject/bytes": "^5.0.4", 454 | "@ethersproject/hdnode": "^5.0.4", 455 | "@ethersproject/keccak256": "^5.0.3", 456 | "@ethersproject/logger": "^5.0.5", 457 | "@ethersproject/pbkdf2": "^5.0.3", 458 | "@ethersproject/properties": "^5.0.3", 459 | "@ethersproject/random": "^5.0.3", 460 | "@ethersproject/strings": "^5.0.4", 461 | "@ethersproject/transactions": "^5.0.5", 462 | "aes-js": "3.0.0", 463 | "scrypt-js": "3.0.1" 464 | } 465 | }, 466 | "@ethersproject/keccak256": { 467 | "version": "5.0.6", 468 | "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.0.6.tgz", 469 | "integrity": "sha512-eJ4Id/i2rwrf5JXEA7a12bG1phuxjj47mPZgDUbttuNBodhSuZF2nEO5QdpaRjmlphQ8Kt9PNqY/z7lhtJptZg==", 470 | "dev": true, 471 | "requires": { 472 | "@ethersproject/bytes": "^5.0.4", 473 | "js-sha3": "0.5.7" 474 | } 475 | }, 476 | "@ethersproject/logger": { 477 | "version": "5.0.8", 478 | "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.0.8.tgz", 479 | "integrity": "sha512-SkJCTaVTnaZ3/ieLF5pVftxGEFX56pTH+f2Slrpv7cU0TNpUZNib84QQdukd++sWUp/S7j5t5NW+WegbXd4U/A==", 480 | "dev": true 481 | }, 482 | "@ethersproject/networks": { 483 | "version": "5.0.6", 484 | "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.0.6.tgz", 485 | "integrity": "sha512-2Cg1N5109zzFOBfkyuPj+FfF7ioqAsRffmybJ2lrsiB5skphIAE72XNSCs4fqktlf+rwSh/5o/UXRjXxvSktZw==", 486 | "dev": true, 487 | "requires": { 488 | "@ethersproject/logger": "^5.0.5" 489 | } 490 | }, 491 | "@ethersproject/pbkdf2": { 492 | "version": "5.0.6", 493 | "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.0.6.tgz", 494 | "integrity": "sha512-CUYciSxR/AaCoKMJk3WUW+BDhR41G3C+O9lOeZ4bR1wDhLKL2Z8p0ciF5XDEiVbmI4CToW6boVKybeVMdngRrg==", 495 | "dev": true, 496 | "requires": { 497 | "@ethersproject/bytes": "^5.0.4", 498 | "@ethersproject/sha2": "^5.0.3" 499 | } 500 | }, 501 | "@ethersproject/properties": { 502 | "version": "5.0.6", 503 | "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.0.6.tgz", 504 | "integrity": "sha512-a9DUMizYhJ0TbtuDkO9iYlb2CDlpSKqGPDr+amvlZhRspQ6jbl5Eq8jfu4SCcGlcfaTbguJmqGnyOGn1EFt6xA==", 505 | "dev": true, 506 | "requires": { 507 | "@ethersproject/logger": "^5.0.5" 508 | } 509 | }, 510 | "@ethersproject/providers": { 511 | "version": "5.0.17", 512 | "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.0.17.tgz", 513 | "integrity": "sha512-bJnvs5X7ttU5x2ekGJYG7R3Z+spZawLFfR0IDsbaMDLiCwZOyrgk+VTBU7amSFLT0WUhWFv8WwSUB+AryCQG1Q==", 514 | "dev": true, 515 | "requires": { 516 | "@ethersproject/abstract-provider": "^5.0.4", 517 | "@ethersproject/abstract-signer": "^5.0.4", 518 | "@ethersproject/address": "^5.0.4", 519 | "@ethersproject/basex": "^5.0.3", 520 | "@ethersproject/bignumber": "^5.0.7", 521 | "@ethersproject/bytes": "^5.0.4", 522 | "@ethersproject/constants": "^5.0.4", 523 | "@ethersproject/hash": "^5.0.4", 524 | "@ethersproject/logger": "^5.0.5", 525 | "@ethersproject/networks": "^5.0.3", 526 | "@ethersproject/properties": "^5.0.3", 527 | "@ethersproject/random": "^5.0.3", 528 | "@ethersproject/rlp": "^5.0.3", 529 | "@ethersproject/sha2": "^5.0.3", 530 | "@ethersproject/strings": "^5.0.4", 531 | "@ethersproject/transactions": "^5.0.5", 532 | "@ethersproject/web": "^5.0.6", 533 | "bech32": "1.1.4", 534 | "ws": "7.2.3" 535 | } 536 | }, 537 | "@ethersproject/random": { 538 | "version": "5.0.6", 539 | "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.0.6.tgz", 540 | "integrity": "sha512-8nsVNaZvZ9OD5NXfzE4mmz8IH/1DYJbAR95xpRxZkIuNmfn6QlMp49ccJYZWGhs6m0Zj2+FXjx3pzXfYlo9/dA==", 541 | "dev": true, 542 | "requires": { 543 | "@ethersproject/bytes": "^5.0.4", 544 | "@ethersproject/logger": "^5.0.5" 545 | } 546 | }, 547 | "@ethersproject/rlp": { 548 | "version": "5.0.6", 549 | "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.0.6.tgz", 550 | "integrity": "sha512-M223MTaydfmQSsvqAl0FJZDYFlSqt6cgbhnssLDwqCKYegAHE16vrFyo+eiOapYlt32XAIJm0BXlqSunULzZuQ==", 551 | "dev": true, 552 | "requires": { 553 | "@ethersproject/bytes": "^5.0.4", 554 | "@ethersproject/logger": "^5.0.5" 555 | } 556 | }, 557 | "@ethersproject/sha2": { 558 | "version": "5.0.6", 559 | "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.0.6.tgz", 560 | "integrity": "sha512-30gypDLkfkP5gE3llqi0jEuRV8m4/nvzeqmqMxiihZ7veFQHqDaGpyFeHzFim+qGeH9fq0lgYjavLvwW69+Fkw==", 561 | "dev": true, 562 | "requires": { 563 | "@ethersproject/bytes": "^5.0.4", 564 | "@ethersproject/logger": "^5.0.5", 565 | "hash.js": "1.1.3" 566 | }, 567 | "dependencies": { 568 | "hash.js": { 569 | "version": "1.1.3", 570 | "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz", 571 | "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==", 572 | "dev": true, 573 | "requires": { 574 | "inherits": "^2.0.3", 575 | "minimalistic-assert": "^1.0.0" 576 | } 577 | } 578 | } 579 | }, 580 | "@ethersproject/signing-key": { 581 | "version": "5.0.7", 582 | "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.0.7.tgz", 583 | "integrity": "sha512-JYndnhFPKH0daPcIjyhi+GMcw3srIHkQ40hGRe6DA0CdGrpMfgyfSYDQ2D8HL2lgR+Xm4SHfEB0qba6+sCyrvg==", 584 | "dev": true, 585 | "requires": { 586 | "@ethersproject/bytes": "^5.0.4", 587 | "@ethersproject/logger": "^5.0.5", 588 | "@ethersproject/properties": "^5.0.3", 589 | "elliptic": "6.5.3" 590 | } 591 | }, 592 | "@ethersproject/solidity": { 593 | "version": "5.0.7", 594 | "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.0.7.tgz", 595 | "integrity": "sha512-dUevKUZ06p/VMLP/+cz4QUV+lA17NixucDJfm0ioWF0B3R0Lf+6wqwPchcqiAXlxkNFGIax7WNLgGMh4CkQ8iw==", 596 | "dev": true, 597 | "requires": { 598 | "@ethersproject/bignumber": "^5.0.7", 599 | "@ethersproject/bytes": "^5.0.4", 600 | "@ethersproject/keccak256": "^5.0.3", 601 | "@ethersproject/sha2": "^5.0.3", 602 | "@ethersproject/strings": "^5.0.4" 603 | } 604 | }, 605 | "@ethersproject/strings": { 606 | "version": "5.0.7", 607 | "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.0.7.tgz", 608 | "integrity": "sha512-a+6T80LvmXGMOOWQTZHtGGQEg1z4v8rm8oX70KNs55YtPXI/5J3LBbVf5pyqCKSlmiBw5IaepPvs5XGalRUSZQ==", 609 | "dev": true, 610 | "requires": { 611 | "@ethersproject/bytes": "^5.0.4", 612 | "@ethersproject/constants": "^5.0.4", 613 | "@ethersproject/logger": "^5.0.5" 614 | } 615 | }, 616 | "@ethersproject/transactions": { 617 | "version": "5.0.8", 618 | "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.0.8.tgz", 619 | "integrity": "sha512-i7NtOXVzUe+YSU6QufzlRrI2WzHaTmULAKHJv4duIZMLqzehCBXGA9lTpFgFdqGYcQJ7vOtNFC2BB2mSjmuXqg==", 620 | "dev": true, 621 | "requires": { 622 | "@ethersproject/address": "^5.0.4", 623 | "@ethersproject/bignumber": "^5.0.7", 624 | "@ethersproject/bytes": "^5.0.4", 625 | "@ethersproject/constants": "^5.0.4", 626 | "@ethersproject/keccak256": "^5.0.3", 627 | "@ethersproject/logger": "^5.0.5", 628 | "@ethersproject/properties": "^5.0.3", 629 | "@ethersproject/rlp": "^5.0.3", 630 | "@ethersproject/signing-key": "^5.0.4" 631 | } 632 | }, 633 | "@ethersproject/units": { 634 | "version": "5.0.8", 635 | "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.0.8.tgz", 636 | "integrity": "sha512-3O4MaNHFs05vC5v2ZGqVFVWtO1WyqFejO78M7Qh16njo282aoMlENtVI6cn2B36zOLFXRvYt2pYx6xCG53qKzg==", 637 | "dev": true, 638 | "requires": { 639 | "@ethersproject/bignumber": "^5.0.7", 640 | "@ethersproject/constants": "^5.0.4", 641 | "@ethersproject/logger": "^5.0.5" 642 | } 643 | }, 644 | "@ethersproject/wallet": { 645 | "version": "5.0.9", 646 | "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.0.9.tgz", 647 | "integrity": "sha512-GfpQF56PO/945SJq7Wdg5F5U6wkxaDgkAzcgGbCW6Joz8oW8MzKItkvYCzMh+j/8gJMzFncsuqX4zg2gq3J6nQ==", 648 | "dev": true, 649 | "requires": { 650 | "@ethersproject/abstract-provider": "^5.0.4", 651 | "@ethersproject/abstract-signer": "^5.0.4", 652 | "@ethersproject/address": "^5.0.4", 653 | "@ethersproject/bignumber": "^5.0.7", 654 | "@ethersproject/bytes": "^5.0.4", 655 | "@ethersproject/hash": "^5.0.4", 656 | "@ethersproject/hdnode": "^5.0.4", 657 | "@ethersproject/json-wallets": "^5.0.6", 658 | "@ethersproject/keccak256": "^5.0.3", 659 | "@ethersproject/logger": "^5.0.5", 660 | "@ethersproject/properties": "^5.0.3", 661 | "@ethersproject/random": "^5.0.3", 662 | "@ethersproject/signing-key": "^5.0.4", 663 | "@ethersproject/transactions": "^5.0.5", 664 | "@ethersproject/wordlists": "^5.0.4" 665 | } 666 | }, 667 | "@ethersproject/web": { 668 | "version": "5.0.11", 669 | "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.0.11.tgz", 670 | "integrity": "sha512-x03ihbPoN1S8Gsh9WSwxkYxUIumLi02ZEKJku1C43sxBfe+mdprWyvujzYlpuoRNfWRgNhdRDKMP8JbG6MwNGA==", 671 | "dev": true, 672 | "requires": { 673 | "@ethersproject/base64": "^5.0.3", 674 | "@ethersproject/bytes": "^5.0.4", 675 | "@ethersproject/logger": "^5.0.5", 676 | "@ethersproject/properties": "^5.0.3", 677 | "@ethersproject/strings": "^5.0.4" 678 | } 679 | }, 680 | "@ethersproject/wordlists": { 681 | "version": "5.0.7", 682 | "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.0.7.tgz", 683 | "integrity": "sha512-ZjQtYxm41FmHfYgpkdQG++EDcBPQWv9O6FfP6NndYRVaXaQZh6eq3sy7HQP8zCZ8dznKgy6ZyKECS8qdvnGHwA==", 684 | "dev": true, 685 | "requires": { 686 | "@ethersproject/bytes": "^5.0.4", 687 | "@ethersproject/hash": "^5.0.4", 688 | "@ethersproject/logger": "^5.0.5", 689 | "@ethersproject/properties": "^5.0.3", 690 | "@ethersproject/strings": "^5.0.4" 691 | } 692 | }, 693 | "@flashbots/ethers-provider-bundle": { 694 | "version": "0.3.1", 695 | "resolved": "https://registry.npmjs.org/@flashbots/ethers-provider-bundle/-/ethers-provider-bundle-0.3.1.tgz", 696 | "integrity": "sha512-wCeRcwD3cYJ1jxWFy1e8bELeI9rVoFF5zRQLeu4+owAL6N7ZBwJJESJRX+jSMOTCKfldNHxOkkmgqJ+ZxX6iuA==", 697 | "requires": { 698 | "ts-node": "^9.1.0", 699 | "typescript": "^4.1.2" 700 | } 701 | }, 702 | "@istanbuljs/load-nyc-config": { 703 | "version": "1.1.0", 704 | "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", 705 | "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", 706 | "dev": true, 707 | "requires": { 708 | "camelcase": "^5.3.1", 709 | "find-up": "^4.1.0", 710 | "get-package-type": "^0.1.0", 711 | "js-yaml": "^3.13.1", 712 | "resolve-from": "^5.0.0" 713 | }, 714 | "dependencies": { 715 | "resolve-from": { 716 | "version": "5.0.0", 717 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", 718 | "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", 719 | "dev": true 720 | } 721 | } 722 | }, 723 | "@istanbuljs/schema": { 724 | "version": "0.1.2", 725 | "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.2.tgz", 726 | "integrity": "sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==", 727 | "dev": true 728 | }, 729 | "@nodelib/fs.scandir": { 730 | "version": "2.1.3", 731 | "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz", 732 | "integrity": "sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==", 733 | "dev": true, 734 | "requires": { 735 | "@nodelib/fs.stat": "2.0.3", 736 | "run-parallel": "^1.1.9" 737 | } 738 | }, 739 | "@nodelib/fs.stat": { 740 | "version": "2.0.3", 741 | "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz", 742 | "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==", 743 | "dev": true 744 | }, 745 | "@nodelib/fs.walk": { 746 | "version": "1.2.4", 747 | "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz", 748 | "integrity": "sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==", 749 | "dev": true, 750 | "requires": { 751 | "@nodelib/fs.scandir": "2.1.3", 752 | "fastq": "^1.6.0" 753 | } 754 | }, 755 | "@types/jasmine": { 756 | "version": "3.6.2", 757 | "resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-3.6.2.tgz", 758 | "integrity": "sha512-AzfesNFLvOs6Q1mHzIsVJXSeUnqVh4ZHG8ngygKJfbkcSLwzrBVm/LKa+mR8KrOfnWtUL47112gde1MC0IXqpQ==", 759 | "dev": true 760 | }, 761 | "@types/json-schema": { 762 | "version": "7.0.6", 763 | "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.6.tgz", 764 | "integrity": "sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw==", 765 | "dev": true 766 | }, 767 | "@types/lodash": { 768 | "version": "4.14.165", 769 | "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.165.tgz", 770 | "integrity": "sha512-tjSSOTHhI5mCHTy/OOXYIhi2Wt1qcbHmuXD1Ha7q70CgI/I71afO4XtLb/cVexki1oVYchpul/TOuu3Arcdxrg==", 771 | "dev": true 772 | }, 773 | "@types/node": { 774 | "version": "14.14.14", 775 | "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.14.tgz", 776 | "integrity": "sha512-UHnOPWVWV1z+VV8k6L1HhG7UbGBgIdghqF3l9Ny9ApPghbjICXkUJSd/b9gOgQfjM1r+37cipdw/HJ3F6ICEnQ==", 777 | "dev": true 778 | }, 779 | "@typescript-eslint/eslint-plugin": { 780 | "version": "4.10.0", 781 | "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.10.0.tgz", 782 | "integrity": "sha512-h6/V46o6aXpKRlarP1AiJEXuCJ7cMQdlpfMDrcllIgX3dFkLwEBTXAoNP98ZoOmqd1xvymMVRAI4e7yVvlzWEg==", 783 | "dev": true, 784 | "requires": { 785 | "@typescript-eslint/experimental-utils": "4.10.0", 786 | "@typescript-eslint/scope-manager": "4.10.0", 787 | "debug": "^4.1.1", 788 | "functional-red-black-tree": "^1.0.1", 789 | "regexpp": "^3.0.0", 790 | "semver": "^7.3.2", 791 | "tsutils": "^3.17.1" 792 | } 793 | }, 794 | "@typescript-eslint/experimental-utils": { 795 | "version": "4.10.0", 796 | "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.10.0.tgz", 797 | "integrity": "sha512-opX+7ai1sdWBOIoBgpVJrH5e89ra1KoLrJTz0UtWAa4IekkKmqDosk5r6xqRaNJfCXEfteW4HXQAwMdx+jjEmw==", 798 | "dev": true, 799 | "requires": { 800 | "@types/json-schema": "^7.0.3", 801 | "@typescript-eslint/scope-manager": "4.10.0", 802 | "@typescript-eslint/types": "4.10.0", 803 | "@typescript-eslint/typescript-estree": "4.10.0", 804 | "eslint-scope": "^5.0.0", 805 | "eslint-utils": "^2.0.0" 806 | } 807 | }, 808 | "@typescript-eslint/parser": { 809 | "version": "4.10.0", 810 | "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.10.0.tgz", 811 | "integrity": "sha512-amBvUUGBMadzCW6c/qaZmfr3t9PyevcSWw7hY2FuevdZVp5QPw/K76VSQ5Sw3BxlgYCHZcK6DjIhSZK0PQNsQg==", 812 | "dev": true, 813 | "requires": { 814 | "@typescript-eslint/scope-manager": "4.10.0", 815 | "@typescript-eslint/types": "4.10.0", 816 | "@typescript-eslint/typescript-estree": "4.10.0", 817 | "debug": "^4.1.1" 818 | } 819 | }, 820 | "@typescript-eslint/scope-manager": { 821 | "version": "4.10.0", 822 | "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.10.0.tgz", 823 | "integrity": "sha512-WAPVw35P+fcnOa8DEic0tQUhoJJsgt+g6DEcz257G7vHFMwmag58EfowdVbiNcdfcV27EFR0tUBVXkDoIvfisQ==", 824 | "dev": true, 825 | "requires": { 826 | "@typescript-eslint/types": "4.10.0", 827 | "@typescript-eslint/visitor-keys": "4.10.0" 828 | } 829 | }, 830 | "@typescript-eslint/types": { 831 | "version": "4.10.0", 832 | "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.10.0.tgz", 833 | "integrity": "sha512-+dt5w1+Lqyd7wIPMa4XhJxUuE8+YF+vxQ6zxHyhLGHJjHiunPf0wSV8LtQwkpmAsRi1lEOoOIR30FG5S2HS33g==", 834 | "dev": true 835 | }, 836 | "@typescript-eslint/typescript-estree": { 837 | "version": "4.10.0", 838 | "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.10.0.tgz", 839 | "integrity": "sha512-mGK0YRp9TOk6ZqZ98F++bW6X5kMTzCRROJkGXH62d2azhghmq+1LNLylkGe6uGUOQzD452NOAEth5VAF6PDo5g==", 840 | "dev": true, 841 | "requires": { 842 | "@typescript-eslint/types": "4.10.0", 843 | "@typescript-eslint/visitor-keys": "4.10.0", 844 | "debug": "^4.1.1", 845 | "globby": "^11.0.1", 846 | "is-glob": "^4.0.1", 847 | "lodash": "^4.17.15", 848 | "semver": "^7.3.2", 849 | "tsutils": "^3.17.1" 850 | } 851 | }, 852 | "@typescript-eslint/visitor-keys": { 853 | "version": "4.10.0", 854 | "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.10.0.tgz", 855 | "integrity": "sha512-hPyz5qmDMuZWFtHZkjcCpkAKHX8vdu1G3YsCLEd25ryZgnJfj6FQuJ5/O7R+dB1ueszilJmAFMtlU4CA6se3Jg==", 856 | "dev": true, 857 | "requires": { 858 | "@typescript-eslint/types": "4.10.0", 859 | "eslint-visitor-keys": "^2.0.0" 860 | } 861 | }, 862 | "acorn": { 863 | "version": "7.4.1", 864 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", 865 | "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", 866 | "dev": true 867 | }, 868 | "acorn-jsx": { 869 | "version": "5.3.1", 870 | "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", 871 | "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", 872 | "dev": true 873 | }, 874 | "aes-js": { 875 | "version": "3.0.0", 876 | "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", 877 | "integrity": "sha1-4h3xCtbCBTKVvLuNq0Cwnb6ofk0=", 878 | "dev": true 879 | }, 880 | "aggregate-error": { 881 | "version": "3.1.0", 882 | "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", 883 | "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", 884 | "dev": true, 885 | "requires": { 886 | "clean-stack": "^2.0.0", 887 | "indent-string": "^4.0.0" 888 | } 889 | }, 890 | "ajv": { 891 | "version": "6.12.6", 892 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", 893 | "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", 894 | "dev": true, 895 | "requires": { 896 | "fast-deep-equal": "^3.1.1", 897 | "fast-json-stable-stringify": "^2.0.0", 898 | "json-schema-traverse": "^0.4.1", 899 | "uri-js": "^4.2.2" 900 | } 901 | }, 902 | "ansi-colors": { 903 | "version": "4.1.1", 904 | "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", 905 | "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", 906 | "dev": true 907 | }, 908 | "ansi-regex": { 909 | "version": "5.0.0", 910 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", 911 | "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", 912 | "dev": true 913 | }, 914 | "ansi-styles": { 915 | "version": "3.2.1", 916 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", 917 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", 918 | "dev": true, 919 | "requires": { 920 | "color-convert": "^1.9.0" 921 | } 922 | }, 923 | "append-transform": { 924 | "version": "2.0.0", 925 | "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz", 926 | "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==", 927 | "dev": true, 928 | "requires": { 929 | "default-require-extensions": "^3.0.0" 930 | } 931 | }, 932 | "archy": { 933 | "version": "1.0.0", 934 | "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", 935 | "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", 936 | "dev": true 937 | }, 938 | "arg": { 939 | "version": "4.1.3", 940 | "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", 941 | "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" 942 | }, 943 | "argparse": { 944 | "version": "1.0.10", 945 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", 946 | "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", 947 | "dev": true, 948 | "requires": { 949 | "sprintf-js": "~1.0.2" 950 | } 951 | }, 952 | "array-union": { 953 | "version": "2.1.0", 954 | "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", 955 | "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", 956 | "dev": true 957 | }, 958 | "astral-regex": { 959 | "version": "1.0.0", 960 | "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", 961 | "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", 962 | "dev": true 963 | }, 964 | "balanced-match": { 965 | "version": "1.0.0", 966 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", 967 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", 968 | "dev": true 969 | }, 970 | "bech32": { 971 | "version": "1.1.4", 972 | "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", 973 | "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==", 974 | "dev": true 975 | }, 976 | "bn.js": { 977 | "version": "4.11.9", 978 | "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", 979 | "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", 980 | "dev": true 981 | }, 982 | "brace-expansion": { 983 | "version": "1.1.11", 984 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 985 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 986 | "dev": true, 987 | "requires": { 988 | "balanced-match": "^1.0.0", 989 | "concat-map": "0.0.1" 990 | } 991 | }, 992 | "braces": { 993 | "version": "3.0.2", 994 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", 995 | "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", 996 | "dev": true, 997 | "requires": { 998 | "fill-range": "^7.0.1" 999 | } 1000 | }, 1001 | "brorand": { 1002 | "version": "1.1.0", 1003 | "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", 1004 | "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", 1005 | "dev": true 1006 | }, 1007 | "buffer-from": { 1008 | "version": "1.1.1", 1009 | "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", 1010 | "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" 1011 | }, 1012 | "caching-transform": { 1013 | "version": "4.0.0", 1014 | "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz", 1015 | "integrity": "sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==", 1016 | "dev": true, 1017 | "requires": { 1018 | "hasha": "^5.0.0", 1019 | "make-dir": "^3.0.0", 1020 | "package-hash": "^4.0.0", 1021 | "write-file-atomic": "^3.0.0" 1022 | } 1023 | }, 1024 | "callsites": { 1025 | "version": "3.1.0", 1026 | "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", 1027 | "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", 1028 | "dev": true 1029 | }, 1030 | "camelcase": { 1031 | "version": "5.3.1", 1032 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", 1033 | "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", 1034 | "dev": true 1035 | }, 1036 | "chalk": { 1037 | "version": "4.1.0", 1038 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", 1039 | "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", 1040 | "dev": true, 1041 | "requires": { 1042 | "ansi-styles": "^4.1.0", 1043 | "supports-color": "^7.1.0" 1044 | }, 1045 | "dependencies": { 1046 | "ansi-styles": { 1047 | "version": "4.3.0", 1048 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", 1049 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", 1050 | "dev": true, 1051 | "requires": { 1052 | "color-convert": "^2.0.1" 1053 | } 1054 | }, 1055 | "color-convert": { 1056 | "version": "2.0.1", 1057 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", 1058 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", 1059 | "dev": true, 1060 | "requires": { 1061 | "color-name": "~1.1.4" 1062 | } 1063 | }, 1064 | "color-name": { 1065 | "version": "1.1.4", 1066 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", 1067 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", 1068 | "dev": true 1069 | }, 1070 | "has-flag": { 1071 | "version": "4.0.0", 1072 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", 1073 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", 1074 | "dev": true 1075 | }, 1076 | "supports-color": { 1077 | "version": "7.2.0", 1078 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", 1079 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", 1080 | "dev": true, 1081 | "requires": { 1082 | "has-flag": "^4.0.0" 1083 | } 1084 | } 1085 | } 1086 | }, 1087 | "clean-stack": { 1088 | "version": "2.2.0", 1089 | "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", 1090 | "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", 1091 | "dev": true 1092 | }, 1093 | "cliui": { 1094 | "version": "6.0.0", 1095 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", 1096 | "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", 1097 | "dev": true, 1098 | "requires": { 1099 | "string-width": "^4.2.0", 1100 | "strip-ansi": "^6.0.0", 1101 | "wrap-ansi": "^6.2.0" 1102 | }, 1103 | "dependencies": { 1104 | "emoji-regex": { 1105 | "version": "8.0.0", 1106 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", 1107 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", 1108 | "dev": true 1109 | }, 1110 | "is-fullwidth-code-point": { 1111 | "version": "3.0.0", 1112 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", 1113 | "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", 1114 | "dev": true 1115 | }, 1116 | "string-width": { 1117 | "version": "4.2.0", 1118 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", 1119 | "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", 1120 | "dev": true, 1121 | "requires": { 1122 | "emoji-regex": "^8.0.0", 1123 | "is-fullwidth-code-point": "^3.0.0", 1124 | "strip-ansi": "^6.0.0" 1125 | } 1126 | } 1127 | } 1128 | }, 1129 | "color-convert": { 1130 | "version": "1.9.3", 1131 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", 1132 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", 1133 | "dev": true, 1134 | "requires": { 1135 | "color-name": "1.1.3" 1136 | } 1137 | }, 1138 | "color-name": { 1139 | "version": "1.1.3", 1140 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", 1141 | "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", 1142 | "dev": true 1143 | }, 1144 | "commondir": { 1145 | "version": "1.0.1", 1146 | "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", 1147 | "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", 1148 | "dev": true 1149 | }, 1150 | "concat-map": { 1151 | "version": "0.0.1", 1152 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 1153 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", 1154 | "dev": true 1155 | }, 1156 | "convert-source-map": { 1157 | "version": "1.7.0", 1158 | "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", 1159 | "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", 1160 | "dev": true, 1161 | "requires": { 1162 | "safe-buffer": "~5.1.1" 1163 | } 1164 | }, 1165 | "create-require": { 1166 | "version": "1.1.1", 1167 | "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", 1168 | "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==" 1169 | }, 1170 | "cross-spawn": { 1171 | "version": "7.0.3", 1172 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", 1173 | "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", 1174 | "dev": true, 1175 | "requires": { 1176 | "path-key": "^3.1.0", 1177 | "shebang-command": "^2.0.0", 1178 | "which": "^2.0.1" 1179 | } 1180 | }, 1181 | "debug": { 1182 | "version": "4.3.1", 1183 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", 1184 | "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", 1185 | "dev": true, 1186 | "requires": { 1187 | "ms": "2.1.2" 1188 | } 1189 | }, 1190 | "decamelize": { 1191 | "version": "1.2.0", 1192 | "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", 1193 | "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", 1194 | "dev": true 1195 | }, 1196 | "deep-is": { 1197 | "version": "0.1.3", 1198 | "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", 1199 | "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", 1200 | "dev": true 1201 | }, 1202 | "default-require-extensions": { 1203 | "version": "3.0.0", 1204 | "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.0.tgz", 1205 | "integrity": "sha512-ek6DpXq/SCpvjhpFsLFRVtIxJCRw6fUR42lYMVZuUMK7n8eMz4Uh5clckdBjEpLhn/gEBZo7hDJnJcwdKLKQjg==", 1206 | "dev": true, 1207 | "requires": { 1208 | "strip-bom": "^4.0.0" 1209 | } 1210 | }, 1211 | "diff": { 1212 | "version": "4.0.2", 1213 | "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", 1214 | "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==" 1215 | }, 1216 | "dir-glob": { 1217 | "version": "3.0.1", 1218 | "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", 1219 | "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", 1220 | "dev": true, 1221 | "requires": { 1222 | "path-type": "^4.0.0" 1223 | } 1224 | }, 1225 | "doctrine": { 1226 | "version": "3.0.0", 1227 | "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", 1228 | "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", 1229 | "dev": true, 1230 | "requires": { 1231 | "esutils": "^2.0.2" 1232 | } 1233 | }, 1234 | "elliptic": { 1235 | "version": "6.5.3", 1236 | "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz", 1237 | "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==", 1238 | "dev": true, 1239 | "requires": { 1240 | "bn.js": "^4.4.0", 1241 | "brorand": "^1.0.1", 1242 | "hash.js": "^1.0.0", 1243 | "hmac-drbg": "^1.0.0", 1244 | "inherits": "^2.0.1", 1245 | "minimalistic-assert": "^1.0.0", 1246 | "minimalistic-crypto-utils": "^1.0.0" 1247 | } 1248 | }, 1249 | "emoji-regex": { 1250 | "version": "7.0.3", 1251 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", 1252 | "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", 1253 | "dev": true 1254 | }, 1255 | "enquirer": { 1256 | "version": "2.3.6", 1257 | "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", 1258 | "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", 1259 | "dev": true, 1260 | "requires": { 1261 | "ansi-colors": "^4.1.1" 1262 | } 1263 | }, 1264 | "es6-error": { 1265 | "version": "4.1.1", 1266 | "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", 1267 | "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", 1268 | "dev": true 1269 | }, 1270 | "escape-string-regexp": { 1271 | "version": "1.0.5", 1272 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", 1273 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", 1274 | "dev": true 1275 | }, 1276 | "eslint": { 1277 | "version": "7.15.0", 1278 | "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.15.0.tgz", 1279 | "integrity": "sha512-Vr64xFDT8w30wFll643e7cGrIkPEU50yIiI36OdSIDoSGguIeaLzBo0vpGvzo9RECUqq7htURfwEtKqwytkqzA==", 1280 | "dev": true, 1281 | "requires": { 1282 | "@babel/code-frame": "^7.0.0", 1283 | "@eslint/eslintrc": "^0.2.2", 1284 | "ajv": "^6.10.0", 1285 | "chalk": "^4.0.0", 1286 | "cross-spawn": "^7.0.2", 1287 | "debug": "^4.0.1", 1288 | "doctrine": "^3.0.0", 1289 | "enquirer": "^2.3.5", 1290 | "eslint-scope": "^5.1.1", 1291 | "eslint-utils": "^2.1.0", 1292 | "eslint-visitor-keys": "^2.0.0", 1293 | "espree": "^7.3.1", 1294 | "esquery": "^1.2.0", 1295 | "esutils": "^2.0.2", 1296 | "file-entry-cache": "^6.0.0", 1297 | "functional-red-black-tree": "^1.0.1", 1298 | "glob-parent": "^5.0.0", 1299 | "globals": "^12.1.0", 1300 | "ignore": "^4.0.6", 1301 | "import-fresh": "^3.0.0", 1302 | "imurmurhash": "^0.1.4", 1303 | "is-glob": "^4.0.0", 1304 | "js-yaml": "^3.13.1", 1305 | "json-stable-stringify-without-jsonify": "^1.0.1", 1306 | "levn": "^0.4.1", 1307 | "lodash": "^4.17.19", 1308 | "minimatch": "^3.0.4", 1309 | "natural-compare": "^1.4.0", 1310 | "optionator": "^0.9.1", 1311 | "progress": "^2.0.0", 1312 | "regexpp": "^3.1.0", 1313 | "semver": "^7.2.1", 1314 | "strip-ansi": "^6.0.0", 1315 | "strip-json-comments": "^3.1.0", 1316 | "table": "^5.2.3", 1317 | "text-table": "^0.2.0", 1318 | "v8-compile-cache": "^2.0.3" 1319 | }, 1320 | "dependencies": { 1321 | "ignore": { 1322 | "version": "4.0.6", 1323 | "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", 1324 | "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", 1325 | "dev": true 1326 | } 1327 | } 1328 | }, 1329 | "eslint-scope": { 1330 | "version": "5.1.1", 1331 | "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", 1332 | "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", 1333 | "dev": true, 1334 | "requires": { 1335 | "esrecurse": "^4.3.0", 1336 | "estraverse": "^4.1.1" 1337 | } 1338 | }, 1339 | "eslint-utils": { 1340 | "version": "2.1.0", 1341 | "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", 1342 | "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", 1343 | "dev": true, 1344 | "requires": { 1345 | "eslint-visitor-keys": "^1.1.0" 1346 | }, 1347 | "dependencies": { 1348 | "eslint-visitor-keys": { 1349 | "version": "1.3.0", 1350 | "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", 1351 | "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", 1352 | "dev": true 1353 | } 1354 | } 1355 | }, 1356 | "eslint-visitor-keys": { 1357 | "version": "2.0.0", 1358 | "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz", 1359 | "integrity": "sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==", 1360 | "dev": true 1361 | }, 1362 | "espree": { 1363 | "version": "7.3.1", 1364 | "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", 1365 | "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", 1366 | "dev": true, 1367 | "requires": { 1368 | "acorn": "^7.4.0", 1369 | "acorn-jsx": "^5.3.1", 1370 | "eslint-visitor-keys": "^1.3.0" 1371 | }, 1372 | "dependencies": { 1373 | "eslint-visitor-keys": { 1374 | "version": "1.3.0", 1375 | "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", 1376 | "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", 1377 | "dev": true 1378 | } 1379 | } 1380 | }, 1381 | "esprima": { 1382 | "version": "4.0.1", 1383 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", 1384 | "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", 1385 | "dev": true 1386 | }, 1387 | "esquery": { 1388 | "version": "1.3.1", 1389 | "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz", 1390 | "integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==", 1391 | "dev": true, 1392 | "requires": { 1393 | "estraverse": "^5.1.0" 1394 | }, 1395 | "dependencies": { 1396 | "estraverse": { 1397 | "version": "5.2.0", 1398 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", 1399 | "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", 1400 | "dev": true 1401 | } 1402 | } 1403 | }, 1404 | "esrecurse": { 1405 | "version": "4.3.0", 1406 | "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", 1407 | "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", 1408 | "dev": true, 1409 | "requires": { 1410 | "estraverse": "^5.2.0" 1411 | }, 1412 | "dependencies": { 1413 | "estraverse": { 1414 | "version": "5.2.0", 1415 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", 1416 | "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", 1417 | "dev": true 1418 | } 1419 | } 1420 | }, 1421 | "estraverse": { 1422 | "version": "4.3.0", 1423 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", 1424 | "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", 1425 | "dev": true 1426 | }, 1427 | "esutils": { 1428 | "version": "2.0.3", 1429 | "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", 1430 | "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", 1431 | "dev": true 1432 | }, 1433 | "ethers": { 1434 | "version": "5.0.24", 1435 | "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.0.24.tgz", 1436 | "integrity": "sha512-77CEtVC88fJGEhxGXRvQqAEH6e2A+ZFiv2FBT6ikXndlty5sw6vMatAhg1v+w3CaaGZOf1CP81jl4Mc8Zrj08A==", 1437 | "dev": true, 1438 | "requires": { 1439 | "@ethersproject/abi": "5.0.9", 1440 | "@ethersproject/abstract-provider": "5.0.7", 1441 | "@ethersproject/abstract-signer": "5.0.9", 1442 | "@ethersproject/address": "5.0.8", 1443 | "@ethersproject/base64": "5.0.6", 1444 | "@ethersproject/basex": "5.0.6", 1445 | "@ethersproject/bignumber": "5.0.12", 1446 | "@ethersproject/bytes": "5.0.8", 1447 | "@ethersproject/constants": "5.0.7", 1448 | "@ethersproject/contracts": "5.0.8", 1449 | "@ethersproject/hash": "5.0.9", 1450 | "@ethersproject/hdnode": "5.0.7", 1451 | "@ethersproject/json-wallets": "5.0.9", 1452 | "@ethersproject/keccak256": "5.0.6", 1453 | "@ethersproject/logger": "5.0.8", 1454 | "@ethersproject/networks": "5.0.6", 1455 | "@ethersproject/pbkdf2": "5.0.6", 1456 | "@ethersproject/properties": "5.0.6", 1457 | "@ethersproject/providers": "5.0.17", 1458 | "@ethersproject/random": "5.0.6", 1459 | "@ethersproject/rlp": "5.0.6", 1460 | "@ethersproject/sha2": "5.0.6", 1461 | "@ethersproject/signing-key": "5.0.7", 1462 | "@ethersproject/solidity": "5.0.7", 1463 | "@ethersproject/strings": "5.0.7", 1464 | "@ethersproject/transactions": "5.0.8", 1465 | "@ethersproject/units": "5.0.8", 1466 | "@ethersproject/wallet": "5.0.9", 1467 | "@ethersproject/web": "5.0.11", 1468 | "@ethersproject/wordlists": "5.0.7" 1469 | } 1470 | }, 1471 | "fast-deep-equal": { 1472 | "version": "3.1.3", 1473 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", 1474 | "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", 1475 | "dev": true 1476 | }, 1477 | "fast-glob": { 1478 | "version": "3.2.4", 1479 | "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.4.tgz", 1480 | "integrity": "sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ==", 1481 | "dev": true, 1482 | "requires": { 1483 | "@nodelib/fs.stat": "^2.0.2", 1484 | "@nodelib/fs.walk": "^1.2.3", 1485 | "glob-parent": "^5.1.0", 1486 | "merge2": "^1.3.0", 1487 | "micromatch": "^4.0.2", 1488 | "picomatch": "^2.2.1" 1489 | } 1490 | }, 1491 | "fast-json-stable-stringify": { 1492 | "version": "2.1.0", 1493 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", 1494 | "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", 1495 | "dev": true 1496 | }, 1497 | "fast-levenshtein": { 1498 | "version": "2.0.6", 1499 | "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", 1500 | "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", 1501 | "dev": true 1502 | }, 1503 | "fastq": { 1504 | "version": "1.9.0", 1505 | "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.9.0.tgz", 1506 | "integrity": "sha512-i7FVWL8HhVY+CTkwFxkN2mk3h+787ixS5S63eb78diVRc1MCssarHq3W5cj0av7YDSwmaV928RNag+U1etRQ7w==", 1507 | "dev": true, 1508 | "requires": { 1509 | "reusify": "^1.0.4" 1510 | } 1511 | }, 1512 | "file-entry-cache": { 1513 | "version": "6.0.0", 1514 | "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.0.tgz", 1515 | "integrity": "sha512-fqoO76jZ3ZnYrXLDRxBR1YvOvc0k844kcOg40bgsPrE25LAb/PDqTY+ho64Xh2c8ZXgIKldchCFHczG2UVRcWA==", 1516 | "dev": true, 1517 | "requires": { 1518 | "flat-cache": "^3.0.4" 1519 | } 1520 | }, 1521 | "fill-range": { 1522 | "version": "7.0.1", 1523 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", 1524 | "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", 1525 | "dev": true, 1526 | "requires": { 1527 | "to-regex-range": "^5.0.1" 1528 | } 1529 | }, 1530 | "find-cache-dir": { 1531 | "version": "3.3.1", 1532 | "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz", 1533 | "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==", 1534 | "dev": true, 1535 | "requires": { 1536 | "commondir": "^1.0.1", 1537 | "make-dir": "^3.0.2", 1538 | "pkg-dir": "^4.1.0" 1539 | } 1540 | }, 1541 | "find-up": { 1542 | "version": "4.1.0", 1543 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", 1544 | "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", 1545 | "dev": true, 1546 | "requires": { 1547 | "locate-path": "^5.0.0", 1548 | "path-exists": "^4.0.0" 1549 | } 1550 | }, 1551 | "flat-cache": { 1552 | "version": "3.0.4", 1553 | "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", 1554 | "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", 1555 | "dev": true, 1556 | "requires": { 1557 | "flatted": "^3.1.0", 1558 | "rimraf": "^3.0.2" 1559 | } 1560 | }, 1561 | "flatted": { 1562 | "version": "3.1.0", 1563 | "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.0.tgz", 1564 | "integrity": "sha512-tW+UkmtNg/jv9CSofAKvgVcO7c2URjhTdW1ZTkcAritblu8tajiYy7YisnIflEwtKssCtOxpnBRoCB7iap0/TA==", 1565 | "dev": true 1566 | }, 1567 | "foreground-child": { 1568 | "version": "2.0.0", 1569 | "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", 1570 | "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", 1571 | "dev": true, 1572 | "requires": { 1573 | "cross-spawn": "^7.0.0", 1574 | "signal-exit": "^3.0.2" 1575 | } 1576 | }, 1577 | "fromentries": { 1578 | "version": "1.3.2", 1579 | "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz", 1580 | "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==", 1581 | "dev": true 1582 | }, 1583 | "fs.realpath": { 1584 | "version": "1.0.0", 1585 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 1586 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", 1587 | "dev": true 1588 | }, 1589 | "functional-red-black-tree": { 1590 | "version": "1.0.1", 1591 | "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", 1592 | "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", 1593 | "dev": true 1594 | }, 1595 | "gensync": { 1596 | "version": "1.0.0-beta.2", 1597 | "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", 1598 | "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", 1599 | "dev": true 1600 | }, 1601 | "get-caller-file": { 1602 | "version": "2.0.5", 1603 | "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", 1604 | "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", 1605 | "dev": true 1606 | }, 1607 | "get-package-type": { 1608 | "version": "0.1.0", 1609 | "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", 1610 | "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", 1611 | "dev": true 1612 | }, 1613 | "glob": { 1614 | "version": "7.1.6", 1615 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", 1616 | "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", 1617 | "dev": true, 1618 | "requires": { 1619 | "fs.realpath": "^1.0.0", 1620 | "inflight": "^1.0.4", 1621 | "inherits": "2", 1622 | "minimatch": "^3.0.4", 1623 | "once": "^1.3.0", 1624 | "path-is-absolute": "^1.0.0" 1625 | } 1626 | }, 1627 | "glob-parent": { 1628 | "version": "5.1.1", 1629 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", 1630 | "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", 1631 | "dev": true, 1632 | "requires": { 1633 | "is-glob": "^4.0.1" 1634 | } 1635 | }, 1636 | "globals": { 1637 | "version": "12.4.0", 1638 | "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", 1639 | "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", 1640 | "dev": true, 1641 | "requires": { 1642 | "type-fest": "^0.8.1" 1643 | } 1644 | }, 1645 | "globby": { 1646 | "version": "11.0.1", 1647 | "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.1.tgz", 1648 | "integrity": "sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ==", 1649 | "dev": true, 1650 | "requires": { 1651 | "array-union": "^2.1.0", 1652 | "dir-glob": "^3.0.1", 1653 | "fast-glob": "^3.1.1", 1654 | "ignore": "^5.1.4", 1655 | "merge2": "^1.3.0", 1656 | "slash": "^3.0.0" 1657 | } 1658 | }, 1659 | "graceful-fs": { 1660 | "version": "4.2.4", 1661 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", 1662 | "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", 1663 | "dev": true 1664 | }, 1665 | "has-flag": { 1666 | "version": "3.0.0", 1667 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", 1668 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", 1669 | "dev": true 1670 | }, 1671 | "hash.js": { 1672 | "version": "1.1.7", 1673 | "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", 1674 | "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", 1675 | "dev": true, 1676 | "requires": { 1677 | "inherits": "^2.0.3", 1678 | "minimalistic-assert": "^1.0.1" 1679 | } 1680 | }, 1681 | "hasha": { 1682 | "version": "5.2.2", 1683 | "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz", 1684 | "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==", 1685 | "dev": true, 1686 | "requires": { 1687 | "is-stream": "^2.0.0", 1688 | "type-fest": "^0.8.0" 1689 | } 1690 | }, 1691 | "hmac-drbg": { 1692 | "version": "1.0.1", 1693 | "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", 1694 | "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", 1695 | "dev": true, 1696 | "requires": { 1697 | "hash.js": "^1.0.3", 1698 | "minimalistic-assert": "^1.0.0", 1699 | "minimalistic-crypto-utils": "^1.0.1" 1700 | } 1701 | }, 1702 | "html-escaper": { 1703 | "version": "2.0.2", 1704 | "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", 1705 | "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", 1706 | "dev": true 1707 | }, 1708 | "ignore": { 1709 | "version": "5.1.8", 1710 | "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", 1711 | "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", 1712 | "dev": true 1713 | }, 1714 | "import-fresh": { 1715 | "version": "3.2.2", 1716 | "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.2.tgz", 1717 | "integrity": "sha512-cTPNrlvJT6twpYy+YmKUKrTSjWFs3bjYjAhCwm+z4EOCubZxAuO+hHpRN64TqjEaYSHs7tJAE0w1CKMGmsG/lw==", 1718 | "dev": true, 1719 | "requires": { 1720 | "parent-module": "^1.0.0", 1721 | "resolve-from": "^4.0.0" 1722 | } 1723 | }, 1724 | "imurmurhash": { 1725 | "version": "0.1.4", 1726 | "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", 1727 | "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", 1728 | "dev": true 1729 | }, 1730 | "indent-string": { 1731 | "version": "4.0.0", 1732 | "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", 1733 | "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", 1734 | "dev": true 1735 | }, 1736 | "inflight": { 1737 | "version": "1.0.6", 1738 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 1739 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 1740 | "dev": true, 1741 | "requires": { 1742 | "once": "^1.3.0", 1743 | "wrappy": "1" 1744 | } 1745 | }, 1746 | "inherits": { 1747 | "version": "2.0.4", 1748 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 1749 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", 1750 | "dev": true 1751 | }, 1752 | "is-extglob": { 1753 | "version": "2.1.1", 1754 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", 1755 | "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", 1756 | "dev": true 1757 | }, 1758 | "is-fullwidth-code-point": { 1759 | "version": "2.0.0", 1760 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", 1761 | "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", 1762 | "dev": true 1763 | }, 1764 | "is-glob": { 1765 | "version": "4.0.1", 1766 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", 1767 | "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", 1768 | "dev": true, 1769 | "requires": { 1770 | "is-extglob": "^2.1.1" 1771 | } 1772 | }, 1773 | "is-number": { 1774 | "version": "7.0.0", 1775 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", 1776 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", 1777 | "dev": true 1778 | }, 1779 | "is-stream": { 1780 | "version": "2.0.0", 1781 | "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", 1782 | "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", 1783 | "dev": true 1784 | }, 1785 | "is-typedarray": { 1786 | "version": "1.0.0", 1787 | "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", 1788 | "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", 1789 | "dev": true 1790 | }, 1791 | "is-windows": { 1792 | "version": "1.0.2", 1793 | "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", 1794 | "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", 1795 | "dev": true 1796 | }, 1797 | "isexe": { 1798 | "version": "2.0.0", 1799 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 1800 | "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", 1801 | "dev": true 1802 | }, 1803 | "istanbul-lib-coverage": { 1804 | "version": "3.0.0", 1805 | "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", 1806 | "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==", 1807 | "dev": true 1808 | }, 1809 | "istanbul-lib-hook": { 1810 | "version": "3.0.0", 1811 | "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-3.0.0.tgz", 1812 | "integrity": "sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==", 1813 | "dev": true, 1814 | "requires": { 1815 | "append-transform": "^2.0.0" 1816 | } 1817 | }, 1818 | "istanbul-lib-instrument": { 1819 | "version": "4.0.3", 1820 | "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", 1821 | "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", 1822 | "dev": true, 1823 | "requires": { 1824 | "@babel/core": "^7.7.5", 1825 | "@istanbuljs/schema": "^0.1.2", 1826 | "istanbul-lib-coverage": "^3.0.0", 1827 | "semver": "^6.3.0" 1828 | }, 1829 | "dependencies": { 1830 | "semver": { 1831 | "version": "6.3.0", 1832 | "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", 1833 | "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", 1834 | "dev": true 1835 | } 1836 | } 1837 | }, 1838 | "istanbul-lib-processinfo": { 1839 | "version": "2.0.2", 1840 | "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.2.tgz", 1841 | "integrity": "sha512-kOwpa7z9hme+IBPZMzQ5vdQj8srYgAtaRqeI48NGmAQ+/5yKiHLV0QbYqQpxsdEF0+w14SoB8YbnHKcXE2KnYw==", 1842 | "dev": true, 1843 | "requires": { 1844 | "archy": "^1.0.0", 1845 | "cross-spawn": "^7.0.0", 1846 | "istanbul-lib-coverage": "^3.0.0-alpha.1", 1847 | "make-dir": "^3.0.0", 1848 | "p-map": "^3.0.0", 1849 | "rimraf": "^3.0.0", 1850 | "uuid": "^3.3.3" 1851 | } 1852 | }, 1853 | "istanbul-lib-report": { 1854 | "version": "3.0.0", 1855 | "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", 1856 | "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", 1857 | "dev": true, 1858 | "requires": { 1859 | "istanbul-lib-coverage": "^3.0.0", 1860 | "make-dir": "^3.0.0", 1861 | "supports-color": "^7.1.0" 1862 | }, 1863 | "dependencies": { 1864 | "has-flag": { 1865 | "version": "4.0.0", 1866 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", 1867 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", 1868 | "dev": true 1869 | }, 1870 | "supports-color": { 1871 | "version": "7.2.0", 1872 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", 1873 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", 1874 | "dev": true, 1875 | "requires": { 1876 | "has-flag": "^4.0.0" 1877 | } 1878 | } 1879 | } 1880 | }, 1881 | "istanbul-lib-source-maps": { 1882 | "version": "4.0.0", 1883 | "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz", 1884 | "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==", 1885 | "dev": true, 1886 | "requires": { 1887 | "debug": "^4.1.1", 1888 | "istanbul-lib-coverage": "^3.0.0", 1889 | "source-map": "^0.6.1" 1890 | } 1891 | }, 1892 | "istanbul-reports": { 1893 | "version": "3.0.2", 1894 | "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz", 1895 | "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==", 1896 | "dev": true, 1897 | "requires": { 1898 | "html-escaper": "^2.0.0", 1899 | "istanbul-lib-report": "^3.0.0" 1900 | } 1901 | }, 1902 | "jasmine": { 1903 | "version": "3.6.3", 1904 | "resolved": "https://registry.npmjs.org/jasmine/-/jasmine-3.6.3.tgz", 1905 | "integrity": "sha512-Th91zHsbsALWjDUIiU5d/W5zaYQsZFMPTdeNmi8GivZPmAaUAK8MblSG3yQI4VMGC/abF2us7ex60NH1AAIMTA==", 1906 | "dev": true, 1907 | "requires": { 1908 | "glob": "^7.1.6", 1909 | "jasmine-core": "~3.6.0" 1910 | } 1911 | }, 1912 | "jasmine-core": { 1913 | "version": "3.6.0", 1914 | "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-3.6.0.tgz", 1915 | "integrity": "sha512-8uQYa7zJN8hq9z+g8z1bqCfdC8eoDAeVnM5sfqs7KHv9/ifoJ500m018fpFc7RDaO6SWCLCXwo/wPSNcdYTgcw==", 1916 | "dev": true 1917 | }, 1918 | "js-sha3": { 1919 | "version": "0.5.7", 1920 | "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz", 1921 | "integrity": "sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc=", 1922 | "dev": true 1923 | }, 1924 | "js-tokens": { 1925 | "version": "4.0.0", 1926 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", 1927 | "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", 1928 | "dev": true 1929 | }, 1930 | "js-yaml": { 1931 | "version": "3.14.1", 1932 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", 1933 | "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", 1934 | "dev": true, 1935 | "requires": { 1936 | "argparse": "^1.0.7", 1937 | "esprima": "^4.0.0" 1938 | } 1939 | }, 1940 | "jsesc": { 1941 | "version": "2.5.2", 1942 | "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", 1943 | "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", 1944 | "dev": true 1945 | }, 1946 | "json-schema-traverse": { 1947 | "version": "0.4.1", 1948 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", 1949 | "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", 1950 | "dev": true 1951 | }, 1952 | "json-stable-stringify-without-jsonify": { 1953 | "version": "1.0.1", 1954 | "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", 1955 | "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", 1956 | "dev": true 1957 | }, 1958 | "json5": { 1959 | "version": "2.1.3", 1960 | "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", 1961 | "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", 1962 | "dev": true, 1963 | "requires": { 1964 | "minimist": "^1.2.5" 1965 | } 1966 | }, 1967 | "levn": { 1968 | "version": "0.4.1", 1969 | "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", 1970 | "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", 1971 | "dev": true, 1972 | "requires": { 1973 | "prelude-ls": "^1.2.1", 1974 | "type-check": "~0.4.0" 1975 | } 1976 | }, 1977 | "locate-path": { 1978 | "version": "5.0.0", 1979 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", 1980 | "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", 1981 | "dev": true, 1982 | "requires": { 1983 | "p-locate": "^4.1.0" 1984 | } 1985 | }, 1986 | "lodash": { 1987 | "version": "4.17.21", 1988 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", 1989 | "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" 1990 | }, 1991 | "lodash.flattendeep": { 1992 | "version": "4.4.0", 1993 | "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", 1994 | "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=", 1995 | "dev": true 1996 | }, 1997 | "lru-cache": { 1998 | "version": "6.0.0", 1999 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", 2000 | "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", 2001 | "dev": true, 2002 | "requires": { 2003 | "yallist": "^4.0.0" 2004 | } 2005 | }, 2006 | "make-dir": { 2007 | "version": "3.1.0", 2008 | "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", 2009 | "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", 2010 | "dev": true, 2011 | "requires": { 2012 | "semver": "^6.0.0" 2013 | }, 2014 | "dependencies": { 2015 | "semver": { 2016 | "version": "6.3.0", 2017 | "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", 2018 | "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", 2019 | "dev": true 2020 | } 2021 | } 2022 | }, 2023 | "make-error": { 2024 | "version": "1.3.6", 2025 | "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", 2026 | "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" 2027 | }, 2028 | "merge2": { 2029 | "version": "1.4.1", 2030 | "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", 2031 | "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", 2032 | "dev": true 2033 | }, 2034 | "micromatch": { 2035 | "version": "4.0.2", 2036 | "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", 2037 | "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", 2038 | "dev": true, 2039 | "requires": { 2040 | "braces": "^3.0.1", 2041 | "picomatch": "^2.0.5" 2042 | } 2043 | }, 2044 | "minimalistic-assert": { 2045 | "version": "1.0.1", 2046 | "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", 2047 | "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", 2048 | "dev": true 2049 | }, 2050 | "minimalistic-crypto-utils": { 2051 | "version": "1.0.1", 2052 | "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", 2053 | "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", 2054 | "dev": true 2055 | }, 2056 | "minimatch": { 2057 | "version": "3.0.4", 2058 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", 2059 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 2060 | "dev": true, 2061 | "requires": { 2062 | "brace-expansion": "^1.1.7" 2063 | } 2064 | }, 2065 | "minimist": { 2066 | "version": "1.2.5", 2067 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", 2068 | "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", 2069 | "dev": true 2070 | }, 2071 | "ms": { 2072 | "version": "2.1.2", 2073 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 2074 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", 2075 | "dev": true 2076 | }, 2077 | "natural-compare": { 2078 | "version": "1.4.0", 2079 | "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", 2080 | "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", 2081 | "dev": true 2082 | }, 2083 | "node-preload": { 2084 | "version": "0.2.1", 2085 | "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", 2086 | "integrity": "sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==", 2087 | "dev": true, 2088 | "requires": { 2089 | "process-on-spawn": "^1.0.0" 2090 | } 2091 | }, 2092 | "nyc": { 2093 | "version": "15.1.0", 2094 | "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz", 2095 | "integrity": "sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A==", 2096 | "dev": true, 2097 | "requires": { 2098 | "@istanbuljs/load-nyc-config": "^1.0.0", 2099 | "@istanbuljs/schema": "^0.1.2", 2100 | "caching-transform": "^4.0.0", 2101 | "convert-source-map": "^1.7.0", 2102 | "decamelize": "^1.2.0", 2103 | "find-cache-dir": "^3.2.0", 2104 | "find-up": "^4.1.0", 2105 | "foreground-child": "^2.0.0", 2106 | "get-package-type": "^0.1.0", 2107 | "glob": "^7.1.6", 2108 | "istanbul-lib-coverage": "^3.0.0", 2109 | "istanbul-lib-hook": "^3.0.0", 2110 | "istanbul-lib-instrument": "^4.0.0", 2111 | "istanbul-lib-processinfo": "^2.0.2", 2112 | "istanbul-lib-report": "^3.0.0", 2113 | "istanbul-lib-source-maps": "^4.0.0", 2114 | "istanbul-reports": "^3.0.2", 2115 | "make-dir": "^3.0.0", 2116 | "node-preload": "^0.2.1", 2117 | "p-map": "^3.0.0", 2118 | "process-on-spawn": "^1.0.0", 2119 | "resolve-from": "^5.0.0", 2120 | "rimraf": "^3.0.0", 2121 | "signal-exit": "^3.0.2", 2122 | "spawn-wrap": "^2.0.0", 2123 | "test-exclude": "^6.0.0", 2124 | "yargs": "^15.0.2" 2125 | }, 2126 | "dependencies": { 2127 | "resolve-from": { 2128 | "version": "5.0.0", 2129 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", 2130 | "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", 2131 | "dev": true 2132 | } 2133 | } 2134 | }, 2135 | "once": { 2136 | "version": "1.4.0", 2137 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 2138 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 2139 | "dev": true, 2140 | "requires": { 2141 | "wrappy": "1" 2142 | } 2143 | }, 2144 | "optionator": { 2145 | "version": "0.9.1", 2146 | "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", 2147 | "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", 2148 | "dev": true, 2149 | "requires": { 2150 | "deep-is": "^0.1.3", 2151 | "fast-levenshtein": "^2.0.6", 2152 | "levn": "^0.4.1", 2153 | "prelude-ls": "^1.2.1", 2154 | "type-check": "^0.4.0", 2155 | "word-wrap": "^1.2.3" 2156 | } 2157 | }, 2158 | "p-limit": { 2159 | "version": "2.3.0", 2160 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", 2161 | "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", 2162 | "dev": true, 2163 | "requires": { 2164 | "p-try": "^2.0.0" 2165 | } 2166 | }, 2167 | "p-locate": { 2168 | "version": "4.1.0", 2169 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", 2170 | "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", 2171 | "dev": true, 2172 | "requires": { 2173 | "p-limit": "^2.2.0" 2174 | } 2175 | }, 2176 | "p-map": { 2177 | "version": "3.0.0", 2178 | "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", 2179 | "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", 2180 | "dev": true, 2181 | "requires": { 2182 | "aggregate-error": "^3.0.0" 2183 | } 2184 | }, 2185 | "p-try": { 2186 | "version": "2.2.0", 2187 | "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", 2188 | "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", 2189 | "dev": true 2190 | }, 2191 | "package-hash": { 2192 | "version": "4.0.0", 2193 | "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-4.0.0.tgz", 2194 | "integrity": "sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==", 2195 | "dev": true, 2196 | "requires": { 2197 | "graceful-fs": "^4.1.15", 2198 | "hasha": "^5.0.0", 2199 | "lodash.flattendeep": "^4.4.0", 2200 | "release-zalgo": "^1.0.0" 2201 | } 2202 | }, 2203 | "parent-module": { 2204 | "version": "1.0.1", 2205 | "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", 2206 | "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", 2207 | "dev": true, 2208 | "requires": { 2209 | "callsites": "^3.0.0" 2210 | } 2211 | }, 2212 | "path-exists": { 2213 | "version": "4.0.0", 2214 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", 2215 | "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", 2216 | "dev": true 2217 | }, 2218 | "path-is-absolute": { 2219 | "version": "1.0.1", 2220 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 2221 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", 2222 | "dev": true 2223 | }, 2224 | "path-key": { 2225 | "version": "3.1.1", 2226 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", 2227 | "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", 2228 | "dev": true 2229 | }, 2230 | "path-type": { 2231 | "version": "4.0.0", 2232 | "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", 2233 | "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", 2234 | "dev": true 2235 | }, 2236 | "picomatch": { 2237 | "version": "2.2.2", 2238 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", 2239 | "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", 2240 | "dev": true 2241 | }, 2242 | "pkg-dir": { 2243 | "version": "4.2.0", 2244 | "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", 2245 | "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", 2246 | "dev": true, 2247 | "requires": { 2248 | "find-up": "^4.0.0" 2249 | } 2250 | }, 2251 | "prelude-ls": { 2252 | "version": "1.2.1", 2253 | "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", 2254 | "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", 2255 | "dev": true 2256 | }, 2257 | "process-on-spawn": { 2258 | "version": "1.0.0", 2259 | "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz", 2260 | "integrity": "sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg==", 2261 | "dev": true, 2262 | "requires": { 2263 | "fromentries": "^1.2.0" 2264 | } 2265 | }, 2266 | "progress": { 2267 | "version": "2.0.3", 2268 | "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", 2269 | "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", 2270 | "dev": true 2271 | }, 2272 | "punycode": { 2273 | "version": "2.1.1", 2274 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", 2275 | "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", 2276 | "dev": true 2277 | }, 2278 | "regexpp": { 2279 | "version": "3.1.0", 2280 | "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", 2281 | "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", 2282 | "dev": true 2283 | }, 2284 | "release-zalgo": { 2285 | "version": "1.0.0", 2286 | "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", 2287 | "integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=", 2288 | "dev": true, 2289 | "requires": { 2290 | "es6-error": "^4.0.1" 2291 | } 2292 | }, 2293 | "require-directory": { 2294 | "version": "2.1.1", 2295 | "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", 2296 | "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", 2297 | "dev": true 2298 | }, 2299 | "require-main-filename": { 2300 | "version": "2.0.0", 2301 | "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", 2302 | "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", 2303 | "dev": true 2304 | }, 2305 | "resolve-from": { 2306 | "version": "4.0.0", 2307 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", 2308 | "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", 2309 | "dev": true 2310 | }, 2311 | "reusify": { 2312 | "version": "1.0.4", 2313 | "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", 2314 | "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", 2315 | "dev": true 2316 | }, 2317 | "rimraf": { 2318 | "version": "3.0.2", 2319 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", 2320 | "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", 2321 | "dev": true, 2322 | "requires": { 2323 | "glob": "^7.1.3" 2324 | } 2325 | }, 2326 | "run-parallel": { 2327 | "version": "1.1.10", 2328 | "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.10.tgz", 2329 | "integrity": "sha512-zb/1OuZ6flOlH6tQyMPUrE3x3Ulxjlo9WIVXR4yVYi4H9UXQaeIsPbLn2R3O3vQCnDKkAl2qHiuocKKX4Tz/Sw==", 2330 | "dev": true 2331 | }, 2332 | "safe-buffer": { 2333 | "version": "5.1.2", 2334 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 2335 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", 2336 | "dev": true 2337 | }, 2338 | "scrypt-js": { 2339 | "version": "3.0.1", 2340 | "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", 2341 | "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==", 2342 | "dev": true 2343 | }, 2344 | "semver": { 2345 | "version": "7.3.4", 2346 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", 2347 | "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", 2348 | "dev": true, 2349 | "requires": { 2350 | "lru-cache": "^6.0.0" 2351 | } 2352 | }, 2353 | "set-blocking": { 2354 | "version": "2.0.0", 2355 | "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", 2356 | "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", 2357 | "dev": true 2358 | }, 2359 | "shebang-command": { 2360 | "version": "2.0.0", 2361 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", 2362 | "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", 2363 | "dev": true, 2364 | "requires": { 2365 | "shebang-regex": "^3.0.0" 2366 | } 2367 | }, 2368 | "shebang-regex": { 2369 | "version": "3.0.0", 2370 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", 2371 | "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", 2372 | "dev": true 2373 | }, 2374 | "signal-exit": { 2375 | "version": "3.0.3", 2376 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", 2377 | "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", 2378 | "dev": true 2379 | }, 2380 | "slash": { 2381 | "version": "3.0.0", 2382 | "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", 2383 | "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", 2384 | "dev": true 2385 | }, 2386 | "slice-ansi": { 2387 | "version": "2.1.0", 2388 | "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", 2389 | "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", 2390 | "dev": true, 2391 | "requires": { 2392 | "ansi-styles": "^3.2.0", 2393 | "astral-regex": "^1.0.0", 2394 | "is-fullwidth-code-point": "^2.0.0" 2395 | } 2396 | }, 2397 | "source-map": { 2398 | "version": "0.6.1", 2399 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", 2400 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" 2401 | }, 2402 | "source-map-support": { 2403 | "version": "0.5.19", 2404 | "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", 2405 | "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", 2406 | "requires": { 2407 | "buffer-from": "^1.0.0", 2408 | "source-map": "^0.6.0" 2409 | } 2410 | }, 2411 | "spawn-wrap": { 2412 | "version": "2.0.0", 2413 | "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz", 2414 | "integrity": "sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==", 2415 | "dev": true, 2416 | "requires": { 2417 | "foreground-child": "^2.0.0", 2418 | "is-windows": "^1.0.2", 2419 | "make-dir": "^3.0.0", 2420 | "rimraf": "^3.0.0", 2421 | "signal-exit": "^3.0.2", 2422 | "which": "^2.0.1" 2423 | } 2424 | }, 2425 | "sprintf-js": { 2426 | "version": "1.0.3", 2427 | "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", 2428 | "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", 2429 | "dev": true 2430 | }, 2431 | "string-width": { 2432 | "version": "3.1.0", 2433 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", 2434 | "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", 2435 | "dev": true, 2436 | "requires": { 2437 | "emoji-regex": "^7.0.1", 2438 | "is-fullwidth-code-point": "^2.0.0", 2439 | "strip-ansi": "^5.1.0" 2440 | }, 2441 | "dependencies": { 2442 | "ansi-regex": { 2443 | "version": "4.1.0", 2444 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", 2445 | "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", 2446 | "dev": true 2447 | }, 2448 | "strip-ansi": { 2449 | "version": "5.2.0", 2450 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", 2451 | "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", 2452 | "dev": true, 2453 | "requires": { 2454 | "ansi-regex": "^4.1.0" 2455 | } 2456 | } 2457 | } 2458 | }, 2459 | "strip-ansi": { 2460 | "version": "6.0.0", 2461 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", 2462 | "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", 2463 | "dev": true, 2464 | "requires": { 2465 | "ansi-regex": "^5.0.0" 2466 | } 2467 | }, 2468 | "strip-bom": { 2469 | "version": "4.0.0", 2470 | "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", 2471 | "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", 2472 | "dev": true 2473 | }, 2474 | "strip-json-comments": { 2475 | "version": "3.1.1", 2476 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", 2477 | "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", 2478 | "dev": true 2479 | }, 2480 | "supports-color": { 2481 | "version": "5.5.0", 2482 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", 2483 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", 2484 | "dev": true, 2485 | "requires": { 2486 | "has-flag": "^3.0.0" 2487 | } 2488 | }, 2489 | "table": { 2490 | "version": "5.4.6", 2491 | "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", 2492 | "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", 2493 | "dev": true, 2494 | "requires": { 2495 | "ajv": "^6.10.2", 2496 | "lodash": "^4.17.14", 2497 | "slice-ansi": "^2.1.0", 2498 | "string-width": "^3.0.0" 2499 | } 2500 | }, 2501 | "test-exclude": { 2502 | "version": "6.0.0", 2503 | "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", 2504 | "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", 2505 | "dev": true, 2506 | "requires": { 2507 | "@istanbuljs/schema": "^0.1.2", 2508 | "glob": "^7.1.4", 2509 | "minimatch": "^3.0.4" 2510 | } 2511 | }, 2512 | "text-table": { 2513 | "version": "0.2.0", 2514 | "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", 2515 | "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", 2516 | "dev": true 2517 | }, 2518 | "to-fast-properties": { 2519 | "version": "2.0.0", 2520 | "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", 2521 | "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", 2522 | "dev": true 2523 | }, 2524 | "to-regex-range": { 2525 | "version": "5.0.1", 2526 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", 2527 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", 2528 | "dev": true, 2529 | "requires": { 2530 | "is-number": "^7.0.0" 2531 | } 2532 | }, 2533 | "ts-node": { 2534 | "version": "9.1.1", 2535 | "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-9.1.1.tgz", 2536 | "integrity": "sha512-hPlt7ZACERQGf03M253ytLY3dHbGNGrAq9qIHWUY9XHYl1z7wYngSr3OQ5xmui8o2AaxsONxIzjafLUiWBo1Fg==", 2537 | "requires": { 2538 | "arg": "^4.1.0", 2539 | "create-require": "^1.1.0", 2540 | "diff": "^4.0.1", 2541 | "make-error": "^1.1.1", 2542 | "source-map-support": "^0.5.17", 2543 | "yn": "3.1.1" 2544 | } 2545 | }, 2546 | "tslib": { 2547 | "version": "1.14.1", 2548 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", 2549 | "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", 2550 | "dev": true 2551 | }, 2552 | "tsutils": { 2553 | "version": "3.17.1", 2554 | "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.17.1.tgz", 2555 | "integrity": "sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g==", 2556 | "dev": true, 2557 | "requires": { 2558 | "tslib": "^1.8.1" 2559 | } 2560 | }, 2561 | "type-check": { 2562 | "version": "0.4.0", 2563 | "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", 2564 | "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", 2565 | "dev": true, 2566 | "requires": { 2567 | "prelude-ls": "^1.2.1" 2568 | } 2569 | }, 2570 | "type-fest": { 2571 | "version": "0.8.1", 2572 | "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", 2573 | "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", 2574 | "dev": true 2575 | }, 2576 | "typedarray-to-buffer": { 2577 | "version": "3.1.5", 2578 | "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", 2579 | "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", 2580 | "dev": true, 2581 | "requires": { 2582 | "is-typedarray": "^1.0.0" 2583 | } 2584 | }, 2585 | "typescript": { 2586 | "version": "4.1.3", 2587 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.1.3.tgz", 2588 | "integrity": "sha512-B3ZIOf1IKeH2ixgHhj6la6xdwR9QrLC5d1VKeCSY4tvkqhF2eqd9O7txNlS0PO3GrBAFIdr3L1ndNwteUbZLYg==" 2589 | }, 2590 | "uri-js": { 2591 | "version": "4.4.0", 2592 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.0.tgz", 2593 | "integrity": "sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g==", 2594 | "dev": true, 2595 | "requires": { 2596 | "punycode": "^2.1.0" 2597 | } 2598 | }, 2599 | "uuid": { 2600 | "version": "3.4.0", 2601 | "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", 2602 | "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", 2603 | "dev": true 2604 | }, 2605 | "v8-compile-cache": { 2606 | "version": "2.2.0", 2607 | "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.2.0.tgz", 2608 | "integrity": "sha512-gTpR5XQNKFwOd4clxfnhaqvfqMpqEwr4tOtCyz4MtYZX2JYhfr1JvBFKdS+7K/9rfpZR3VLX+YWBbKoxCgS43Q==", 2609 | "dev": true 2610 | }, 2611 | "which": { 2612 | "version": "2.0.2", 2613 | "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", 2614 | "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", 2615 | "dev": true, 2616 | "requires": { 2617 | "isexe": "^2.0.0" 2618 | } 2619 | }, 2620 | "which-module": { 2621 | "version": "2.0.0", 2622 | "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", 2623 | "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", 2624 | "dev": true 2625 | }, 2626 | "word-wrap": { 2627 | "version": "1.2.3", 2628 | "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", 2629 | "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", 2630 | "dev": true 2631 | }, 2632 | "wrap-ansi": { 2633 | "version": "6.2.0", 2634 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", 2635 | "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", 2636 | "dev": true, 2637 | "requires": { 2638 | "ansi-styles": "^4.0.0", 2639 | "string-width": "^4.1.0", 2640 | "strip-ansi": "^6.0.0" 2641 | }, 2642 | "dependencies": { 2643 | "ansi-styles": { 2644 | "version": "4.3.0", 2645 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", 2646 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", 2647 | "dev": true, 2648 | "requires": { 2649 | "color-convert": "^2.0.1" 2650 | } 2651 | }, 2652 | "color-convert": { 2653 | "version": "2.0.1", 2654 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", 2655 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", 2656 | "dev": true, 2657 | "requires": { 2658 | "color-name": "~1.1.4" 2659 | } 2660 | }, 2661 | "color-name": { 2662 | "version": "1.1.4", 2663 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", 2664 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", 2665 | "dev": true 2666 | }, 2667 | "emoji-regex": { 2668 | "version": "8.0.0", 2669 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", 2670 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", 2671 | "dev": true 2672 | }, 2673 | "is-fullwidth-code-point": { 2674 | "version": "3.0.0", 2675 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", 2676 | "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", 2677 | "dev": true 2678 | }, 2679 | "string-width": { 2680 | "version": "4.2.0", 2681 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", 2682 | "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", 2683 | "dev": true, 2684 | "requires": { 2685 | "emoji-regex": "^8.0.0", 2686 | "is-fullwidth-code-point": "^3.0.0", 2687 | "strip-ansi": "^6.0.0" 2688 | } 2689 | } 2690 | } 2691 | }, 2692 | "wrappy": { 2693 | "version": "1.0.2", 2694 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 2695 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", 2696 | "dev": true 2697 | }, 2698 | "write-file-atomic": { 2699 | "version": "3.0.3", 2700 | "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", 2701 | "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", 2702 | "dev": true, 2703 | "requires": { 2704 | "imurmurhash": "^0.1.4", 2705 | "is-typedarray": "^1.0.0", 2706 | "signal-exit": "^3.0.2", 2707 | "typedarray-to-buffer": "^3.1.5" 2708 | } 2709 | }, 2710 | "ws": { 2711 | "version": "7.2.3", 2712 | "resolved": "https://registry.npmjs.org/ws/-/ws-7.2.3.tgz", 2713 | "integrity": "sha512-HTDl9G9hbkNDk98naoR/cHDws7+EyYMOdL1BmjsZXRUjf7d+MficC4B7HLUPlSiho0vg+CWKrGIt/VJBd1xunQ==", 2714 | "dev": true 2715 | }, 2716 | "y18n": { 2717 | "version": "4.0.1", 2718 | "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz", 2719 | "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==", 2720 | "dev": true 2721 | }, 2722 | "yallist": { 2723 | "version": "4.0.0", 2724 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", 2725 | "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", 2726 | "dev": true 2727 | }, 2728 | "yargs": { 2729 | "version": "15.4.1", 2730 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", 2731 | "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", 2732 | "dev": true, 2733 | "requires": { 2734 | "cliui": "^6.0.0", 2735 | "decamelize": "^1.2.0", 2736 | "find-up": "^4.1.0", 2737 | "get-caller-file": "^2.0.1", 2738 | "require-directory": "^2.1.1", 2739 | "require-main-filename": "^2.0.0", 2740 | "set-blocking": "^2.0.0", 2741 | "string-width": "^4.2.0", 2742 | "which-module": "^2.0.0", 2743 | "y18n": "^4.0.0", 2744 | "yargs-parser": "^18.1.2" 2745 | }, 2746 | "dependencies": { 2747 | "emoji-regex": { 2748 | "version": "8.0.0", 2749 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", 2750 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", 2751 | "dev": true 2752 | }, 2753 | "is-fullwidth-code-point": { 2754 | "version": "3.0.0", 2755 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", 2756 | "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", 2757 | "dev": true 2758 | }, 2759 | "string-width": { 2760 | "version": "4.2.0", 2761 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", 2762 | "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", 2763 | "dev": true, 2764 | "requires": { 2765 | "emoji-regex": "^8.0.0", 2766 | "is-fullwidth-code-point": "^3.0.0", 2767 | "strip-ansi": "^6.0.0" 2768 | } 2769 | } 2770 | } 2771 | }, 2772 | "yargs-parser": { 2773 | "version": "18.1.3", 2774 | "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", 2775 | "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", 2776 | "dev": true, 2777 | "requires": { 2778 | "camelcase": "^5.0.0", 2779 | "decamelize": "^1.2.0" 2780 | } 2781 | }, 2782 | "yn": { 2783 | "version": "3.1.1", 2784 | "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", 2785 | "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==" 2786 | } 2787 | } 2788 | } 2789 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@flashbots/simple-arbitrage", 3 | "version": "0.0.1", 4 | "description": "", 5 | "main": "build/index.js", 6 | "types": "build/index.d.ts", 7 | "scripts": { 8 | "start": "npx ts-node --project tsconfig.json src/index.ts", 9 | "test": "npx ts-node node_modules/jasmine/bin/jasmine --config=jasmine.json", 10 | "build": "npx tsc", 11 | "prepare": "npm run build", 12 | "lint": "npx eslint src" 13 | }, 14 | "author": "", 15 | "license": "ISC", 16 | "devDependencies": { 17 | "@types/jasmine": "^3.6.2", 18 | "@types/lodash": "^4.14.165", 19 | "@types/node": "^14.14.10", 20 | "@typescript-eslint/eslint-plugin": "^4.9.1", 21 | "@typescript-eslint/parser": "^4.9.1", 22 | "eslint": "^7.15.0", 23 | "ethers": "^5.0.23", 24 | "jasmine": "^3.6.3", 25 | "nyc": "^15.1.0" 26 | }, 27 | "peerDependencies": { 28 | "ethers": "^5.0.23" 29 | }, 30 | "dependencies": { 31 | "@flashbots/ethers-provider-bundle": "^0.3.1", 32 | "lodash": "^4.17.21", 33 | "ts-node": "^9.1.0", 34 | "typescript": "^4.1.2" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Arbitrage.ts: -------------------------------------------------------------------------------- 1 | import * as _ from "lodash"; 2 | import { BigNumber, Contract, Wallet } from "ethers"; 3 | import { FlashbotsBundleProvider } from "@flashbots/ethers-provider-bundle"; 4 | import { WETH_ADDRESS } from "./addresses"; 5 | import { EthMarket } from "./EthMarket"; 6 | import { ETHER, bigNumberToDecimal } from "./utils"; 7 | 8 | export interface CrossedMarketDetails { 9 | profit: BigNumber, 10 | volume: BigNumber, 11 | tokenAddress: string, 12 | buyFromMarket: EthMarket, 13 | sellToMarket: EthMarket, 14 | } 15 | 16 | export type MarketsByToken = { [tokenAddress: string]: Array } 17 | 18 | // TODO: implement binary search (assuming linear/exponential global maximum profitability) 19 | const TEST_VOLUMES = [ 20 | ETHER.div(100), 21 | ETHER.div(10), 22 | ETHER.div(6), 23 | ETHER.div(4), 24 | ETHER.div(2), 25 | ETHER.div(1), 26 | ETHER.mul(2), 27 | ETHER.mul(5), 28 | ETHER.mul(10), 29 | ] 30 | 31 | export function getBestCrossedMarket(crossedMarkets: Array[], tokenAddress: string): CrossedMarketDetails | undefined { 32 | let bestCrossedMarket: CrossedMarketDetails | undefined = undefined; 33 | for (const crossedMarket of crossedMarkets) { 34 | const sellToMarket = crossedMarket[0] 35 | const buyFromMarket = crossedMarket[1] 36 | for (const size of TEST_VOLUMES) { 37 | const tokensOutFromBuyingSize = buyFromMarket.getTokensOut(WETH_ADDRESS, tokenAddress, size); 38 | const proceedsFromSellingTokens = sellToMarket.getTokensOut(tokenAddress, WETH_ADDRESS, tokensOutFromBuyingSize) 39 | const profit = proceedsFromSellingTokens.sub(size); 40 | if (bestCrossedMarket !== undefined && profit.lt(bestCrossedMarket.profit)) { 41 | // If the next size up lost value, meet halfway. TODO: replace with real binary search 42 | const trySize = size.add(bestCrossedMarket.volume).div(2) 43 | const tryTokensOutFromBuyingSize = buyFromMarket.getTokensOut(WETH_ADDRESS, tokenAddress, trySize); 44 | const tryProceedsFromSellingTokens = sellToMarket.getTokensOut(tokenAddress, WETH_ADDRESS, tryTokensOutFromBuyingSize) 45 | const tryProfit = tryProceedsFromSellingTokens.sub(trySize); 46 | if (tryProfit.gt(bestCrossedMarket.profit)) { 47 | bestCrossedMarket = { 48 | volume: trySize, 49 | profit: tryProfit, 50 | tokenAddress, 51 | sellToMarket, 52 | buyFromMarket 53 | } 54 | } 55 | break; 56 | } 57 | bestCrossedMarket = { 58 | volume: size, 59 | profit: profit, 60 | tokenAddress, 61 | sellToMarket, 62 | buyFromMarket 63 | } 64 | } 65 | } 66 | return bestCrossedMarket; 67 | } 68 | 69 | export class Arbitrage { 70 | private flashbotsProvider: FlashbotsBundleProvider; 71 | private bundleExecutorContract: Contract; 72 | private executorWallet: Wallet; 73 | 74 | constructor(executorWallet: Wallet, flashbotsProvider: FlashbotsBundleProvider, bundleExecutorContract: Contract) { 75 | this.executorWallet = executorWallet; 76 | this.flashbotsProvider = flashbotsProvider; 77 | this.bundleExecutorContract = bundleExecutorContract; 78 | } 79 | 80 | static printCrossedMarket(crossedMarket: CrossedMarketDetails): void { 81 | const buyTokens = crossedMarket.buyFromMarket.tokens 82 | const sellTokens = crossedMarket.sellToMarket.tokens 83 | console.log( 84 | `Profit: ${bigNumberToDecimal(crossedMarket.profit)} Volume: ${bigNumberToDecimal(crossedMarket.volume)}\n` + 85 | `${crossedMarket.buyFromMarket.protocol} (${crossedMarket.buyFromMarket.marketAddress})\n` + 86 | ` ${buyTokens[0]} => ${buyTokens[1]}\n` + 87 | `${crossedMarket.sellToMarket.protocol} (${crossedMarket.sellToMarket.marketAddress})\n` + 88 | ` ${sellTokens[0]} => ${sellTokens[1]}\n` + 89 | `\n` 90 | ) 91 | } 92 | 93 | 94 | async evaluateMarkets(marketsByToken: MarketsByToken): Promise> { 95 | const bestCrossedMarkets = new Array() 96 | 97 | for (const tokenAddress in marketsByToken) { 98 | const markets = marketsByToken[tokenAddress] 99 | const pricedMarkets = _.map(markets, (ethMarket: EthMarket) => { 100 | return { 101 | ethMarket: ethMarket, 102 | buyTokenPrice: ethMarket.getTokensIn(tokenAddress, WETH_ADDRESS, ETHER.div(100)), 103 | sellTokenPrice: ethMarket.getTokensOut(WETH_ADDRESS, tokenAddress, ETHER.div(100)), 104 | } 105 | }); 106 | 107 | const crossedMarkets = new Array>() 108 | for (const pricedMarket of pricedMarkets) { 109 | _.forEach(pricedMarkets, pm => { 110 | if (pm.sellTokenPrice.gt(pricedMarket.buyTokenPrice)) { 111 | crossedMarkets.push([pricedMarket.ethMarket, pm.ethMarket]) 112 | } 113 | }) 114 | } 115 | 116 | const bestCrossedMarket = getBestCrossedMarket(crossedMarkets, tokenAddress); 117 | if (bestCrossedMarket !== undefined && bestCrossedMarket.profit.gt(ETHER.div(1000))) { 118 | bestCrossedMarkets.push(bestCrossedMarket) 119 | } 120 | } 121 | bestCrossedMarkets.sort((a, b) => a.profit.lt(b.profit) ? 1 : a.profit.gt(b.profit) ? -1 : 0) 122 | return bestCrossedMarkets 123 | } 124 | 125 | // TODO: take more than 1 126 | async takeCrossedMarkets(bestCrossedMarkets: CrossedMarketDetails[], blockNumber: number, minerRewardPercentage: number): Promise { 127 | for (const bestCrossedMarket of bestCrossedMarkets) { 128 | 129 | console.log("Send this much WETH", bestCrossedMarket.volume.toString(), "get this much profit", bestCrossedMarket.profit.toString()) 130 | const buyCalls = await bestCrossedMarket.buyFromMarket.sellTokensToNextMarket(WETH_ADDRESS, bestCrossedMarket.volume, bestCrossedMarket.sellToMarket); 131 | const inter = bestCrossedMarket.buyFromMarket.getTokensOut(WETH_ADDRESS, bestCrossedMarket.tokenAddress, bestCrossedMarket.volume) 132 | const sellCallData = await bestCrossedMarket.sellToMarket.sellTokens(bestCrossedMarket.tokenAddress, inter, this.bundleExecutorContract.address); 133 | 134 | const targets: Array = [...buyCalls.targets, bestCrossedMarket.sellToMarket.marketAddress] 135 | const payloads: Array = [...buyCalls.data, sellCallData] 136 | console.log({targets, payloads}) 137 | const minerReward = bestCrossedMarket.profit.mul(minerRewardPercentage).div(100); 138 | const transaction = await this.bundleExecutorContract.populateTransaction.uniswapWeth(bestCrossedMarket.volume, minerReward, targets, payloads, { 139 | gasPrice: BigNumber.from(0), 140 | gasLimit: BigNumber.from(1000000), 141 | }); 142 | 143 | try { 144 | const estimateGas = await this.bundleExecutorContract.provider.estimateGas( 145 | { 146 | ...transaction, 147 | from: this.executorWallet.address 148 | }) 149 | if (estimateGas.gt(1400000)) { 150 | console.log("EstimateGas succeeded, but suspiciously large: " + estimateGas.toString()) 151 | continue 152 | } 153 | transaction.gasLimit = estimateGas.mul(2) 154 | } catch (e) { 155 | console.warn(`Estimate gas failure for ${JSON.stringify(bestCrossedMarket)}`) 156 | continue 157 | } 158 | const bundledTransactions = [ 159 | { 160 | signer: this.executorWallet, 161 | transaction: transaction 162 | } 163 | ]; 164 | console.log(bundledTransactions) 165 | const signedBundle = await this.flashbotsProvider.signBundle(bundledTransactions) 166 | // 167 | const simulation = await this.flashbotsProvider.simulate(signedBundle, blockNumber + 1 ) 168 | if ("error" in simulation || simulation.firstRevert !== undefined) { 169 | console.log(`Simulation Error on token ${bestCrossedMarket.tokenAddress}, skipping`) 170 | continue 171 | } 172 | console.log(`Submitting bundle, profit sent to miner: ${bigNumberToDecimal(simulation.coinbaseDiff)}, effective gas price: ${bigNumberToDecimal(simulation.coinbaseDiff.div(simulation.totalGasUsed), 9)} GWEI`) 173 | const bundlePromises = _.map([blockNumber + 1, blockNumber + 2], targetBlockNumber => 174 | this.flashbotsProvider.sendRawBundle( 175 | signedBundle, 176 | targetBlockNumber 177 | )) 178 | await Promise.all(bundlePromises) 179 | return 180 | } 181 | throw new Error("No arbitrage submitted to relay") 182 | } 183 | } 184 | -------------------------------------------------------------------------------- /src/EthMarket.ts: -------------------------------------------------------------------------------- 1 | import { BigNumber } from "ethers"; 2 | 3 | export interface TokenBalances { 4 | [tokenAddress: string]: BigNumber 5 | } 6 | 7 | export interface MultipleCallData { 8 | targets: Array 9 | data: Array 10 | } 11 | 12 | export interface CallDetails { 13 | target: string; 14 | data: string; 15 | value?: BigNumber; 16 | } 17 | 18 | export abstract class EthMarket { 19 | get tokens(): Array { 20 | return this._tokens; 21 | } 22 | 23 | get marketAddress(): string { 24 | return this._marketAddress; 25 | } 26 | 27 | get protocol(): string { 28 | return this._protocol; 29 | } 30 | 31 | protected readonly _tokens: Array; 32 | protected readonly _marketAddress: string; 33 | protected readonly _protocol: string; 34 | 35 | constructor(marketAddress: string, tokens: Array, protocol: string) { 36 | this._marketAddress = marketAddress; 37 | this._tokens = tokens 38 | this._protocol = protocol; 39 | } 40 | 41 | 42 | abstract getTokensOut(tokenIn: string, tokenOut: string, amountIn: BigNumber): BigNumber; 43 | 44 | abstract getTokensIn(tokenIn: string, tokenOut: string, amountOut: BigNumber): BigNumber; 45 | 46 | abstract sellTokensToNextMarket(tokenIn: string, amountIn: BigNumber, ethMarket: EthMarket): Promise 47 | 48 | abstract sellTokens(tokenIn: string, amountIn: BigNumber, recipient: string): Promise 49 | 50 | abstract receiveDirectly(tokenAddress: string): boolean; 51 | 52 | abstract prepareReceive(tokenAddress: string, amountIn: BigNumber): Promise> 53 | } 54 | -------------------------------------------------------------------------------- /src/UniswappyV2EthPair.ts: -------------------------------------------------------------------------------- 1 | import * as _ from "lodash"; 2 | import { BigNumber, Contract, providers } from "ethers"; 3 | import { UNISWAP_PAIR_ABI, UNISWAP_QUERY_ABI } from "./abi"; 4 | import { UNISWAP_LOOKUP_CONTRACT_ADDRESS, WETH_ADDRESS } from "./addresses"; 5 | import { CallDetails, EthMarket, MultipleCallData, TokenBalances } from "./EthMarket"; 6 | import { ETHER } from "./utils"; 7 | import { MarketsByToken } from "./Arbitrage"; 8 | 9 | // batch count limit helpful for testing, loading entire set of uniswap markets takes a long time to load 10 | const BATCH_COUNT_LIMIT = 100; 11 | const UNISWAP_BATCH_SIZE = 1000 12 | 13 | // Not necessary, slightly speeds up loading initialization when we know tokens are bad 14 | // Estimate gas will ensure we aren't submitting bad bundles, but bad tokens waste time 15 | const blacklistTokens = [ 16 | '0xD75EA151a61d06868E31F8988D28DFE5E9df57B4' 17 | ] 18 | 19 | interface GroupedMarkets { 20 | marketsByToken: MarketsByToken; 21 | allMarketPairs: Array; 22 | } 23 | 24 | export class UniswappyV2EthPair extends EthMarket { 25 | static uniswapInterface = new Contract(WETH_ADDRESS, UNISWAP_PAIR_ABI); 26 | private _tokenBalances: TokenBalances 27 | 28 | constructor(marketAddress: string, tokens: Array, protocol: string) { 29 | super(marketAddress, tokens, protocol); 30 | this._tokenBalances = _.zipObject(tokens,[BigNumber.from(0), BigNumber.from(0)]) 31 | } 32 | 33 | receiveDirectly(tokenAddress: string): boolean { 34 | return tokenAddress in this._tokenBalances 35 | } 36 | 37 | async prepareReceive(tokenAddress: string, amountIn: BigNumber): Promise> { 38 | if (this._tokenBalances[tokenAddress] === undefined) { 39 | throw new Error(`Market does not operate on token ${tokenAddress}`) 40 | } 41 | if (! amountIn.gt(0)) { 42 | throw new Error(`Invalid amount: ${amountIn.toString()}`) 43 | } 44 | // No preparation necessary 45 | return [] 46 | } 47 | 48 | static async getUniswappyMarkets(provider: providers.JsonRpcProvider, factoryAddress: string): Promise> { 49 | const uniswapQuery = new Contract(UNISWAP_LOOKUP_CONTRACT_ADDRESS, UNISWAP_QUERY_ABI, provider); 50 | 51 | const marketPairs = new Array() 52 | for (let i = 0; i < BATCH_COUNT_LIMIT * UNISWAP_BATCH_SIZE; i += UNISWAP_BATCH_SIZE) { 53 | const pairs: Array> = (await uniswapQuery.functions.getPairsByIndexRange(factoryAddress, i, i + UNISWAP_BATCH_SIZE))[0]; 54 | for (let i = 0; i < pairs.length; i++) { 55 | const pair = pairs[i]; 56 | const marketAddress = pair[2]; 57 | let tokenAddress: string; 58 | 59 | if (pair[0] === WETH_ADDRESS) { 60 | tokenAddress = pair[1] 61 | } else if (pair[1] === WETH_ADDRESS) { 62 | tokenAddress = pair[0] 63 | } else { 64 | continue; 65 | } 66 | if (!blacklistTokens.includes(tokenAddress)) { 67 | const uniswappyV2EthPair = new UniswappyV2EthPair(marketAddress, [pair[0], pair[1]], ""); 68 | marketPairs.push(uniswappyV2EthPair); 69 | } 70 | } 71 | if (pairs.length < UNISWAP_BATCH_SIZE) { 72 | break 73 | } 74 | } 75 | 76 | return marketPairs 77 | } 78 | 79 | static async getUniswapMarketsByToken(provider: providers.JsonRpcProvider, factoryAddresses: Array): Promise { 80 | const allPairs = await Promise.all( 81 | _.map(factoryAddresses, factoryAddress => UniswappyV2EthPair.getUniswappyMarkets(provider, factoryAddress)) 82 | ) 83 | 84 | const marketsByTokenAll = _.chain(allPairs) 85 | .flatten() 86 | .groupBy(pair => pair.tokens[0] === WETH_ADDRESS ? pair.tokens[1] : pair.tokens[0]) 87 | .value() 88 | 89 | const allMarketPairs = _.chain( 90 | _.pickBy(marketsByTokenAll, a => a.length > 1) // weird TS bug, chain'd pickBy is Partial<> 91 | ) 92 | .values() 93 | .flatten() 94 | .value() 95 | 96 | await UniswappyV2EthPair.updateReserves(provider, allMarketPairs); 97 | 98 | const marketsByToken = _.chain(allMarketPairs) 99 | .filter(pair => (pair.getBalance(WETH_ADDRESS).gt(ETHER))) 100 | .groupBy(pair => pair.tokens[0] === WETH_ADDRESS ? pair.tokens[1] : pair.tokens[0]) 101 | .value() 102 | 103 | return { 104 | marketsByToken, 105 | allMarketPairs 106 | } 107 | } 108 | 109 | static async updateReserves(provider: providers.JsonRpcProvider, allMarketPairs: Array): Promise { 110 | const uniswapQuery = new Contract(UNISWAP_LOOKUP_CONTRACT_ADDRESS, UNISWAP_QUERY_ABI, provider); 111 | const pairAddresses = allMarketPairs.map(marketPair => marketPair.marketAddress); 112 | console.log("Updating markets, count:", pairAddresses.length) 113 | const reserves: Array> = (await uniswapQuery.functions.getReservesByPairs(pairAddresses))[0]; 114 | for (let i = 0; i < allMarketPairs.length; i++) { 115 | const marketPair = allMarketPairs[i]; 116 | const reserve = reserves[i] 117 | marketPair.setReservesViaOrderedBalances([reserve[0], reserve[1]]) 118 | } 119 | } 120 | 121 | getBalance(tokenAddress: string): BigNumber { 122 | const balance = this._tokenBalances[tokenAddress] 123 | if (balance === undefined) throw new Error("bad token") 124 | return balance; 125 | } 126 | 127 | setReservesViaOrderedBalances(balances: Array): void { 128 | this.setReservesViaMatchingArray(this._tokens, balances) 129 | } 130 | 131 | setReservesViaMatchingArray(tokens: Array, balances: Array): void { 132 | const tokenBalances = _.zipObject(tokens, balances) 133 | if (!_.isEqual(this._tokenBalances, tokenBalances)) { 134 | this._tokenBalances = tokenBalances 135 | } 136 | } 137 | 138 | getTokensIn(tokenIn: string, tokenOut: string, amountOut: BigNumber): BigNumber { 139 | const reserveIn = this._tokenBalances[tokenIn] 140 | const reserveOut = this._tokenBalances[tokenOut] 141 | return this.getAmountIn(reserveIn, reserveOut, amountOut); 142 | } 143 | 144 | getTokensOut(tokenIn: string, tokenOut: string, amountIn: BigNumber): BigNumber { 145 | const reserveIn = this._tokenBalances[tokenIn] 146 | const reserveOut = this._tokenBalances[tokenOut] 147 | return this.getAmountOut(reserveIn, reserveOut, amountIn); 148 | } 149 | 150 | getAmountIn(reserveIn: BigNumber, reserveOut: BigNumber, amountOut: BigNumber): BigNumber { 151 | const numerator: BigNumber = reserveIn.mul(amountOut).mul(1000); 152 | const denominator: BigNumber = reserveOut.sub(amountOut).mul(997); 153 | return numerator.div(denominator).add(1); 154 | } 155 | 156 | getAmountOut(reserveIn: BigNumber, reserveOut: BigNumber, amountIn: BigNumber): BigNumber { 157 | const amountInWithFee: BigNumber = amountIn.mul(997); 158 | const numerator = amountInWithFee.mul(reserveOut); 159 | const denominator = reserveIn.mul(1000).add(amountInWithFee); 160 | return numerator.div(denominator); 161 | } 162 | 163 | async sellTokensToNextMarket(tokenIn: string, amountIn: BigNumber, ethMarket: EthMarket): Promise { 164 | if (ethMarket.receiveDirectly(tokenIn) === true) { 165 | const exchangeCall = await this.sellTokens(tokenIn, amountIn, ethMarket.marketAddress) 166 | return { 167 | data: [exchangeCall], 168 | targets: [this.marketAddress] 169 | } 170 | } 171 | 172 | const exchangeCall = await this.sellTokens(tokenIn, amountIn, ethMarket.marketAddress) 173 | return { 174 | data: [exchangeCall], 175 | targets: [this.marketAddress] 176 | } 177 | } 178 | 179 | async sellTokens(tokenIn: string, amountIn: BigNumber, recipient: string): Promise { 180 | // function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external lock { 181 | let amount0Out = BigNumber.from(0) 182 | let amount1Out = BigNumber.from(0) 183 | let tokenOut: string; 184 | if (tokenIn === this.tokens[0]) { 185 | tokenOut = this.tokens[1] 186 | amount1Out = this.getTokensOut(tokenIn, tokenOut, amountIn) 187 | } else if (tokenIn === this.tokens[1]) { 188 | tokenOut = this.tokens[0] 189 | amount0Out = this.getTokensOut(tokenIn, tokenOut, amountIn) 190 | } else { 191 | throw new Error("Bad token input address") 192 | } 193 | const populatedTransaction = await UniswappyV2EthPair.uniswapInterface.populateTransaction.swap(amount0Out, amount1Out, recipient, []); 194 | if (populatedTransaction === undefined || populatedTransaction.data === undefined) throw new Error("HI") 195 | return populatedTransaction.data; 196 | } 197 | } 198 | -------------------------------------------------------------------------------- /src/abi.ts: -------------------------------------------------------------------------------- 1 | export const UNISWAP_QUERY_ABI = [{ 2 | "inputs": [{ 3 | "internalType": "contract UniswapV2Factory", 4 | "name": "_uniswapFactory", 5 | "type": "address" 6 | }, {"internalType": "uint256", "name": "_start", "type": "uint256"}, { 7 | "internalType": "uint256", 8 | "name": "_stop", 9 | "type": "uint256" 10 | }], 11 | "name": "getPairsByIndexRange", 12 | "outputs": [{"internalType": "address[3][]", "name": "", "type": "address[3][]"}], 13 | "stateMutability": "view", 14 | "type": "function" 15 | }, { 16 | "inputs": [{"internalType": "contract IUniswapV2Pair[]", "name": "_pairs", "type": "address[]"}], 17 | "name": "getReservesByPairs", 18 | "outputs": [{"internalType": "uint256[3][]", "name": "", "type": "uint256[3][]"}], 19 | "stateMutability": "view", 20 | "type": "function" 21 | }] 22 | 23 | export const BUNDLE_EXECUTOR_ABI = [{ 24 | "inputs": [{ 25 | "internalType": "address payable", 26 | "name": "_to", 27 | "type": "address" 28 | }, {"internalType": "uint256", "name": "_value", "type": "uint256"}, { 29 | "internalType": "bytes", 30 | "name": "_data", 31 | "type": "bytes" 32 | }], 33 | "name": "call", 34 | "outputs": [{"internalType": "bytes", "name": "", "type": "bytes"}], 35 | "stateMutability": "payable", 36 | "type": "function" 37 | }, { 38 | "inputs": [{"internalType": "address", "name": "_executor", "type": "address"}], 39 | "stateMutability": "payable", 40 | "type": "constructor" 41 | }, { 42 | "inputs": [{ 43 | "internalType": "uint256", 44 | "name": "_wethAmountToFirstMarket", 45 | "type": "uint256" 46 | }, {"internalType": "uint256", "name": "_ethAmountToCoinbase", "type": "uint256"}, { 47 | "internalType": "address[]", 48 | "name": "_targets", 49 | "type": "address[]" 50 | }, {"internalType": "bytes[]", "name": "_payloads", "type": "bytes[]"}], 51 | "name": "uniswapWeth", 52 | "outputs": [], 53 | "stateMutability": "payable", 54 | "type": "function" 55 | }, {"stateMutability": "payable", "type": "receive"}] 56 | 57 | 58 | export const UNISWAP_PAIR_ABI = [{ 59 | "inputs": [], 60 | "payable": false, 61 | "stateMutability": "nonpayable", 62 | "type": "constructor" 63 | }, { 64 | "anonymous": false, 65 | "inputs": [{"indexed": true, "internalType": "address", "name": "owner", "type": "address"}, { 66 | "indexed": true, 67 | "internalType": "address", 68 | "name": "spender", 69 | "type": "address" 70 | }, {"indexed": false, "internalType": "uint256", "name": "value", "type": "uint256"}], 71 | "name": "Approval", 72 | "type": "event" 73 | }, { 74 | "anonymous": false, 75 | "inputs": [{"indexed": true, "internalType": "address", "name": "sender", "type": "address"}, { 76 | "indexed": false, 77 | "internalType": "uint256", 78 | "name": "amount0", 79 | "type": "uint256" 80 | }, {"indexed": false, "internalType": "uint256", "name": "amount1", "type": "uint256"}, { 81 | "indexed": true, 82 | "internalType": "address", 83 | "name": "to", 84 | "type": "address" 85 | }], 86 | "name": "Burn", 87 | "type": "event" 88 | }, { 89 | "anonymous": false, 90 | "inputs": [{"indexed": true, "internalType": "address", "name": "sender", "type": "address"}, { 91 | "indexed": false, 92 | "internalType": "uint256", 93 | "name": "amount0", 94 | "type": "uint256" 95 | }, {"indexed": false, "internalType": "uint256", "name": "amount1", "type": "uint256"}], 96 | "name": "Mint", 97 | "type": "event" 98 | }, { 99 | "anonymous": false, 100 | "inputs": [{"indexed": true, "internalType": "address", "name": "sender", "type": "address"}, { 101 | "indexed": false, 102 | "internalType": "uint256", 103 | "name": "amount0In", 104 | "type": "uint256" 105 | }, {"indexed": false, "internalType": "uint256", "name": "amount1In", "type": "uint256"}, { 106 | "indexed": false, 107 | "internalType": "uint256", 108 | "name": "amount0Out", 109 | "type": "uint256" 110 | }, {"indexed": false, "internalType": "uint256", "name": "amount1Out", "type": "uint256"}, { 111 | "indexed": true, 112 | "internalType": "address", 113 | "name": "to", 114 | "type": "address" 115 | }], 116 | "name": "Swap", 117 | "type": "event" 118 | }, { 119 | "anonymous": false, 120 | "inputs": [{"indexed": false, "internalType": "uint112", "name": "reserve0", "type": "uint112"}, { 121 | "indexed": false, 122 | "internalType": "uint112", 123 | "name": "reserve1", 124 | "type": "uint112" 125 | }], 126 | "name": "Sync", 127 | "type": "event" 128 | }, { 129 | "anonymous": false, 130 | "inputs": [{"indexed": true, "internalType": "address", "name": "from", "type": "address"}, { 131 | "indexed": true, 132 | "internalType": "address", 133 | "name": "to", 134 | "type": "address" 135 | }, {"indexed": false, "internalType": "uint256", "name": "value", "type": "uint256"}], 136 | "name": "Transfer", 137 | "type": "event" 138 | }, { 139 | "constant": true, 140 | "inputs": [], 141 | "name": "DOMAIN_SEPARATOR", 142 | "outputs": [{"internalType": "bytes32", "name": "", "type": "bytes32"}], 143 | "payable": false, 144 | "stateMutability": "view", 145 | "type": "function" 146 | }, { 147 | "constant": true, 148 | "inputs": [], 149 | "name": "MINIMUM_LIQUIDITY", 150 | "outputs": [{"internalType": "uint256", "name": "", "type": "uint256"}], 151 | "payable": false, 152 | "stateMutability": "view", 153 | "type": "function" 154 | }, { 155 | "constant": true, 156 | "inputs": [], 157 | "name": "PERMIT_TYPEHASH", 158 | "outputs": [{"internalType": "bytes32", "name": "", "type": "bytes32"}], 159 | "payable": false, 160 | "stateMutability": "view", 161 | "type": "function" 162 | }, { 163 | "constant": true, 164 | "inputs": [{"internalType": "address", "name": "", "type": "address"}, { 165 | "internalType": "address", 166 | "name": "", 167 | "type": "address" 168 | }], 169 | "name": "allowance", 170 | "outputs": [{"internalType": "uint256", "name": "", "type": "uint256"}], 171 | "payable": false, 172 | "stateMutability": "view", 173 | "type": "function" 174 | }, { 175 | "constant": false, 176 | "inputs": [{"internalType": "address", "name": "spender", "type": "address"}, { 177 | "internalType": "uint256", 178 | "name": "value", 179 | "type": "uint256" 180 | }], 181 | "name": "approve", 182 | "outputs": [{"internalType": "bool", "name": "", "type": "bool"}], 183 | "payable": false, 184 | "stateMutability": "nonpayable", 185 | "type": "function" 186 | }, { 187 | "constant": true, 188 | "inputs": [{"internalType": "address", "name": "", "type": "address"}], 189 | "name": "balanceOf", 190 | "outputs": [{"internalType": "uint256", "name": "", "type": "uint256"}], 191 | "payable": false, 192 | "stateMutability": "view", 193 | "type": "function" 194 | }, { 195 | "constant": false, 196 | "inputs": [{"internalType": "address", "name": "to", "type": "address"}], 197 | "name": "burn", 198 | "outputs": [{"internalType": "uint256", "name": "amount0", "type": "uint256"}, { 199 | "internalType": "uint256", 200 | "name": "amount1", 201 | "type": "uint256" 202 | }], 203 | "payable": false, 204 | "stateMutability": "nonpayable", 205 | "type": "function" 206 | }, { 207 | "constant": true, 208 | "inputs": [], 209 | "name": "decimals", 210 | "outputs": [{"internalType": "uint8", "name": "", "type": "uint8"}], 211 | "payable": false, 212 | "stateMutability": "view", 213 | "type": "function" 214 | }, { 215 | "constant": true, 216 | "inputs": [], 217 | "name": "factory", 218 | "outputs": [{"internalType": "address", "name": "", "type": "address"}], 219 | "payable": false, 220 | "stateMutability": "view", 221 | "type": "function" 222 | }, { 223 | "constant": true, 224 | "inputs": [], 225 | "name": "getReserves", 226 | "outputs": [{"internalType": "uint112", "name": "_reserve0", "type": "uint112"}, { 227 | "internalType": "uint112", 228 | "name": "_reserve1", 229 | "type": "uint112" 230 | }, {"internalType": "uint32", "name": "_blockTimestampLast", "type": "uint32"}], 231 | "payable": false, 232 | "stateMutability": "view", 233 | "type": "function" 234 | }, { 235 | "constant": false, 236 | "inputs": [{"internalType": "address", "name": "_token0", "type": "address"}, { 237 | "internalType": "address", 238 | "name": "_token1", 239 | "type": "address" 240 | }], 241 | "name": "initialize", 242 | "outputs": [], 243 | "payable": false, 244 | "stateMutability": "nonpayable", 245 | "type": "function" 246 | }, { 247 | "constant": true, 248 | "inputs": [], 249 | "name": "kLast", 250 | "outputs": [{"internalType": "uint256", "name": "", "type": "uint256"}], 251 | "payable": false, 252 | "stateMutability": "view", 253 | "type": "function" 254 | }, { 255 | "constant": false, 256 | "inputs": [{"internalType": "address", "name": "to", "type": "address"}], 257 | "name": "mint", 258 | "outputs": [{"internalType": "uint256", "name": "liquidity", "type": "uint256"}], 259 | "payable": false, 260 | "stateMutability": "nonpayable", 261 | "type": "function" 262 | }, { 263 | "constant": true, 264 | "inputs": [], 265 | "name": "name", 266 | "outputs": [{"internalType": "string", "name": "", "type": "string"}], 267 | "payable": false, 268 | "stateMutability": "view", 269 | "type": "function" 270 | }, { 271 | "constant": true, 272 | "inputs": [{"internalType": "address", "name": "", "type": "address"}], 273 | "name": "nonces", 274 | "outputs": [{"internalType": "uint256", "name": "", "type": "uint256"}], 275 | "payable": false, 276 | "stateMutability": "view", 277 | "type": "function" 278 | }, { 279 | "constant": false, 280 | "inputs": [{"internalType": "address", "name": "owner", "type": "address"}, { 281 | "internalType": "address", 282 | "name": "spender", 283 | "type": "address" 284 | }, {"internalType": "uint256", "name": "value", "type": "uint256"}, { 285 | "internalType": "uint256", 286 | "name": "deadline", 287 | "type": "uint256" 288 | }, {"internalType": "uint8", "name": "v", "type": "uint8"}, { 289 | "internalType": "bytes32", 290 | "name": "r", 291 | "type": "bytes32" 292 | }, {"internalType": "bytes32", "name": "s", "type": "bytes32"}], 293 | "name": "permit", 294 | "outputs": [], 295 | "payable": false, 296 | "stateMutability": "nonpayable", 297 | "type": "function" 298 | }, { 299 | "constant": true, 300 | "inputs": [], 301 | "name": "price0CumulativeLast", 302 | "outputs": [{"internalType": "uint256", "name": "", "type": "uint256"}], 303 | "payable": false, 304 | "stateMutability": "view", 305 | "type": "function" 306 | }, { 307 | "constant": true, 308 | "inputs": [], 309 | "name": "price1CumulativeLast", 310 | "outputs": [{"internalType": "uint256", "name": "", "type": "uint256"}], 311 | "payable": false, 312 | "stateMutability": "view", 313 | "type": "function" 314 | }, { 315 | "constant": false, 316 | "inputs": [{"internalType": "address", "name": "to", "type": "address"}], 317 | "name": "skim", 318 | "outputs": [], 319 | "payable": false, 320 | "stateMutability": "nonpayable", 321 | "type": "function" 322 | }, { 323 | "constant": false, 324 | "inputs": [{"internalType": "uint256", "name": "amount0Out", "type": "uint256"}, { 325 | "internalType": "uint256", 326 | "name": "amount1Out", 327 | "type": "uint256" 328 | }, {"internalType": "address", "name": "to", "type": "address"}, { 329 | "internalType": "bytes", 330 | "name": "data", 331 | "type": "bytes" 332 | }], 333 | "name": "swap", 334 | "outputs": [], 335 | "payable": false, 336 | "stateMutability": "nonpayable", 337 | "type": "function" 338 | }, { 339 | "constant": true, 340 | "inputs": [], 341 | "name": "symbol", 342 | "outputs": [{"internalType": "string", "name": "", "type": "string"}], 343 | "payable": false, 344 | "stateMutability": "view", 345 | "type": "function" 346 | }, { 347 | "constant": false, 348 | "inputs": [], 349 | "name": "sync", 350 | "outputs": [], 351 | "payable": false, 352 | "stateMutability": "nonpayable", 353 | "type": "function" 354 | }, { 355 | "constant": true, 356 | "inputs": [], 357 | "name": "token0", 358 | "outputs": [{"internalType": "address", "name": "", "type": "address"}], 359 | "payable": false, 360 | "stateMutability": "view", 361 | "type": "function" 362 | }, { 363 | "constant": true, 364 | "inputs": [], 365 | "name": "token1", 366 | "outputs": [{"internalType": "address", "name": "", "type": "address"}], 367 | "payable": false, 368 | "stateMutability": "view", 369 | "type": "function" 370 | }, { 371 | "constant": true, 372 | "inputs": [], 373 | "name": "totalSupply", 374 | "outputs": [{"internalType": "uint256", "name": "", "type": "uint256"}], 375 | "payable": false, 376 | "stateMutability": "view", 377 | "type": "function" 378 | }, { 379 | "constant": false, 380 | "inputs": [{"internalType": "address", "name": "to", "type": "address"}, { 381 | "internalType": "uint256", 382 | "name": "value", 383 | "type": "uint256" 384 | }], 385 | "name": "transfer", 386 | "outputs": [{"internalType": "bool", "name": "", "type": "bool"}], 387 | "payable": false, 388 | "stateMutability": "nonpayable", 389 | "type": "function" 390 | }, { 391 | "constant": false, 392 | "inputs": [{"internalType": "address", "name": "from", "type": "address"}, { 393 | "internalType": "address", 394 | "name": "to", 395 | "type": "address" 396 | }, {"internalType": "uint256", "name": "value", "type": "uint256"}], 397 | "name": "transferFrom", 398 | "outputs": [{"internalType": "bool", "name": "", "type": "bool"}], 399 | "payable": false, 400 | "stateMutability": "nonpayable", 401 | "type": "function" 402 | }] 403 | -------------------------------------------------------------------------------- /src/addresses.ts: -------------------------------------------------------------------------------- 1 | export const UNISWAP_LOOKUP_CONTRACT_ADDRESS = '0x5EF1009b9FCD4fec3094a5564047e190D72Bd511' 2 | export const WETH_ADDRESS = '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2'; 3 | export const SUSHISWAP_FACTORY_ADDRESS = '0xC0AEe478e3658e2610c5F7A4A2E1777cE9e4f2Ac'; 4 | export const UNISWAP_FACTORY_ADDRESS = '0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f'; 5 | export const CRO_FACTORY_ADDRESS = "0x9DEB29c9a4c7A88a3C0257393b7f3335338D9A9D"; 6 | export const ZEUS_FACTORY_ADDRESS = "0xbdda21dd8da31d5bee0c9bb886c044ebb9b8906a"; 7 | export const LUA_FACTORY_ADDRESS = "0x0388c1e0f210abae597b7de712b9510c6c36c857"; 8 | 9 | export const FACTORY_ADDRESSES = [ 10 | CRO_FACTORY_ADDRESS, 11 | ZEUS_FACTORY_ADDRESS, 12 | LUA_FACTORY_ADDRESS, 13 | SUSHISWAP_FACTORY_ADDRESS, 14 | UNISWAP_FACTORY_ADDRESS, 15 | ] 16 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import { FlashbotsBundleProvider } from "@flashbots/ethers-provider-bundle"; 2 | import { Contract, providers, Wallet } from "ethers"; 3 | import { BUNDLE_EXECUTOR_ABI } from "./abi"; 4 | import { UniswappyV2EthPair } from "./UniswappyV2EthPair"; 5 | import { FACTORY_ADDRESSES } from "./addresses"; 6 | import { Arbitrage } from "./Arbitrage"; 7 | import { get } from "https" 8 | import { getDefaultRelaySigningKey } from "./utils"; 9 | 10 | const ETHEREUM_RPC_URL = process.env.ETHEREUM_RPC_URL || "http://127.0.0.1:8545" 11 | const PRIVATE_KEY = process.env.PRIVATE_KEY || "" 12 | const BUNDLE_EXECUTOR_ADDRESS = process.env.BUNDLE_EXECUTOR_ADDRESS || "" 13 | 14 | const FLASHBOTS_RELAY_SIGNING_KEY = process.env.FLASHBOTS_RELAY_SIGNING_KEY || getDefaultRelaySigningKey(); 15 | 16 | const MINER_REWARD_PERCENTAGE = parseInt(process.env.MINER_REWARD_PERCENTAGE || "80") 17 | 18 | if (PRIVATE_KEY === "") { 19 | console.warn("Must provide PRIVATE_KEY environment variable") 20 | process.exit(1) 21 | } 22 | if (BUNDLE_EXECUTOR_ADDRESS === "") { 23 | console.warn("Must provide BUNDLE_EXECUTOR_ADDRESS environment variable. Please see README.md") 24 | process.exit(1) 25 | } 26 | 27 | if (FLASHBOTS_RELAY_SIGNING_KEY === "") { 28 | console.warn("Must provide FLASHBOTS_RELAY_SIGNING_KEY. Please see https://github.com/flashbots/pm/blob/main/guides/searcher-onboarding.md") 29 | process.exit(1) 30 | } 31 | 32 | const HEALTHCHECK_URL = process.env.HEALTHCHECK_URL || "" 33 | 34 | const provider = new providers.StaticJsonRpcProvider(ETHEREUM_RPC_URL); 35 | 36 | const arbitrageSigningWallet = new Wallet(PRIVATE_KEY); 37 | const flashbotsRelaySigningWallet = new Wallet(FLASHBOTS_RELAY_SIGNING_KEY); 38 | 39 | function healthcheck() { 40 | if (HEALTHCHECK_URL === "") { 41 | return 42 | } 43 | get(HEALTHCHECK_URL).on('error', console.error); 44 | } 45 | 46 | async function main() { 47 | console.log("Searcher Wallet Address: " + await arbitrageSigningWallet.getAddress()) 48 | console.log("Flashbots Relay Signing Wallet Address: " + await flashbotsRelaySigningWallet.getAddress()) 49 | const flashbotsProvider = await FlashbotsBundleProvider.create(provider, flashbotsRelaySigningWallet); 50 | const arbitrage = new Arbitrage( 51 | arbitrageSigningWallet, 52 | flashbotsProvider, 53 | new Contract(BUNDLE_EXECUTOR_ADDRESS, BUNDLE_EXECUTOR_ABI, provider) ) 54 | 55 | const markets = await UniswappyV2EthPair.getUniswapMarketsByToken(provider, FACTORY_ADDRESSES); 56 | provider.on('block', async (blockNumber) => { 57 | await UniswappyV2EthPair.updateReserves(provider, markets.allMarketPairs); 58 | const bestCrossedMarkets = await arbitrage.evaluateMarkets(markets.marketsByToken); 59 | if (bestCrossedMarkets.length === 0) { 60 | console.log("No crossed markets") 61 | return 62 | } 63 | bestCrossedMarkets.forEach(Arbitrage.printCrossedMarket); 64 | arbitrage.takeCrossedMarkets(bestCrossedMarkets, blockNumber, MINER_REWARD_PERCENTAGE).then(healthcheck).catch(console.error) 65 | }) 66 | } 67 | 68 | main(); 69 | -------------------------------------------------------------------------------- /src/utils.ts: -------------------------------------------------------------------------------- 1 | import { BigNumber, Wallet } from "ethers"; 2 | 3 | export const ETHER = BigNumber.from(10).pow(18); 4 | 5 | export function bigNumberToDecimal(value: BigNumber, base = 18): number { 6 | const divisor = BigNumber.from(10).pow(base) 7 | return value.mul(10000).div(divisor).toNumber() / 10000 8 | } 9 | 10 | export function getDefaultRelaySigningKey(): string { 11 | console.warn("You have not specified an explicity FLASHBOTS_RELAY_SIGNING_KEY environment variable. Creating random signing key, this searcher will not be building a reputation for next run") 12 | return Wallet.createRandom().privateKey; 13 | } 14 | -------------------------------------------------------------------------------- /test/Arbitrage.test.ts: -------------------------------------------------------------------------------- 1 | 2 | import { Arbitrage, getBestCrossedMarket } from "../src/Arbitrage" 3 | import { WETH_ADDRESS} from "../src/addresses" 4 | import { UniswappyV2EthPair } from "../src/UniswappyV2EthPair"; 5 | import { BigNumber } from "ethers"; 6 | import { ETHER } from "../src/utils"; 7 | 8 | const MARKET_ADDRESS = "0x0000000000000000000000000000000000000001" 9 | const TOKEN_ADDRESS = "0x000000000000000000000000000000000000000a" 10 | const PROTOCOL_NAME = "TEST"; 11 | 12 | 13 | describe('Arbitrage', function() { 14 | let groupedWethMarkets: Array 15 | beforeEach(() => { 16 | groupedWethMarkets = [ 17 | new UniswappyV2EthPair(MARKET_ADDRESS, [TOKEN_ADDRESS, WETH_ADDRESS], PROTOCOL_NAME), 18 | new UniswappyV2EthPair(MARKET_ADDRESS, [TOKEN_ADDRESS, WETH_ADDRESS], PROTOCOL_NAME), 19 | ] 20 | }) 21 | it('Calculate Crossed Markets', function() { 22 | groupedWethMarkets[0].setReservesViaOrderedBalances([ETHER, ETHER.mul(2)]) 23 | groupedWethMarkets[1].setReservesViaOrderedBalances([ETHER, ETHER]) 24 | 25 | const bestCrossedMarket = getBestCrossedMarket([groupedWethMarkets], TOKEN_ADDRESS); 26 | if (bestCrossedMarket === undefined) { 27 | fail("No crossed Market") 28 | return 29 | } 30 | expect(bestCrossedMarket.volume).toEqual(BigNumber.from("208333333333333333")) 31 | expect(bestCrossedMarket.profit).toEqual(BigNumber.from("0x012be1d487a428ce")) 32 | }); 33 | it('Calculate markets that do not cross', function() { 34 | groupedWethMarkets[0].setReservesViaOrderedBalances([ETHER, ETHER]) 35 | groupedWethMarkets[1].setReservesViaOrderedBalances([ETHER, ETHER]) 36 | 37 | const bestCrossedMarket = getBestCrossedMarket([groupedWethMarkets], TOKEN_ADDRESS); 38 | if (bestCrossedMarket === undefined) { 39 | fail("No crossed Market") 40 | return 41 | } 42 | expect(bestCrossedMarket.profit.lt(0)).toBeTrue() 43 | }); 44 | }); 45 | -------------------------------------------------------------------------------- /test/UniswappyV2EthPair.test.ts: -------------------------------------------------------------------------------- 1 | import { UniswappyV2EthPair } from "../src/UniswappyV2EthPair" 2 | import { WETH_ADDRESS } from "../src/addresses" 3 | import { BigNumber } from "ethers"; 4 | import { ETHER } from "../src/utils"; 5 | 6 | const MARKET_ADDRESS = "0x0000000000000000000000000000000000000001" 7 | const TOKEN_ADDRESS = "0x000000000000000000000000000000000000000a" 8 | const PROTOCOL_NAME = "TEST"; 9 | 10 | describe('UniswappyV2EthPair', function() { 11 | let wethPair: UniswappyV2EthPair 12 | beforeEach(() => { 13 | wethPair = new UniswappyV2EthPair(MARKET_ADDRESS, [TOKEN_ADDRESS, WETH_ADDRESS], PROTOCOL_NAME); 14 | wethPair.setReservesViaOrderedBalances([ETHER, ETHER.mul(2)]) 15 | }) 16 | it('fetch balances by token address', function() { 17 | expect(wethPair.getBalance(TOKEN_ADDRESS)).toEqual(ETHER); 18 | expect(wethPair.getBalance(WETH_ADDRESS)).toEqual(ETHER.mul(2)); 19 | }); 20 | it('get token input required for output', function() { 21 | expect(wethPair.getTokensIn(TOKEN_ADDRESS, WETH_ADDRESS, ETHER.div(10))).toEqual(BigNumber.from("52789948793749671")); 22 | expect(wethPair.getTokensIn(WETH_ADDRESS, TOKEN_ADDRESS, ETHER.div(10))).toEqual(BigNumber.from("222890894906943052")); 23 | }); 24 | it('get token output from input', function() { 25 | expect(wethPair.getTokensOut(TOKEN_ADDRESS, WETH_ADDRESS, BigNumber.from("52789948793749671"))).toEqual(ETHER.div(10).add(1)); 26 | expect(wethPair.getTokensOut(WETH_ADDRESS, TOKEN_ADDRESS, BigNumber.from("222890894906943052"))).toEqual(ETHER.div(10)); 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Basic Options */ 4 | // "incremental": true, /* Enable incremental compilation */ 5 | "target": "es2018", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */ 6 | "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ 7 | "lib": [ "es2018" ], /* Specify library files to be included in the compilation. */ 8 | // "allowJs": true, /* Allow javascript files to be compiled. */ 9 | // "checkJs": true, /* Report errors in .js files. */ 10 | // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ 11 | "declaration": true, /* Generates corresponding '.d.ts' file. */ 12 | // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ 13 | "sourceMap": true, /* Generates corresponding '.map' file. */ 14 | // "outFile": "./", /* Concatenate and emit output to single file. */ 15 | "outDir": "./build", /* Redirect output structure to the directory. */ 16 | "rootDir": "./src", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ 17 | "composite": true, /* Enable project compilation */ 18 | // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ 19 | // "removeComments": true, /* Do not emit comments to output. */ 20 | // "noEmit": true, /* Do not emit outputs. */ 21 | // "importHelpers": true, /* Import emit helpers from 'tslib'. */ 22 | // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ 23 | // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ 24 | 25 | /* Strict Type-Checking Options */ 26 | "strict": true, /* Enable all strict type-checking options. */ 27 | "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ 28 | // "strictNullChecks": true, /* Enable strict null checks. */ 29 | // "strictFunctionTypes": true, /* Enable strict checking of function types. */ 30 | // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ 31 | // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ 32 | // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ 33 | // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ 34 | 35 | /* Additional Checks */ 36 | // "noUnusedLocals": true, /* Report errors on unused locals. */ 37 | // "noUnusedParameters": true, /* Report errors on unused parameters. */ 38 | // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ 39 | // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ 40 | 41 | /* Module Resolution Options */ 42 | // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ 43 | // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ 44 | // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ 45 | // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ 46 | // "typeRoots": [], /* List of folders to include type definitions from. */ 47 | // "types": [], /* Type declaration files to be included in compilation. */ 48 | // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ 49 | "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ 50 | // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ 51 | // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ 52 | 53 | /* Source Map Options */ 54 | // "sourceRoot": "src/" /* Specify the location where debugger should locate TypeScript files instead of source locations. */ 55 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ 56 | // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ 57 | // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ 58 | 59 | /* Experimental Options */ 60 | // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ 61 | // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ 62 | }, 63 | "include": [ 64 | "src/**/*", 65 | ], 66 | "exclude": [ 67 | "test", 68 | "build", 69 | "node_modules", 70 | ] 71 | } 72 | --------------------------------------------------------------------------------