commit b7769d45486a752984cbb57e13d44f4360f41764 Author: Theo Date: Thu Aug 17 14:38:38 2023 -0700 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b7bfa02 --- /dev/null +++ b/.gitignore @@ -0,0 +1,93 @@ +# Created by .ignore support plugin (hsz.mobi) +### Node template +# Logs +/logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# TypeScript v1 declaration files +typings/ + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variables file +.env + +# parcel-bundler cache (https://parceljs.org/) +.cache + +# next.js build output +.next + +# nuxt.js build output +.nuxt + +# Nuxt generate +dist + +# vuepress build output +.vuepress/dist + +# Serverless directories +.serverless + +# IDE / Editor +.idea + +# Service worker +sw.* + +# macOS +.DS_Store + +# Vim swap files +*.swp + +test \ No newline at end of file diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000..05ba80e --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +@tornado:registry=https://git.tornado.ws/api/packages/tornado-packages/npm/ \ No newline at end of file diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 0000000..dbe6e5a --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +v20.3.0 \ No newline at end of file diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..7951405 --- /dev/null +++ b/.prettierignore @@ -0,0 +1 @@ +lib \ No newline at end of file diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..22245e6 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,8 @@ +{ + "semi": true, + "trailingComma": "all", + "singleQuote": true, + "jsxSingleQuote": true, + "printWidth": 120, + "tabWidth": 2 +} diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..aadef24 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 Tornado Cash Team + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/abis/Multicall.abi.json b/abis/Multicall.abi.json new file mode 100644 index 0000000..8f30555 --- /dev/null +++ b/abis/Multicall.abi.json @@ -0,0 +1,38 @@ +[ + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "internalType": "struct MultiCall.Call[]", + "name": "calls", + "type": "tuple[]" + } + ], + "name": "multicall", + "outputs": [ + { + "internalType": "bytes[]", + "name": "results", + "type": "bytes[]" + }, + { + "internalType": "bool[]", + "name": "success", + "type": "bool[]" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/abis/OffchainOracle.abi.json b/abis/OffchainOracle.abi.json new file mode 100644 index 0000000..d43f1b5 --- /dev/null +++ b/abis/OffchainOracle.abi.json @@ -0,0 +1,292 @@ +[ + { + "inputs": [ + { + "internalType": "contract MultiWrapper", + "name": "_multiWrapper", + "type": "address" + }, + { + "internalType": "contract IOracle[]", + "name": "existingOracles", + "type": "address[]" + }, + { + "internalType": "enum OffchainOracle.OracleType[]", + "name": "oracleTypes", + "type": "uint8[]" + }, + { + "internalType": "contract IERC20[]", + "name": "existingConnectors", + "type": "address[]" + }, + { "internalType": "contract IERC20", "name": "wBase", "type": "address" } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract IERC20", + "name": "connector", + "type": "address" + } + ], + "name": "ConnectorAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract IERC20", + "name": "connector", + "type": "address" + } + ], + "name": "ConnectorRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract MultiWrapper", + "name": "multiWrapper", + "type": "address" + } + ], + "name": "MultiWrapperUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract IOracle", + "name": "oracle", + "type": "address" + }, + { + "indexed": false, + "internalType": "enum OffchainOracle.OracleType", + "name": "oracleType", + "type": "uint8" + } + ], + "name": "OracleAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract IOracle", + "name": "oracle", + "type": "address" + }, + { + "indexed": false, + "internalType": "enum OffchainOracle.OracleType", + "name": "oracleType", + "type": "uint8" + } + ], + "name": "OracleRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "connector", + "type": "address" + } + ], + "name": "addConnector", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IOracle", + "name": "oracle", + "type": "address" + }, + { + "internalType": "enum OffchainOracle.OracleType", + "name": "oracleKind", + "type": "uint8" + } + ], + "name": "addOracle", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "connectors", + "outputs": [ + { + "internalType": "contract IERC20[]", + "name": "allConnectors", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "srcToken", + "type": "address" + }, + { + "internalType": "contract IERC20", + "name": "dstToken", + "type": "address" + }, + { "internalType": "bool", "name": "useWrappers", "type": "bool" } + ], + "name": "getRate", + "outputs": [{ "internalType": "uint256", "name": "weightedRate", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "srcToken", + "type": "address" + }, + { "internalType": "bool", "name": "useSrcWrappers", "type": "bool" } + ], + "name": "getRateToEth", + "outputs": [{ "internalType": "uint256", "name": "weightedRate", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "multiWrapper", + "outputs": [{ "internalType": "contract MultiWrapper", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "oracles", + "outputs": [ + { + "internalType": "contract IOracle[]", + "name": "allOracles", + "type": "address[]" + }, + { + "internalType": "enum OffchainOracle.OracleType[]", + "name": "oracleTypes", + "type": "uint8[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "connector", + "type": "address" + } + ], + "name": "removeConnector", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IOracle", + "name": "oracle", + "type": "address" + }, + { + "internalType": "enum OffchainOracle.OracleType", + "name": "oracleKind", + "type": "uint8" + } + ], + "name": "removeOracle", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract MultiWrapper", + "name": "_multiWrapper", + "type": "address" + } + ], + "name": "setMultiWrapper", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "newOwner", "type": "address" }], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/abis/OptimismL1FeeOracle.abi.json b/abis/OptimismL1FeeOracle.abi.json new file mode 100644 index 0000000..8f239ad --- /dev/null +++ b/abis/OptimismL1FeeOracle.abi.json @@ -0,0 +1,151 @@ +[ + { + "inputs": [{ "internalType": "address", "name": "_owner", "type": "address" }], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [{ "indexed": false, "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "DecimalsUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [{ "indexed": false, "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "GasPriceUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [{ "indexed": false, "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "L1BaseFeeUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [{ "indexed": false, "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "OverheadUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "address", "name": "previousOwner", "type": "address" }, + { "indexed": true, "internalType": "address", "name": "newOwner", "type": "address" } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [{ "indexed": false, "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "ScalarUpdated", + "type": "event" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "gasPrice", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "bytes", "name": "_data", "type": "bytes" }], + "name": "getL1Fee", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "bytes", "name": "_data", "type": "bytes" }], + "name": "getL1GasUsed", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "l1BaseFee", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "overhead", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "scalar", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "_decimals", "type": "uint256" }], + "name": "setDecimals", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "_gasPrice", "type": "uint256" }], + "name": "setGasPrice", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "_baseFee", "type": "uint256" }], + "name": "setL1BaseFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "_overhead", "type": "uint256" }], + "name": "setOverhead", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "_scalar", "type": "uint256" }], + "name": "setScalar", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "newOwner", "type": "address" }], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/package.json b/package.json new file mode 100644 index 0000000..b8c72fa --- /dev/null +++ b/package.json @@ -0,0 +1,45 @@ +{ + "name": "@tornado/tornado-oracles", + "version": "0.1.0", + "description": "Gas oracle for Tornado-specific transactions", + "main": "./lib/index.js", + "types": "./lib/index.d.ts", + "scripts": { + "build": "tsc", + "build:esm": "tsc -p tsconfig.esm.json", + "prettier:check": "prettier --check . --config .prettierrc", + "prettier:fix": "prettier --write . --config .prettierrc", + "build:abi": "yarn typechain --target ethers-v5 --out-dir src/contracts ./abis/*.abi.json", + "test": "echo \"Error: no test specified\" && exit 1", + "prepare": "npm run build && npm run build:esm" + }, + "repository": { + "type": "git", + "url": "https://git.tornado.ws/tornado-packages/tornado-gas-oracle.git" + }, + "keywords": [ + "Gas", + "price", + "Gas", + "Gas", + "limit", + "Oracle" + ], + "author": "Theo", + "license": "MIT", + "dependencies": { + "@tornado/gas-price-oracle": "^0.5.3", + "@tornado/tornado-config": "^2.0.0", + "bignumber.js": "^9.1.1", + "ethers": "5.7" + }, + "devDependencies": { + "@typechain/ethers-v5": "^11.1.1", + "@types/node": "^20.4.10", + "nodemon": "^3.0.1", + "prettier": "^3.0.1", + "ts-node": "^10.9.1", + "typechain": "^8.3.1", + "typescript": "^5.1.6" + } +} diff --git a/src/config.ts b/src/config.ts new file mode 100644 index 0000000..a05305a --- /dev/null +++ b/src/config.ts @@ -0,0 +1,86 @@ +import { LegacyGasPrices } from './types'; + +export enum ChainId { + MAINNET = 1, + GOERLI = 5, + BSC = 56, + XDAI = 100, + POLYGON = 137, + OPTIMISM = 10, + ARBITRUM = 42161, + AVAX = 43114, +} + +export type GasPricesConfig = { + [chainId in ChainId]: LegacyGasPrices; +}; + +export const defaultGasPrices: GasPricesConfig = { + [ChainId.MAINNET]: { + instant: 80, + fast: 50, + standard: 25, + low: 8, + }, + [ChainId.GOERLI]: { + instant: 80, + fast: 50, + standard: 25, + low: 8, + }, + [ChainId.OPTIMISM]: { + instant: 0.001, + fast: 0.001, + standard: 0.001, + low: 0.001, + }, + [ChainId.XDAI]: { + instant: 6, + fast: 5, + standard: 4, + low: 1, + }, + [ChainId.BSC]: { + instant: 5, + fast: 4, + standard: 3, + low: 3, + }, + [ChainId.POLYGON]: { + instant: 100, + fast: 75, + standard: 50, + low: 30, + }, + [ChainId.ARBITRUM]: { + instant: 4, + fast: 3, + standard: 2.52, + low: 2.29, + }, + [ChainId.AVAX]: { + instant: 225, + fast: 35, + standard: 25, + low: 25, + }, +}; + +type GasLimitConfig = { + [chainId in ChainId]: number; +}; + +export const defaultWithdrawalGasLimit: GasLimitConfig = { + [ChainId.MAINNET]: 550000, + [ChainId.GOERLI]: 550000, + [ChainId.ARBITRUM]: 1900000, + [ChainId.OPTIMISM]: 440000, + [ChainId.AVAX]: 390000, + [ChainId.BSC]: 390000, + [ChainId.POLYGON]: 390000, + [ChainId.XDAI]: 390000, +}; + +export const optimismL1FeeOracleAddress = '0x420000000000000000000000000000000000000F'; +export const offchainOracleAddress = '0x07D91f5fb9Bf7798734C3f606dB065549F6893bb'; +export const multiCallAddress = '0xda3c19c6fe954576707fa24695efb830d9cca1ca'; diff --git a/src/contracts/MulticallAbi.ts b/src/contracts/MulticallAbi.ts new file mode 100644 index 0000000..e4730b6 --- /dev/null +++ b/src/contracts/MulticallAbi.ts @@ -0,0 +1,82 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ +import type { BaseContract, BigNumber, BytesLike, CallOverrides, PopulatedTransaction, Signer, utils } from 'ethers'; +import type { FunctionFragment, Result } from '@ethersproject/abi'; +import type { Listener, Provider } from '@ethersproject/providers'; +import type { TypedEventFilter, TypedEvent, TypedListener, OnEvent } from './common'; + +export declare namespace MultiCall { + export type CallStruct = { to: string; data: BytesLike }; + + export type CallStructOutput = [string, string] & { + to: string; + data: string; + }; +} + +export interface MulticallAbiInterface extends utils.Interface { + functions: { + 'multicall((address,bytes)[])': FunctionFragment; + }; + + getFunction(nameOrSignatureOrTopic: 'multicall'): FunctionFragment; + + encodeFunctionData(functionFragment: 'multicall', values: [MultiCall.CallStruct[]]): string; + + decodeFunctionResult(functionFragment: 'multicall', data: BytesLike): Result; + + events: {}; +} + +export interface MulticallAbi extends BaseContract { + connect(signerOrProvider: Signer | Provider | string): this; + attach(addressOrName: string): this; + deployed(): Promise; + + interface: MulticallAbiInterface; + + queryFilter( + event: TypedEventFilter, + fromBlockOrBlockhash?: string | number | undefined, + toBlock?: string | number | undefined, + ): Promise>; + + listeners(eventFilter?: TypedEventFilter): Array>; + listeners(eventName?: string): Array; + removeAllListeners(eventFilter: TypedEventFilter): this; + removeAllListeners(eventName?: string): this; + off: OnEvent; + on: OnEvent; + once: OnEvent; + removeListener: OnEvent; + + functions: { + multicall( + calls: MultiCall.CallStruct[], + overrides?: CallOverrides, + ): Promise<[string[], boolean[]] & { results: string[]; success: boolean[] }>; + }; + + multicall( + calls: MultiCall.CallStruct[], + overrides?: CallOverrides, + ): Promise<[string[], boolean[]] & { results: string[]; success: boolean[] }>; + + callStatic: { + multicall( + calls: MultiCall.CallStruct[], + overrides?: CallOverrides, + ): Promise<[string[], boolean[]] & { results: string[]; success: boolean[] }>; + }; + + filters: {}; + + estimateGas: { + multicall(calls: MultiCall.CallStruct[], overrides?: CallOverrides): Promise; + }; + + populateTransaction: { + multicall(calls: MultiCall.CallStruct[], overrides?: CallOverrides): Promise; + }; +} diff --git a/src/contracts/OffchainOracleAbi.ts b/src/contracts/OffchainOracleAbi.ts new file mode 100644 index 0000000..1838514 --- /dev/null +++ b/src/contracts/OffchainOracleAbi.ts @@ -0,0 +1,368 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ +import type { + BaseContract, + BigNumber, + BigNumberish, + BytesLike, + CallOverrides, + ContractTransaction, + Overrides, + PopulatedTransaction, + Signer, + utils, +} from 'ethers'; +import type { FunctionFragment, Result, EventFragment } from '@ethersproject/abi'; +import type { Listener, Provider } from '@ethersproject/providers'; +import type { TypedEventFilter, TypedEvent, TypedListener, OnEvent } from './common'; + +export interface OffchainOracleAbiInterface extends utils.Interface { + functions: { + 'addConnector(address)': FunctionFragment; + 'addOracle(address,uint8)': FunctionFragment; + 'connectors()': FunctionFragment; + 'getRate(address,address,bool)': FunctionFragment; + 'getRateToEth(address,bool)': FunctionFragment; + 'multiWrapper()': FunctionFragment; + 'oracles()': FunctionFragment; + 'owner()': FunctionFragment; + 'removeConnector(address)': FunctionFragment; + 'removeOracle(address,uint8)': FunctionFragment; + 'renounceOwnership()': FunctionFragment; + 'setMultiWrapper(address)': FunctionFragment; + 'transferOwnership(address)': FunctionFragment; + }; + + getFunction( + nameOrSignatureOrTopic: + | 'addConnector' + | 'addOracle' + | 'connectors' + | 'getRate' + | 'getRateToEth' + | 'multiWrapper' + | 'oracles' + | 'owner' + | 'removeConnector' + | 'removeOracle' + | 'renounceOwnership' + | 'setMultiWrapper' + | 'transferOwnership', + ): FunctionFragment; + + encodeFunctionData(functionFragment: 'addConnector', values: [string]): string; + encodeFunctionData(functionFragment: 'addOracle', values: [string, BigNumberish]): string; + encodeFunctionData(functionFragment: 'connectors', values?: undefined): string; + encodeFunctionData(functionFragment: 'getRate', values: [string, string, boolean]): string; + encodeFunctionData(functionFragment: 'getRateToEth', values: [string, boolean]): string; + encodeFunctionData(functionFragment: 'multiWrapper', values?: undefined): string; + encodeFunctionData(functionFragment: 'oracles', values?: undefined): string; + encodeFunctionData(functionFragment: 'owner', values?: undefined): string; + encodeFunctionData(functionFragment: 'removeConnector', values: [string]): string; + encodeFunctionData(functionFragment: 'removeOracle', values: [string, BigNumberish]): string; + encodeFunctionData(functionFragment: 'renounceOwnership', values?: undefined): string; + encodeFunctionData(functionFragment: 'setMultiWrapper', values: [string]): string; + encodeFunctionData(functionFragment: 'transferOwnership', values: [string]): string; + + decodeFunctionResult(functionFragment: 'addConnector', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'addOracle', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'connectors', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'getRate', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'getRateToEth', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'multiWrapper', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'oracles', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'owner', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'removeConnector', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'removeOracle', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'renounceOwnership', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'setMultiWrapper', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'transferOwnership', data: BytesLike): Result; + + events: { + 'ConnectorAdded(address)': EventFragment; + 'ConnectorRemoved(address)': EventFragment; + 'MultiWrapperUpdated(address)': EventFragment; + 'OracleAdded(address,uint8)': EventFragment; + 'OracleRemoved(address,uint8)': EventFragment; + 'OwnershipTransferred(address,address)': EventFragment; + }; + + getEvent(nameOrSignatureOrTopic: 'ConnectorAdded'): EventFragment; + getEvent(nameOrSignatureOrTopic: 'ConnectorRemoved'): EventFragment; + getEvent(nameOrSignatureOrTopic: 'MultiWrapperUpdated'): EventFragment; + getEvent(nameOrSignatureOrTopic: 'OracleAdded'): EventFragment; + getEvent(nameOrSignatureOrTopic: 'OracleRemoved'): EventFragment; + getEvent(nameOrSignatureOrTopic: 'OwnershipTransferred'): EventFragment; +} + +export interface ConnectorAddedEventObject { + connector: string; +} +export type ConnectorAddedEvent = TypedEvent<[string], ConnectorAddedEventObject>; + +export type ConnectorAddedEventFilter = TypedEventFilter; + +export interface ConnectorRemovedEventObject { + connector: string; +} +export type ConnectorRemovedEvent = TypedEvent<[string], ConnectorRemovedEventObject>; + +export type ConnectorRemovedEventFilter = TypedEventFilter; + +export interface MultiWrapperUpdatedEventObject { + multiWrapper: string; +} +export type MultiWrapperUpdatedEvent = TypedEvent<[string], MultiWrapperUpdatedEventObject>; + +export type MultiWrapperUpdatedEventFilter = TypedEventFilter; + +export interface OracleAddedEventObject { + oracle: string; + oracleType: number; +} +export type OracleAddedEvent = TypedEvent<[string, number], OracleAddedEventObject>; + +export type OracleAddedEventFilter = TypedEventFilter; + +export interface OracleRemovedEventObject { + oracle: string; + oracleType: number; +} +export type OracleRemovedEvent = TypedEvent<[string, number], OracleRemovedEventObject>; + +export type OracleRemovedEventFilter = TypedEventFilter; + +export interface OwnershipTransferredEventObject { + previousOwner: string; + newOwner: string; +} +export type OwnershipTransferredEvent = TypedEvent<[string, string], OwnershipTransferredEventObject>; + +export type OwnershipTransferredEventFilter = TypedEventFilter; + +export interface OffchainOracleAbi extends BaseContract { + connect(signerOrProvider: Signer | Provider | string): this; + attach(addressOrName: string): this; + deployed(): Promise; + + interface: OffchainOracleAbiInterface; + + queryFilter( + event: TypedEventFilter, + fromBlockOrBlockhash?: string | number | undefined, + toBlock?: string | number | undefined, + ): Promise>; + + listeners(eventFilter?: TypedEventFilter): Array>; + listeners(eventName?: string): Array; + removeAllListeners(eventFilter: TypedEventFilter): this; + removeAllListeners(eventName?: string): this; + off: OnEvent; + on: OnEvent; + once: OnEvent; + removeListener: OnEvent; + + functions: { + addConnector(connector: string, overrides?: Overrides & { from?: string }): Promise; + + addOracle( + oracle: string, + oracleKind: BigNumberish, + overrides?: Overrides & { from?: string }, + ): Promise; + + connectors(overrides?: CallOverrides): Promise<[string[]] & { allConnectors: string[] }>; + + getRate( + srcToken: string, + dstToken: string, + useWrappers: boolean, + overrides?: CallOverrides, + ): Promise<[BigNumber] & { weightedRate: BigNumber }>; + + getRateToEth( + srcToken: string, + useSrcWrappers: boolean, + overrides?: CallOverrides, + ): Promise<[BigNumber] & { weightedRate: BigNumber }>; + + multiWrapper(overrides?: CallOverrides): Promise<[string]>; + + oracles(overrides?: CallOverrides): Promise<[string[], number[]] & { allOracles: string[]; oracleTypes: number[] }>; + + owner(overrides?: CallOverrides): Promise<[string]>; + + removeConnector(connector: string, overrides?: Overrides & { from?: string }): Promise; + + removeOracle( + oracle: string, + oracleKind: BigNumberish, + overrides?: Overrides & { from?: string }, + ): Promise; + + renounceOwnership(overrides?: Overrides & { from?: string }): Promise; + + setMultiWrapper(_multiWrapper: string, overrides?: Overrides & { from?: string }): Promise; + + transferOwnership(newOwner: string, overrides?: Overrides & { from?: string }): Promise; + }; + + addConnector(connector: string, overrides?: Overrides & { from?: string }): Promise; + + addOracle( + oracle: string, + oracleKind: BigNumberish, + overrides?: Overrides & { from?: string }, + ): Promise; + + connectors(overrides?: CallOverrides): Promise; + + getRate(srcToken: string, dstToken: string, useWrappers: boolean, overrides?: CallOverrides): Promise; + + getRateToEth(srcToken: string, useSrcWrappers: boolean, overrides?: CallOverrides): Promise; + + multiWrapper(overrides?: CallOverrides): Promise; + + oracles(overrides?: CallOverrides): Promise<[string[], number[]] & { allOracles: string[]; oracleTypes: number[] }>; + + owner(overrides?: CallOverrides): Promise; + + removeConnector(connector: string, overrides?: Overrides & { from?: string }): Promise; + + removeOracle( + oracle: string, + oracleKind: BigNumberish, + overrides?: Overrides & { from?: string }, + ): Promise; + + renounceOwnership(overrides?: Overrides & { from?: string }): Promise; + + setMultiWrapper(_multiWrapper: string, overrides?: Overrides & { from?: string }): Promise; + + transferOwnership(newOwner: string, overrides?: Overrides & { from?: string }): Promise; + + callStatic: { + addConnector(connector: string, overrides?: CallOverrides): Promise; + + addOracle(oracle: string, oracleKind: BigNumberish, overrides?: CallOverrides): Promise; + + connectors(overrides?: CallOverrides): Promise; + + getRate(srcToken: string, dstToken: string, useWrappers: boolean, overrides?: CallOverrides): Promise; + + getRateToEth(srcToken: string, useSrcWrappers: boolean, overrides?: CallOverrides): Promise; + + multiWrapper(overrides?: CallOverrides): Promise; + + oracles(overrides?: CallOverrides): Promise<[string[], number[]] & { allOracles: string[]; oracleTypes: number[] }>; + + owner(overrides?: CallOverrides): Promise; + + removeConnector(connector: string, overrides?: CallOverrides): Promise; + + removeOracle(oracle: string, oracleKind: BigNumberish, overrides?: CallOverrides): Promise; + + renounceOwnership(overrides?: CallOverrides): Promise; + + setMultiWrapper(_multiWrapper: string, overrides?: CallOverrides): Promise; + + transferOwnership(newOwner: string, overrides?: CallOverrides): Promise; + }; + + filters: { + 'ConnectorAdded(address)'(connector?: null): ConnectorAddedEventFilter; + ConnectorAdded(connector?: null): ConnectorAddedEventFilter; + + 'ConnectorRemoved(address)'(connector?: null): ConnectorRemovedEventFilter; + ConnectorRemoved(connector?: null): ConnectorRemovedEventFilter; + + 'MultiWrapperUpdated(address)'(multiWrapper?: null): MultiWrapperUpdatedEventFilter; + MultiWrapperUpdated(multiWrapper?: null): MultiWrapperUpdatedEventFilter; + + 'OracleAdded(address,uint8)'(oracle?: null, oracleType?: null): OracleAddedEventFilter; + OracleAdded(oracle?: null, oracleType?: null): OracleAddedEventFilter; + + 'OracleRemoved(address,uint8)'(oracle?: null, oracleType?: null): OracleRemovedEventFilter; + OracleRemoved(oracle?: null, oracleType?: null): OracleRemovedEventFilter; + + 'OwnershipTransferred(address,address)'( + previousOwner?: string | null, + newOwner?: string | null, + ): OwnershipTransferredEventFilter; + OwnershipTransferred(previousOwner?: string | null, newOwner?: string | null): OwnershipTransferredEventFilter; + }; + + estimateGas: { + addConnector(connector: string, overrides?: Overrides & { from?: string }): Promise; + + addOracle(oracle: string, oracleKind: BigNumberish, overrides?: Overrides & { from?: string }): Promise; + + connectors(overrides?: CallOverrides): Promise; + + getRate(srcToken: string, dstToken: string, useWrappers: boolean, overrides?: CallOverrides): Promise; + + getRateToEth(srcToken: string, useSrcWrappers: boolean, overrides?: CallOverrides): Promise; + + multiWrapper(overrides?: CallOverrides): Promise; + + oracles(overrides?: CallOverrides): Promise; + + owner(overrides?: CallOverrides): Promise; + + removeConnector(connector: string, overrides?: Overrides & { from?: string }): Promise; + + removeOracle( + oracle: string, + oracleKind: BigNumberish, + overrides?: Overrides & { from?: string }, + ): Promise; + + renounceOwnership(overrides?: Overrides & { from?: string }): Promise; + + setMultiWrapper(_multiWrapper: string, overrides?: Overrides & { from?: string }): Promise; + + transferOwnership(newOwner: string, overrides?: Overrides & { from?: string }): Promise; + }; + + populateTransaction: { + addConnector(connector: string, overrides?: Overrides & { from?: string }): Promise; + + addOracle( + oracle: string, + oracleKind: BigNumberish, + overrides?: Overrides & { from?: string }, + ): Promise; + + connectors(overrides?: CallOverrides): Promise; + + getRate( + srcToken: string, + dstToken: string, + useWrappers: boolean, + overrides?: CallOverrides, + ): Promise; + + getRateToEth(srcToken: string, useSrcWrappers: boolean, overrides?: CallOverrides): Promise; + + multiWrapper(overrides?: CallOverrides): Promise; + + oracles(overrides?: CallOverrides): Promise; + + owner(overrides?: CallOverrides): Promise; + + removeConnector(connector: string, overrides?: Overrides & { from?: string }): Promise; + + removeOracle( + oracle: string, + oracleKind: BigNumberish, + overrides?: Overrides & { from?: string }, + ): Promise; + + renounceOwnership(overrides?: Overrides & { from?: string }): Promise; + + setMultiWrapper(_multiWrapper: string, overrides?: Overrides & { from?: string }): Promise; + + transferOwnership(newOwner: string, overrides?: Overrides & { from?: string }): Promise; + }; +} diff --git a/src/contracts/OptimismL1FeeOracleAbi.ts b/src/contracts/OptimismL1FeeOracleAbi.ts new file mode 100644 index 0000000..23dc0fb --- /dev/null +++ b/src/contracts/OptimismL1FeeOracleAbi.ts @@ -0,0 +1,352 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ +import type { + BaseContract, + BigNumber, + BigNumberish, + BytesLike, + CallOverrides, + ContractTransaction, + Overrides, + PopulatedTransaction, + Signer, + utils, +} from 'ethers'; +import type { FunctionFragment, Result, EventFragment } from '@ethersproject/abi'; +import type { Listener, Provider } from '@ethersproject/providers'; +import type { TypedEventFilter, TypedEvent, TypedListener, OnEvent } from './common'; + +export interface OptimismL1FeeOracleAbiInterface extends utils.Interface { + functions: { + 'decimals()': FunctionFragment; + 'gasPrice()': FunctionFragment; + 'getL1Fee(bytes)': FunctionFragment; + 'getL1GasUsed(bytes)': FunctionFragment; + 'l1BaseFee()': FunctionFragment; + 'overhead()': FunctionFragment; + 'owner()': FunctionFragment; + 'renounceOwnership()': FunctionFragment; + 'scalar()': FunctionFragment; + 'setDecimals(uint256)': FunctionFragment; + 'setGasPrice(uint256)': FunctionFragment; + 'setL1BaseFee(uint256)': FunctionFragment; + 'setOverhead(uint256)': FunctionFragment; + 'setScalar(uint256)': FunctionFragment; + 'transferOwnership(address)': FunctionFragment; + }; + + getFunction( + nameOrSignatureOrTopic: + | 'decimals' + | 'gasPrice' + | 'getL1Fee' + | 'getL1GasUsed' + | 'l1BaseFee' + | 'overhead' + | 'owner' + | 'renounceOwnership' + | 'scalar' + | 'setDecimals' + | 'setGasPrice' + | 'setL1BaseFee' + | 'setOverhead' + | 'setScalar' + | 'transferOwnership', + ): FunctionFragment; + + encodeFunctionData(functionFragment: 'decimals', values?: undefined): string; + encodeFunctionData(functionFragment: 'gasPrice', values?: undefined): string; + encodeFunctionData(functionFragment: 'getL1Fee', values: [BytesLike]): string; + encodeFunctionData(functionFragment: 'getL1GasUsed', values: [BytesLike]): string; + encodeFunctionData(functionFragment: 'l1BaseFee', values?: undefined): string; + encodeFunctionData(functionFragment: 'overhead', values?: undefined): string; + encodeFunctionData(functionFragment: 'owner', values?: undefined): string; + encodeFunctionData(functionFragment: 'renounceOwnership', values?: undefined): string; + encodeFunctionData(functionFragment: 'scalar', values?: undefined): string; + encodeFunctionData(functionFragment: 'setDecimals', values: [BigNumberish]): string; + encodeFunctionData(functionFragment: 'setGasPrice', values: [BigNumberish]): string; + encodeFunctionData(functionFragment: 'setL1BaseFee', values: [BigNumberish]): string; + encodeFunctionData(functionFragment: 'setOverhead', values: [BigNumberish]): string; + encodeFunctionData(functionFragment: 'setScalar', values: [BigNumberish]): string; + encodeFunctionData(functionFragment: 'transferOwnership', values: [string]): string; + + decodeFunctionResult(functionFragment: 'decimals', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'gasPrice', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'getL1Fee', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'getL1GasUsed', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'l1BaseFee', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'overhead', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'owner', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'renounceOwnership', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'scalar', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'setDecimals', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'setGasPrice', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'setL1BaseFee', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'setOverhead', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'setScalar', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'transferOwnership', data: BytesLike): Result; + + events: { + 'DecimalsUpdated(uint256)': EventFragment; + 'GasPriceUpdated(uint256)': EventFragment; + 'L1BaseFeeUpdated(uint256)': EventFragment; + 'OverheadUpdated(uint256)': EventFragment; + 'OwnershipTransferred(address,address)': EventFragment; + 'ScalarUpdated(uint256)': EventFragment; + }; + + getEvent(nameOrSignatureOrTopic: 'DecimalsUpdated'): EventFragment; + getEvent(nameOrSignatureOrTopic: 'GasPriceUpdated'): EventFragment; + getEvent(nameOrSignatureOrTopic: 'L1BaseFeeUpdated'): EventFragment; + getEvent(nameOrSignatureOrTopic: 'OverheadUpdated'): EventFragment; + getEvent(nameOrSignatureOrTopic: 'OwnershipTransferred'): EventFragment; + getEvent(nameOrSignatureOrTopic: 'ScalarUpdated'): EventFragment; +} + +export interface DecimalsUpdatedEventObject { + arg0: BigNumber; +} +export type DecimalsUpdatedEvent = TypedEvent<[BigNumber], DecimalsUpdatedEventObject>; + +export type DecimalsUpdatedEventFilter = TypedEventFilter; + +export interface GasPriceUpdatedEventObject { + arg0: BigNumber; +} +export type GasPriceUpdatedEvent = TypedEvent<[BigNumber], GasPriceUpdatedEventObject>; + +export type GasPriceUpdatedEventFilter = TypedEventFilter; + +export interface L1BaseFeeUpdatedEventObject { + arg0: BigNumber; +} +export type L1BaseFeeUpdatedEvent = TypedEvent<[BigNumber], L1BaseFeeUpdatedEventObject>; + +export type L1BaseFeeUpdatedEventFilter = TypedEventFilter; + +export interface OverheadUpdatedEventObject { + arg0: BigNumber; +} +export type OverheadUpdatedEvent = TypedEvent<[BigNumber], OverheadUpdatedEventObject>; + +export type OverheadUpdatedEventFilter = TypedEventFilter; + +export interface OwnershipTransferredEventObject { + previousOwner: string; + newOwner: string; +} +export type OwnershipTransferredEvent = TypedEvent<[string, string], OwnershipTransferredEventObject>; + +export type OwnershipTransferredEventFilter = TypedEventFilter; + +export interface ScalarUpdatedEventObject { + arg0: BigNumber; +} +export type ScalarUpdatedEvent = TypedEvent<[BigNumber], ScalarUpdatedEventObject>; + +export type ScalarUpdatedEventFilter = TypedEventFilter; + +export interface OptimismL1FeeOracleAbi extends BaseContract { + connect(signerOrProvider: Signer | Provider | string): this; + attach(addressOrName: string): this; + deployed(): Promise; + + interface: OptimismL1FeeOracleAbiInterface; + + queryFilter( + event: TypedEventFilter, + fromBlockOrBlockhash?: string | number | undefined, + toBlock?: string | number | undefined, + ): Promise>; + + listeners(eventFilter?: TypedEventFilter): Array>; + listeners(eventName?: string): Array; + removeAllListeners(eventFilter: TypedEventFilter): this; + removeAllListeners(eventName?: string): this; + off: OnEvent; + on: OnEvent; + once: OnEvent; + removeListener: OnEvent; + + functions: { + decimals(overrides?: CallOverrides): Promise<[BigNumber]>; + + gasPrice(overrides?: CallOverrides): Promise<[BigNumber]>; + + getL1Fee(_data: BytesLike, overrides?: CallOverrides): Promise<[BigNumber]>; + + getL1GasUsed(_data: BytesLike, overrides?: CallOverrides): Promise<[BigNumber]>; + + l1BaseFee(overrides?: CallOverrides): Promise<[BigNumber]>; + + overhead(overrides?: CallOverrides): Promise<[BigNumber]>; + + owner(overrides?: CallOverrides): Promise<[string]>; + + renounceOwnership(overrides?: Overrides & { from?: string }): Promise; + + scalar(overrides?: CallOverrides): Promise<[BigNumber]>; + + setDecimals(_decimals: BigNumberish, overrides?: Overrides & { from?: string }): Promise; + + setGasPrice(_gasPrice: BigNumberish, overrides?: Overrides & { from?: string }): Promise; + + setL1BaseFee(_baseFee: BigNumberish, overrides?: Overrides & { from?: string }): Promise; + + setOverhead(_overhead: BigNumberish, overrides?: Overrides & { from?: string }): Promise; + + setScalar(_scalar: BigNumberish, overrides?: Overrides & { from?: string }): Promise; + + transferOwnership(newOwner: string, overrides?: Overrides & { from?: string }): Promise; + }; + + decimals(overrides?: CallOverrides): Promise; + + gasPrice(overrides?: CallOverrides): Promise; + + getL1Fee(_data: BytesLike, overrides?: CallOverrides): Promise; + + getL1GasUsed(_data: BytesLike, overrides?: CallOverrides): Promise; + + l1BaseFee(overrides?: CallOverrides): Promise; + + overhead(overrides?: CallOverrides): Promise; + + owner(overrides?: CallOverrides): Promise; + + renounceOwnership(overrides?: Overrides & { from?: string }): Promise; + + scalar(overrides?: CallOverrides): Promise; + + setDecimals(_decimals: BigNumberish, overrides?: Overrides & { from?: string }): Promise; + + setGasPrice(_gasPrice: BigNumberish, overrides?: Overrides & { from?: string }): Promise; + + setL1BaseFee(_baseFee: BigNumberish, overrides?: Overrides & { from?: string }): Promise; + + setOverhead(_overhead: BigNumberish, overrides?: Overrides & { from?: string }): Promise; + + setScalar(_scalar: BigNumberish, overrides?: Overrides & { from?: string }): Promise; + + transferOwnership(newOwner: string, overrides?: Overrides & { from?: string }): Promise; + + callStatic: { + decimals(overrides?: CallOverrides): Promise; + + gasPrice(overrides?: CallOverrides): Promise; + + getL1Fee(_data: BytesLike, overrides?: CallOverrides): Promise; + + getL1GasUsed(_data: BytesLike, overrides?: CallOverrides): Promise; + + l1BaseFee(overrides?: CallOverrides): Promise; + + overhead(overrides?: CallOverrides): Promise; + + owner(overrides?: CallOverrides): Promise; + + renounceOwnership(overrides?: CallOverrides): Promise; + + scalar(overrides?: CallOverrides): Promise; + + setDecimals(_decimals: BigNumberish, overrides?: CallOverrides): Promise; + + setGasPrice(_gasPrice: BigNumberish, overrides?: CallOverrides): Promise; + + setL1BaseFee(_baseFee: BigNumberish, overrides?: CallOverrides): Promise; + + setOverhead(_overhead: BigNumberish, overrides?: CallOverrides): Promise; + + setScalar(_scalar: BigNumberish, overrides?: CallOverrides): Promise; + + transferOwnership(newOwner: string, overrides?: CallOverrides): Promise; + }; + + filters: { + 'DecimalsUpdated(uint256)'(arg0?: null): DecimalsUpdatedEventFilter; + DecimalsUpdated(arg0?: null): DecimalsUpdatedEventFilter; + + 'GasPriceUpdated(uint256)'(arg0?: null): GasPriceUpdatedEventFilter; + GasPriceUpdated(arg0?: null): GasPriceUpdatedEventFilter; + + 'L1BaseFeeUpdated(uint256)'(arg0?: null): L1BaseFeeUpdatedEventFilter; + L1BaseFeeUpdated(arg0?: null): L1BaseFeeUpdatedEventFilter; + + 'OverheadUpdated(uint256)'(arg0?: null): OverheadUpdatedEventFilter; + OverheadUpdated(arg0?: null): OverheadUpdatedEventFilter; + + 'OwnershipTransferred(address,address)'( + previousOwner?: string | null, + newOwner?: string | null, + ): OwnershipTransferredEventFilter; + OwnershipTransferred(previousOwner?: string | null, newOwner?: string | null): OwnershipTransferredEventFilter; + + 'ScalarUpdated(uint256)'(arg0?: null): ScalarUpdatedEventFilter; + ScalarUpdated(arg0?: null): ScalarUpdatedEventFilter; + }; + + estimateGas: { + decimals(overrides?: CallOverrides): Promise; + + gasPrice(overrides?: CallOverrides): Promise; + + getL1Fee(_data: BytesLike, overrides?: CallOverrides): Promise; + + getL1GasUsed(_data: BytesLike, overrides?: CallOverrides): Promise; + + l1BaseFee(overrides?: CallOverrides): Promise; + + overhead(overrides?: CallOverrides): Promise; + + owner(overrides?: CallOverrides): Promise; + + renounceOwnership(overrides?: Overrides & { from?: string }): Promise; + + scalar(overrides?: CallOverrides): Promise; + + setDecimals(_decimals: BigNumberish, overrides?: Overrides & { from?: string }): Promise; + + setGasPrice(_gasPrice: BigNumberish, overrides?: Overrides & { from?: string }): Promise; + + setL1BaseFee(_baseFee: BigNumberish, overrides?: Overrides & { from?: string }): Promise; + + setOverhead(_overhead: BigNumberish, overrides?: Overrides & { from?: string }): Promise; + + setScalar(_scalar: BigNumberish, overrides?: Overrides & { from?: string }): Promise; + + transferOwnership(newOwner: string, overrides?: Overrides & { from?: string }): Promise; + }; + + populateTransaction: { + decimals(overrides?: CallOverrides): Promise; + + gasPrice(overrides?: CallOverrides): Promise; + + getL1Fee(_data: BytesLike, overrides?: CallOverrides): Promise; + + getL1GasUsed(_data: BytesLike, overrides?: CallOverrides): Promise; + + l1BaseFee(overrides?: CallOverrides): Promise; + + overhead(overrides?: CallOverrides): Promise; + + owner(overrides?: CallOverrides): Promise; + + renounceOwnership(overrides?: Overrides & { from?: string }): Promise; + + scalar(overrides?: CallOverrides): Promise; + + setDecimals(_decimals: BigNumberish, overrides?: Overrides & { from?: string }): Promise; + + setGasPrice(_gasPrice: BigNumberish, overrides?: Overrides & { from?: string }): Promise; + + setL1BaseFee(_baseFee: BigNumberish, overrides?: Overrides & { from?: string }): Promise; + + setOverhead(_overhead: BigNumberish, overrides?: Overrides & { from?: string }): Promise; + + setScalar(_scalar: BigNumberish, overrides?: Overrides & { from?: string }): Promise; + + transferOwnership(newOwner: string, overrides?: Overrides & { from?: string }): Promise; + }; +} diff --git a/src/contracts/common.ts b/src/contracts/common.ts new file mode 100644 index 0000000..6cfb104 --- /dev/null +++ b/src/contracts/common.ts @@ -0,0 +1,30 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ +import type { Listener } from '@ethersproject/providers'; +import type { Event, EventFilter } from 'ethers'; + +export interface TypedEvent = any, TArgsObject = any> extends Event { + args: TArgsArray & TArgsObject; +} + +export interface TypedEventFilter<_TEvent extends TypedEvent> extends EventFilter {} + +export interface TypedListener { + (...listenerArg: [...__TypechainArgsArray, TEvent]): void; +} + +type __TypechainArgsArray = T extends TypedEvent ? U : never; + +export interface OnEvent { + (eventFilter: TypedEventFilter, listener: TypedListener): TRes; + (eventName: string, listener: Listener): TRes; +} + +export type MinEthersFactory = { + deploy(...a: ARGS[]): Promise; +}; + +export type GetContractTypeFromFactory = F extends MinEthersFactory ? C : never; + +export type GetARGsTypeFromFactory = F extends MinEthersFactory ? Parameters : never; diff --git a/src/contracts/factories.ts b/src/contracts/factories.ts new file mode 100644 index 0000000..7b9efd2 --- /dev/null +++ b/src/contracts/factories.ts @@ -0,0 +1,15 @@ +import { OptimismL1FeeOracleAbi__factory, OffchainOracleAbi__factory, MulticallAbi__factory } from './'; +import { optimismL1FeeOracleAddress, offchainOracleAddress, multiCallAddress } from '../config'; +import { Provider } from '@ethersproject/abstract-provider'; + +export const getOptimismL1FeeOracle = (provider: Provider) => { + return OptimismL1FeeOracleAbi__factory.connect(optimismL1FeeOracleAddress, provider); +}; + +export const getOffchainOracleContract = (provider: Provider) => { + return OffchainOracleAbi__factory.connect(offchainOracleAddress, provider); +}; + +export const getMultiCallContract = (provider: Provider) => { + return MulticallAbi__factory.connect(multiCallAddress, provider); +}; diff --git a/src/contracts/factories/MulticallAbi__factory.ts b/src/contracts/factories/MulticallAbi__factory.ts new file mode 100644 index 0000000..a598f0f --- /dev/null +++ b/src/contracts/factories/MulticallAbi__factory.ts @@ -0,0 +1,56 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ + +import { Contract, Signer, utils } from 'ethers'; +import type { Provider } from '@ethersproject/providers'; +import type { MulticallAbi, MulticallAbiInterface } from '../MulticallAbi'; + +const _abi = [ + { + inputs: [ + { + components: [ + { + internalType: 'address', + name: 'to', + type: 'address', + }, + { + internalType: 'bytes', + name: 'data', + type: 'bytes', + }, + ], + internalType: 'struct MultiCall.Call[]', + name: 'calls', + type: 'tuple[]', + }, + ], + name: 'multicall', + outputs: [ + { + internalType: 'bytes[]', + name: 'results', + type: 'bytes[]', + }, + { + internalType: 'bool[]', + name: 'success', + type: 'bool[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, +] as const; + +export class MulticallAbi__factory { + static readonly abi = _abi; + static createInterface(): MulticallAbiInterface { + return new utils.Interface(_abi) as MulticallAbiInterface; + } + static connect(address: string, signerOrProvider: Signer | Provider): MulticallAbi { + return new Contract(address, _abi, signerOrProvider) as MulticallAbi; + } +} diff --git a/src/contracts/factories/OffchainOracleAbi__factory.ts b/src/contracts/factories/OffchainOracleAbi__factory.ts new file mode 100644 index 0000000..21916c3 --- /dev/null +++ b/src/contracts/factories/OffchainOracleAbi__factory.ts @@ -0,0 +1,352 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ + +import { Contract, Signer, utils } from 'ethers'; +import type { Provider } from '@ethersproject/providers'; +import type { OffchainOracleAbi, OffchainOracleAbiInterface } from '../OffchainOracleAbi'; + +const _abi = [ + { + inputs: [ + { + internalType: 'contract MultiWrapper', + name: '_multiWrapper', + type: 'address', + }, + { + internalType: 'contract IOracle[]', + name: 'existingOracles', + type: 'address[]', + }, + { + internalType: 'enum OffchainOracle.OracleType[]', + name: 'oracleTypes', + type: 'uint8[]', + }, + { + internalType: 'contract IERC20[]', + name: 'existingConnectors', + type: 'address[]', + }, + { + internalType: 'contract IERC20', + name: 'wBase', + type: 'address', + }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract IERC20', + name: 'connector', + type: 'address', + }, + ], + name: 'ConnectorAdded', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract IERC20', + name: 'connector', + type: 'address', + }, + ], + name: 'ConnectorRemoved', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract MultiWrapper', + name: 'multiWrapper', + type: 'address', + }, + ], + name: 'MultiWrapperUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract IOracle', + name: 'oracle', + type: 'address', + }, + { + indexed: false, + internalType: 'enum OffchainOracle.OracleType', + name: 'oracleType', + type: 'uint8', + }, + ], + name: 'OracleAdded', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract IOracle', + name: 'oracle', + type: 'address', + }, + { + indexed: false, + internalType: 'enum OffchainOracle.OracleType', + name: 'oracleType', + type: 'uint8', + }, + ], + name: 'OracleRemoved', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'previousOwner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'OwnershipTransferred', + type: 'event', + }, + { + inputs: [ + { + internalType: 'contract IERC20', + name: 'connector', + type: 'address', + }, + ], + name: 'addConnector', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IOracle', + name: 'oracle', + type: 'address', + }, + { + internalType: 'enum OffchainOracle.OracleType', + name: 'oracleKind', + type: 'uint8', + }, + ], + name: 'addOracle', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'connectors', + outputs: [ + { + internalType: 'contract IERC20[]', + name: 'allConnectors', + type: 'address[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IERC20', + name: 'srcToken', + type: 'address', + }, + { + internalType: 'contract IERC20', + name: 'dstToken', + type: 'address', + }, + { + internalType: 'bool', + name: 'useWrappers', + type: 'bool', + }, + ], + name: 'getRate', + outputs: [ + { + internalType: 'uint256', + name: 'weightedRate', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IERC20', + name: 'srcToken', + type: 'address', + }, + { + internalType: 'bool', + name: 'useSrcWrappers', + type: 'bool', + }, + ], + name: 'getRateToEth', + outputs: [ + { + internalType: 'uint256', + name: 'weightedRate', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'multiWrapper', + outputs: [ + { + internalType: 'contract MultiWrapper', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'oracles', + outputs: [ + { + internalType: 'contract IOracle[]', + name: 'allOracles', + type: 'address[]', + }, + { + internalType: 'enum OffchainOracle.OracleType[]', + name: 'oracleTypes', + type: 'uint8[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'owner', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IERC20', + name: 'connector', + type: 'address', + }, + ], + name: 'removeConnector', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IOracle', + name: 'oracle', + type: 'address', + }, + { + internalType: 'enum OffchainOracle.OracleType', + name: 'oracleKind', + type: 'uint8', + }, + ], + name: 'removeOracle', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'renounceOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract MultiWrapper', + name: '_multiWrapper', + type: 'address', + }, + ], + name: 'setMultiWrapper', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'transferOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, +] as const; + +export class OffchainOracleAbi__factory { + static readonly abi = _abi; + static createInterface(): OffchainOracleAbiInterface { + return new utils.Interface(_abi) as OffchainOracleAbiInterface; + } + static connect(address: string, signerOrProvider: Signer | Provider): OffchainOracleAbi { + return new Contract(address, _abi, signerOrProvider) as OffchainOracleAbi; + } +} diff --git a/src/contracts/factories/OptimismL1FeeOracleAbi__factory.ts b/src/contracts/factories/OptimismL1FeeOracleAbi__factory.ts new file mode 100644 index 0000000..a06ea0f --- /dev/null +++ b/src/contracts/factories/OptimismL1FeeOracleAbi__factory.ts @@ -0,0 +1,316 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ + +import { Contract, Signer, utils } from 'ethers'; +import type { Provider } from '@ethersproject/providers'; +import type { OptimismL1FeeOracleAbi, OptimismL1FeeOracleAbiInterface } from '../OptimismL1FeeOracleAbi'; + +const _abi = [ + { + inputs: [ + { + internalType: 'address', + name: '_owner', + type: 'address', + }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + name: 'DecimalsUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + name: 'GasPriceUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + name: 'L1BaseFeeUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + name: 'OverheadUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'previousOwner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'OwnershipTransferred', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + name: 'ScalarUpdated', + type: 'event', + }, + { + inputs: [], + name: 'decimals', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'gasPrice', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes', + name: '_data', + type: 'bytes', + }, + ], + name: 'getL1Fee', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes', + name: '_data', + type: 'bytes', + }, + ], + name: 'getL1GasUsed', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'l1BaseFee', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'overhead', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'owner', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'renounceOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'scalar', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_decimals', + type: 'uint256', + }, + ], + name: 'setDecimals', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_gasPrice', + type: 'uint256', + }, + ], + name: 'setGasPrice', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_baseFee', + type: 'uint256', + }, + ], + name: 'setL1BaseFee', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_overhead', + type: 'uint256', + }, + ], + name: 'setOverhead', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_scalar', + type: 'uint256', + }, + ], + name: 'setScalar', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'transferOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, +] as const; + +export class OptimismL1FeeOracleAbi__factory { + static readonly abi = _abi; + static createInterface(): OptimismL1FeeOracleAbiInterface { + return new utils.Interface(_abi) as OptimismL1FeeOracleAbiInterface; + } + static connect(address: string, signerOrProvider: Signer | Provider): OptimismL1FeeOracleAbi { + return new Contract(address, _abi, signerOrProvider) as OptimismL1FeeOracleAbi; + } +} diff --git a/src/contracts/factories/index.ts b/src/contracts/factories/index.ts new file mode 100644 index 0000000..76d7bed --- /dev/null +++ b/src/contracts/factories/index.ts @@ -0,0 +1,6 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ +export { MulticallAbi__factory } from './MulticallAbi__factory'; +export { OffchainOracleAbi__factory } from './OffchainOracleAbi__factory'; +export { OptimismL1FeeOracleAbi__factory } from './OptimismL1FeeOracleAbi__factory'; diff --git a/src/contracts/index.ts b/src/contracts/index.ts new file mode 100644 index 0000000..805bcd2 --- /dev/null +++ b/src/contracts/index.ts @@ -0,0 +1,10 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ +export type { MulticallAbi } from './MulticallAbi'; +export type { OffchainOracleAbi } from './OffchainOracleAbi'; +export type { OptimismL1FeeOracleAbi } from './OptimismL1FeeOracleAbi'; +export * as factories from './factories'; +export { MulticallAbi__factory } from './factories/MulticallAbi__factory'; +export { OffchainOracleAbi__factory } from './factories/OffchainOracleAbi__factory'; +export { OptimismL1FeeOracleAbi__factory } from './factories/OptimismL1FeeOracleAbi__factory'; diff --git a/src/feeOracle.ts b/src/feeOracle.ts new file mode 100644 index 0000000..a0ca88f --- /dev/null +++ b/src/feeOracle.ts @@ -0,0 +1,141 @@ +import { GasPriceOracle } from '@tornado/gas-price-oracle'; +import { BigNumber, BigNumberish, ethers } from 'ethers'; +import { parseUnits } from 'ethers/lib/utils'; +import { TransactionData, TxType, ITornadoFeeOracle, GasPrice, LegacyGasPriceKey } from './types'; +import { Provider } from '@ethersproject/abstract-provider'; +import { ChainId, defaultGasPrices } from './config'; +import { bump, calculateGasPriceInWei, fromGweiToWeiHex, serializeTx } from './utils'; +import { getOptimismL1FeeOracle } from './contracts/factories'; +import { AvailableTokenSymbols } from '@tornado/tornado-config'; + +export abstract class TornadoFeeOracle implements ITornadoFeeOracle { + protected provider: Provider; + + public constructor( + protected chainId: ChainId, + rpcUrl: string, + protected oracle: GasPriceOracle, + ) { + this.provider = new ethers.providers.JsonRpcProvider(rpcUrl); + } + + /** + * Because Optimism transaction published on Mainnet, for each OP transaction we need to calculate L1 security fee: + * https://community.optimism.io/docs/developers/build/transaction-fees/#priority-fee + * @param {TransactionData} tx Transaction data to estimate L1 additional fee + * @returns Fee in WEI (MATIC) + */ + private async fetchL1OptimismFee(tx?: TransactionData): Promise { + if (this.chainId != ChainId.OPTIMISM) return BigNumber.from(0); + + const optimismL1FeeOracle = getOptimismL1FeeOracle(this.provider); + + return await optimismL1FeeOracle.getL1Fee(serializeTx(tx)); + } + + /** + * Estimates next block gas for signed, unsigned or incomplete Tornado transaction + * @param {TransactionData} tx Transaction data in web3 / ethers format + * @param {TxType} type Tornado transaction type: withdrawal by user, withdrawal by relayer or 'other' + * @param {LegacyGasPriceKey} speed Preferred transaction speed, if uses legacy gas (before EIP-1559) + * @returns {Promise} Gas value in WEI (hex-format) + */ + public async getGas( + tx?: TransactionData, + type: TxType = 'other', + speed: LegacyGasPriceKey = 'fast', + ): Promise { + const gasPrice = await this.getGasPrice(type, speed); + let gas = BigNumber.from(0); + gas = gas.add(calculateGasPriceInWei(gasPrice)); + if (tx) tx = Object.assign(tx, { gasPrice }); + gas = gas.mul(await this.getGasLimit(tx, type)); + if (this.chainId === ChainId.OPTIMISM) gas = gas.add(await this.fetchL1OptimismFee(tx)); + + return gas; + } + + /** + * Estimate next block gas price + * @param {TxType} type Tornado transaction type (to select correct default bump percent) + * @param {LegacyGasPriceKey} speed Preferred transaction speed, if uses legacy gas (before EIP-1559) + * @param {number} bumpPercent Gas bump percent to prioritize transaction + * @returns {GasPrice} Estimated gas price info in WEI (hexed) - legacy object with gasPrice property or EIP-1559 object with maxFeePerGas + * and maxPriorityFeePerGas properties + */ + async getGasPrice( + type: TxType = 'other', + speed: LegacyGasPriceKey = 'fast', + bumpPercent: number = 0, + ): Promise { + try { + return await this.oracle.getTxGasParams({ legacySpeed: speed, bumpPercent }); + } catch (e) { + return { gasPrice: bump(fromGweiToWeiHex(defaultGasPrices[this.chainId][speed]), bumpPercent) }; + } + } + + /** + * Estimates gas limit for transaction (or basic gas limit, if no tx data provided) + * @param {TransactionData} tx Transaction data (object in web3 / ethers format) + * @param {TxType} type Tornado transaction type: withdrawal by user, withdrawal by relayer or 'other' + * @returns {Promise} Gas limit + */ + abstract getGasLimit(tx?: TransactionData, type?: TxType): Promise; + + /** + * If user withdraw non-native tokens on ETH or Goerli, we need to calculate refund value: + * if the withdrawal is successful, this amount will be returned to the user after the transfer to the relayer, + * and if the relayer pays a commission and the transfer of tokens fails, this commission will remain to the relayer. + * + * Refund needed that recipient can use tokens after withdrawal (covers gas fee for send/swap) + * @returns {Promise} Refund amount + */ + async calculateRefundInETH(): Promise { + return (await this.getGas()).mul(2); + } + + /** + * Estimates fee for withdrawal via relayer depending on type: gas bump percent is bigger, if it calculates by user, + * so that the real commission from the relayer side is a little less, + * in order to the relayer can send a transaction without fear that he will go into the red + * @param {TxType} type Tornado transaction type: withdrawal costs calculation from user side or from relayer side + * @param {TransactionData} tx Transaction data (object in web3 / ethers format) + * @param {number} relayerFeePercent Relayer fee percent from the transaction amount (for example, 0.15 for BNB or 0.4 for ETH Mainnet) + * @param {string} currency Currency symbol + * @param {number} amount Withdrawal amount in selected currency + * @param {number} decimals Token (currency) decimals + * @param {BigNumberish} refund Refund in ETH, if withdrawed other tokens on Mainnet (not ETH) + * @param {BigNumberish} tokenPriceInEth If withdrawing other token on Mainnet or Goerli, need to provide token price in ETH (in WEI) + * @returns {Promise} Fee in WEI + */ + async calculateWithdrawalFeeViaRelayer( + type: TxType, + tx: TransactionData, + relayerFeePercent: number, + currency: AvailableTokenSymbols, + amount: string, + decimals: number, + refund: BigNumberish = 0, + tokenPriceInEth?: BigNumberish, + ): Promise { + let withdrawalFee = BigNumber.from(0); + const gasCosts = await this.getGas(tx, type); + withdrawalFee = gasCosts; + + const relayerFee = parseUnits(amount, decimals) + .mul(`${relayerFeePercent * 1e10}`) + .div(`${100 * 1e10}`); + + if ((this.chainId === ChainId.MAINNET || this.chainId === ChainId.GOERLI) && currency.toLowerCase() != 'eth') { + if (!tokenPriceInEth) { + console.error('Token price is required argument, if not native chain token is withdrawed'); + return BigNumber.from(0); + } + const tokenDecimals = BigNumber.from(10).pow(decimals); + return withdrawalFee.add(refund).mul(tokenDecimals).div(tokenPriceInEth).add(relayerFee); + } + + return withdrawalFee.add(relayerFee); + } +} diff --git a/src/feeOracleV4.ts b/src/feeOracleV4.ts new file mode 100644 index 0000000..1f1fb75 --- /dev/null +++ b/src/feeOracleV4.ts @@ -0,0 +1,30 @@ +import { defaultWithdrawalGasLimit } from './config'; +import { TornadoFeeOracle } from './feeOracle'; +import { ITornadoFeeOracle, TransactionData, TxType, LegacyGasPrices } from './types'; +import { GasPriceOracle } from '@tornado/gas-price-oracle'; +import { BigNumber } from 'ethers'; +import { bump } from './utils'; + +export class TornadoFeeOracleV4 extends TornadoFeeOracle implements ITornadoFeeOracle { + public constructor(chainId: number, rpcUrl: string, defaultGasPrices?: LegacyGasPrices) { + const oracleConfig = { + chainId, + defaultRpc: rpcUrl, + defaultFallbackGasPrices: defaultGasPrices, + }; + const gasPriceOracle = new GasPriceOracle(oracleConfig); + + super(chainId, rpcUrl, gasPriceOracle); + } + + async getGasLimit(tx?: TransactionData, type: TxType = 'other'): Promise { + if (type === 'user_withdrawal') return BigNumber.from(defaultWithdrawalGasLimit[this.chainId]); + + // Need to bump relayer gas limit for transaction, because predefined gas limit to small to be 100% sure that transaction will be sent + // This leads to fact that relayer often pays extra for gas from his own funds, however, this was designed by previous developers + if (type === 'relayer_withdrawal') return bump(defaultWithdrawalGasLimit[this.chainId], 20); + if (!tx) return BigNumber.from(21_000); + + return this.provider.estimateGas(tx); + } +} diff --git a/src/feeOracleV5.ts b/src/feeOracleV5.ts new file mode 100644 index 0000000..ccbd2b5 --- /dev/null +++ b/src/feeOracleV5.ts @@ -0,0 +1,65 @@ +import { ChainId, defaultWithdrawalGasLimit } from './config'; +import { TornadoFeeOracle } from './feeOracle'; +import { ITornadoFeeOracle, GasPrice, TransactionData, TxType, LegacyGasPrices, LegacyGasPriceKey } from './types'; +import { GasPriceOracle } from '@tornado/gas-price-oracle'; +import { BigNumber } from 'ethers'; +import { bump } from './utils'; + +export class TornadoFeeOracleV5 extends TornadoFeeOracle implements ITornadoFeeOracle { + public constructor(chainId: number, rpcUrl: string, defaultGasPrices?: LegacyGasPrices) { + const oracleConfig = { + chainId, + defaultRpc: rpcUrl, + minPriority: chainId === 1 || chainId === 5 ? 2 : 0.05, + percentile: 5, + blocksCount: 20, + defaultFallbackGasPrices: defaultGasPrices, + }; + const gasPriceOracle = new GasPriceOracle(oracleConfig); + + super(chainId, rpcUrl, gasPriceOracle); + } + + async getGasLimit(tx?: TransactionData, type: TxType = 'other', bumpPercent: number = 20): Promise { + if (!tx) return BigNumber.from(21_000); + + /* Relayer gas limit must be lower so that fluctuations in gas price cannot lead to the fact that + * the relayer will actually pay for gas more than the money allocated for this by the user + * (that is, in fact, relayer will pay for gas from his own money, unless we make the bump percent less for him) + */ + if (type === 'relayer_withdrawal') bumpPercent = 10; + if (type === 'user_withdrawal') bumpPercent = 30; + + try { + const fetchedGasLimit = await this.provider.estimateGas(tx); + return bump(fetchedGasLimit, bumpPercent); + } catch (e) { + if (type.endsWith('withdrawal')) return bump(defaultWithdrawalGasLimit[this.chainId], bumpPercent); + return BigNumber.from(21_000); + } + } + + async getGasPrice( + type: TxType = 'other', + speed: LegacyGasPriceKey = 'fast', + bumpPercent?: number, + ): Promise { + // Only if bump percent didn't provided (if user provides 0, no need to recalculate) + if (bumpPercent === undefined) { + switch (this.chainId) { + case ChainId.GOERLI: + bumpPercent = type === 'user_withdrawal' ? 100 : 50; + break; + case ChainId.POLYGON: + case ChainId.AVAX: + case ChainId.XDAI: + bumpPercent = 30; + break; + default: + bumpPercent = 10; + } + } + + return super.getGasPrice(type, speed, bumpPercent); + } +} diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..0af80b3 --- /dev/null +++ b/src/index.ts @@ -0,0 +1,6 @@ +import { bump } from './utils'; + +export * from './feeOracleV4'; +export * from './feeOracleV5'; +export * from './tokenPriceOracle'; +export { bump }; diff --git a/src/tokenPriceOracle.ts b/src/tokenPriceOracle.ts new file mode 100644 index 0000000..e1257a3 --- /dev/null +++ b/src/tokenPriceOracle.ts @@ -0,0 +1,100 @@ +import { MultiCall } from './contracts/MulticallAbi'; +import { Token, TokenPrices, TokenSymbol } from './types'; +import { MulticallAbi, OffchainOracleAbi } from './contracts'; +import { getMultiCallContract, getOffchainOracleContract } from './contracts/factories'; +import { Provider } from '@ethersproject/abstract-provider'; +import { ethers, BigNumber } from 'ethers'; +import { defaultAbiCoder } from 'ethers/lib/utils'; +import { instances, Instances } from '@tornado/tornado-config'; +import { ChainId } from './config'; + +/** + * Filter non-native tokens from Tornado instances config + * @param instances Tornado instances from torn-token config ('@tornado/tornado-config' library) + * @returns Array of non-native tokens + */ +function filterTokensFromTornadoInstances(instances: Instances): Token[] { + const ethInstances = Object.values(instances[ChainId.MAINNET]); + return ethInstances.filter((tokenInstance) => !!tokenInstance.tokenAddress) as Token[]; +} + +const tornToken: Token = { + tokenAddress: '0x77777FeDdddFfC19Ff86DB637967013e6C6A116C', + symbol: 'torn', + decimals: 18, +}; +const tornadoTokens = [tornToken, ...filterTokensFromTornadoInstances(instances)]; + +const defaultTokenPrices: TokenPrices = { + cdai: '12143621157112', + dai: '543174175301531', + usdc: '543496781058130', + usdt: '540358243246849', + wbtc: '15944433090979762571', + torn: '1683813509941878', +}; + +export class TokenPriceOracle { + private oracle: OffchainOracleAbi; + private multiCall: MulticallAbi; + private provider: Provider; + + /** + * + * @param rpcUrl + * @param tokens + */ + constructor( + rpcUrl: string, + private tokens: Token[] = tornadoTokens, + ) { + this.provider = new ethers.providers.JsonRpcProvider(rpcUrl); + this.oracle = getOffchainOracleContract(this.provider); + this.multiCall = getMultiCallContract(this.provider); + } + + /** + * Prepare data for MultiCall contract + * @param {Token[]} tokens Tokens array + * @returns Valid structure to provide to MultiCall contract + */ + prepareCallData(tokens: Token[] = this.tokens): MultiCall.CallStruct[] { + return tokens.map((token) => ({ + to: this.oracle.address, + data: this.oracle.interface.encodeFunctionData('getRateToEth', [token.tokenAddress, true]), + })); + } + + /** + * Fetch actual tokens price rate to ETH from offchain oracles + * @param {Token[]} tokens Token array + * @returns {TokenPrices} Object with token price rate to ETH in WEI + */ + async fetchPrices(tokens: Token[] = this.tokens): Promise { + try { + if (!tokens?.length) return {}; + + const callData = this.prepareCallData(tokens); + const { results, success } = await this.multiCall.multicall(callData); + const prices: TokenPrices = {}; + + for (let i = 0; i < results.length; i++) { + const tokenSymbol = tokens[i].symbol.toLowerCase() as TokenSymbol; + if (!success[i]) { + if (defaultTokenPrices[tokenSymbol]) prices[tokenSymbol] = defaultTokenPrices[tokenSymbol]; + continue; + } + + const decodedRate = defaultAbiCoder.decode(['uint256'], results[i]).toString(); + const tokenDecimals = BigNumber.from(10).pow(tokens[i].decimals); + const ethDecimals = BigNumber.from(10).pow(18); + const price = BigNumber.from(decodedRate).mul(tokenDecimals).div(ethDecimals); + prices[tokenSymbol] = price.toString(); + } + return prices; + } catch (e) { + console.error('Cannot get token prices, return default: ' + e); + return defaultTokenPrices; + } + } +} diff --git a/src/types.ts b/src/types.ts new file mode 100644 index 0000000..3d501ce --- /dev/null +++ b/src/types.ts @@ -0,0 +1,62 @@ +import { BigNumber, BigNumberish, BytesLike } from 'ethers'; +import { GasPriceKey } from '@tornado/gas-price-oracle/lib/services'; +import { AvailableTokenSymbols } from '@tornado/tornado-config'; + +export type LegacyGasPriceKey = GasPriceKey; +// Gas Prices in WEI +export type GasPrice = { maxFeePerGas: BigNumberish; maxPriorityFeePerGas: BigNumberish } | { gasPrice: BigNumberish }; +export type LegacyGasPrices = { + [gasPriceType in LegacyGasPriceKey]: number; +}; + +export type TxType = 'user_withdrawal' | 'relayer_withdrawal' | 'other'; + +export interface TransactionData { + to: string; + from?: string; + nonce?: number; + gasLimit?: BigNumberish; + gasPrice?: BigNumberish; + data?: string; + value: BigNumberish; + chainId?: number; + type?: number; + maxFeePerGas?: BigNumberish; + maxPriorityFeePerGas?: BigNumberish; +} + +export interface ITornadoFeeOracle { + getGas: (tx?: TransactionData, type?: TxType) => Promise; + getGasPrice: (type?: TxType, speed?: LegacyGasPriceKey, bumpPercent?: number) => Promise; + getGasLimit: (tx?: TransactionData, type?: TxType, bumpPercent?: number) => Promise; + calculateRefundInETH: () => Promise; + calculateWithdrawalFeeViaRelayer: ( + type: TxType, + tx: TransactionData, + relayerFeePercent: number, + currency: AvailableTokenSymbols, + amount: string, + decimals: number, + refund: BigNumberish, + tokenPriceInEth?: BigNumberish, + ) => Promise; +} + +export type WithdrawalData = { + contract: string; + proof: BytesLike; + args: [BytesLike, BytesLike, string, string, BigNumberish, BigNumberish]; +}; +export type TornadoPoolInstance = { + currency: AvailableTokenSymbols; + amount: number; + decimals: number; +}; + +export type TokenSymbol = 'dai' | 'cdai' | 'usdc' | 'usdt' | 'wbtc' | 'torn'; +export type Token = { + tokenAddress: string; + symbol: TokenSymbol; + decimals: number; +}; +export type TokenPrices = { [tokenSymbol in TokenSymbol]?: BigNumberish }; diff --git a/src/utils.ts b/src/utils.ts new file mode 100644 index 0000000..efa38fd --- /dev/null +++ b/src/utils.ts @@ -0,0 +1,34 @@ +import { serialize } from '@ethersproject/transactions'; +import { GasPrice, TransactionData } from './types'; +import { BigNumber, BigNumberish } from 'ethers'; +import BigNumberFloat from 'bignumber.js'; +BigNumberFloat.config({ EXPONENTIAL_AT: 100 }); + +const GWEI = 1e9; + +export function serializeTx(tx?: TransactionData | string): string { + if (!tx) tx = '0x'; + if (typeof tx === 'string') return tx; + + return serialize(tx); +} + +export function calculateGasPriceInWei(gasPrice: GasPrice): BigNumber { + // @ts-ignore + return gasPrice.gasPrice || gasPrice.maxFeePerGas; +} + +export function bump(value: BigNumberish, percent: number): BigNumber { + const hundredPercents = BigNumberFloat(100); + + return BigNumber.from( + BigNumberFloat(BigNumber.from(value).toHexString()) + .times(hundredPercents.plus(BigNumberFloat(percent))) + .div(hundredPercents) + .toString(), + ); +} + +export function fromGweiToWeiHex(value: number | string): BigNumberish { + return BigNumber.from(BigNumberFloat(value).times(GWEI).toString()).toHexString(); +} diff --git a/tsconfig.esm.json b/tsconfig.esm.json new file mode 100644 index 0000000..f6421c6 --- /dev/null +++ b/tsconfig.esm.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig", + "compilerOptions": { + "declaration": false, + "target": "es2015", + "module": "es2015", + "outDir": "lib/esm" + } +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..7dd9c15 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,33 @@ +{ + "compilerOptions": { + "target": "es5", + "module": "commonjs", + "moduleResolution": "node", + "lib": ["es5", "es6", "es2021", "esnext"], + "experimentalDecorators": true, + "sourceMap": true, + "outDir": "lib", + "noImplicitAny": true, + "allowJs": true, + "declaration": true, + "skipLibCheck": true, + "esModuleInterop": true, + "checkJs": false, + "noUnusedLocals": true, + "strictNullChecks": true, + "noImplicitThis": true, + "noImplicitReturns": true, + "allowSyntheticDefaultImports": true, + "strictFunctionTypes": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true, + "isolatedModules": true, + "baseUrl": ".", + "paths": { + "@/*": ["./src/*"] + }, + "types": ["@types/node"] + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "src/tests"] +} diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 0000000..26e7960 --- /dev/null +++ b/yarn.lock @@ -0,0 +1,1151 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@cspotcode/source-map-support@^0.8.0": + version "0.8.1" + resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1" + integrity sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw== + dependencies: + "@jridgewell/trace-mapping" "0.3.9" + +"@ethersproject/abi@5.7.0", "@ethersproject/abi@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.7.0.tgz#b3f3e045bbbeed1af3947335c247ad625a44e449" + integrity sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA== + dependencies: + "@ethersproject/address" "^5.7.0" + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/constants" "^5.7.0" + "@ethersproject/hash" "^5.7.0" + "@ethersproject/keccak256" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + "@ethersproject/strings" "^5.7.0" + +"@ethersproject/abstract-provider@5.7.0", "@ethersproject/abstract-provider@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/abstract-provider/-/abstract-provider-5.7.0.tgz#b0a8550f88b6bf9d51f90e4795d48294630cb9ef" + integrity sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw== + dependencies: + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/networks" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + "@ethersproject/transactions" "^5.7.0" + "@ethersproject/web" "^5.7.0" + +"@ethersproject/abstract-signer@5.7.0", "@ethersproject/abstract-signer@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/abstract-signer/-/abstract-signer-5.7.0.tgz#13f4f32117868452191a4649723cb086d2b596b2" + integrity sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ== + dependencies: + "@ethersproject/abstract-provider" "^5.7.0" + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + +"@ethersproject/address@5.7.0", "@ethersproject/address@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/address/-/address-5.7.0.tgz#19b56c4d74a3b0a46bfdbb6cfcc0a153fc697f37" + integrity sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA== + dependencies: + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/keccak256" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/rlp" "^5.7.0" + +"@ethersproject/base64@5.7.0", "@ethersproject/base64@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/base64/-/base64-5.7.0.tgz#ac4ee92aa36c1628173e221d0d01f53692059e1c" + integrity sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ== + dependencies: + "@ethersproject/bytes" "^5.7.0" + +"@ethersproject/basex@5.7.0", "@ethersproject/basex@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/basex/-/basex-5.7.0.tgz#97034dc7e8938a8ca943ab20f8a5e492ece4020b" + integrity sha512-ywlh43GwZLv2Voc2gQVTKBoVQ1mti3d8HK5aMxsfu/nRDnMmNqaSJ3r3n85HBByT8OpoY96SXM1FogC533T4zw== + dependencies: + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + +"@ethersproject/bignumber@5.7.0", "@ethersproject/bignumber@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/bignumber/-/bignumber-5.7.0.tgz#e2f03837f268ba655ffba03a57853e18a18dc9c2" + integrity sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw== + dependencies: + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + bn.js "^5.2.1" + +"@ethersproject/bytes@5.7.0", "@ethersproject/bytes@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.7.0.tgz#a00f6ea8d7e7534d6d87f47188af1148d71f155d" + integrity sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A== + dependencies: + "@ethersproject/logger" "^5.7.0" + +"@ethersproject/constants@5.7.0", "@ethersproject/constants@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/constants/-/constants-5.7.0.tgz#df80a9705a7e08984161f09014ea012d1c75295e" + integrity sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA== + dependencies: + "@ethersproject/bignumber" "^5.7.0" + +"@ethersproject/contracts@5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/contracts/-/contracts-5.7.0.tgz#c305e775abd07e48aa590e1a877ed5c316f8bd1e" + integrity sha512-5GJbzEU3X+d33CdfPhcyS+z8MzsTrBGk/sc+G+59+tPa9yFkl6HQ9D6L0QMgNTA9q8dT0XKxxkyp883XsQvbbg== + dependencies: + "@ethersproject/abi" "^5.7.0" + "@ethersproject/abstract-provider" "^5.7.0" + "@ethersproject/abstract-signer" "^5.7.0" + "@ethersproject/address" "^5.7.0" + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/constants" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + "@ethersproject/transactions" "^5.7.0" + +"@ethersproject/hash@5.7.0", "@ethersproject/hash@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/hash/-/hash-5.7.0.tgz#eb7aca84a588508369562e16e514b539ba5240a7" + integrity sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g== + dependencies: + "@ethersproject/abstract-signer" "^5.7.0" + "@ethersproject/address" "^5.7.0" + "@ethersproject/base64" "^5.7.0" + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/keccak256" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + "@ethersproject/strings" "^5.7.0" + +"@ethersproject/hdnode@5.7.0", "@ethersproject/hdnode@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/hdnode/-/hdnode-5.7.0.tgz#e627ddc6b466bc77aebf1a6b9e47405ca5aef9cf" + integrity sha512-OmyYo9EENBPPf4ERhR7oj6uAtUAhYGqOnIS+jE5pTXvdKBS99ikzq1E7Iv0ZQZ5V36Lqx1qZLeak0Ra16qpeOg== + dependencies: + "@ethersproject/abstract-signer" "^5.7.0" + "@ethersproject/basex" "^5.7.0" + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/pbkdf2" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + "@ethersproject/sha2" "^5.7.0" + "@ethersproject/signing-key" "^5.7.0" + "@ethersproject/strings" "^5.7.0" + "@ethersproject/transactions" "^5.7.0" + "@ethersproject/wordlists" "^5.7.0" + +"@ethersproject/json-wallets@5.7.0", "@ethersproject/json-wallets@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/json-wallets/-/json-wallets-5.7.0.tgz#5e3355287b548c32b368d91014919ebebddd5360" + integrity sha512-8oee5Xgu6+RKgJTkvEMl2wDgSPSAQ9MB/3JYjFV9jlKvcYHUXZC+cQp0njgmxdHkYWn8s6/IqIZYm0YWCjO/0g== + dependencies: + "@ethersproject/abstract-signer" "^5.7.0" + "@ethersproject/address" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/hdnode" "^5.7.0" + "@ethersproject/keccak256" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/pbkdf2" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + "@ethersproject/random" "^5.7.0" + "@ethersproject/strings" "^5.7.0" + "@ethersproject/transactions" "^5.7.0" + aes-js "3.0.0" + scrypt-js "3.0.1" + +"@ethersproject/keccak256@5.7.0", "@ethersproject/keccak256@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/keccak256/-/keccak256-5.7.0.tgz#3186350c6e1cd6aba7940384ec7d6d9db01f335a" + integrity sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg== + dependencies: + "@ethersproject/bytes" "^5.7.0" + js-sha3 "0.8.0" + +"@ethersproject/logger@5.7.0", "@ethersproject/logger@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.7.0.tgz#6ce9ae168e74fecf287be17062b590852c311892" + integrity sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig== + +"@ethersproject/networks@5.7.1", "@ethersproject/networks@^5.7.0": + version "5.7.1" + resolved "https://registry.yarnpkg.com/@ethersproject/networks/-/networks-5.7.1.tgz#118e1a981d757d45ccea6bb58d9fd3d9db14ead6" + integrity sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ== + dependencies: + "@ethersproject/logger" "^5.7.0" + +"@ethersproject/pbkdf2@5.7.0", "@ethersproject/pbkdf2@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/pbkdf2/-/pbkdf2-5.7.0.tgz#d2267d0a1f6e123f3771007338c47cccd83d3102" + integrity sha512-oR/dBRZR6GTyaofd86DehG72hY6NpAjhabkhxgr3X2FpJtJuodEl2auADWBZfhDHgVCbu3/H/Ocq2uC6dpNjjw== + dependencies: + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/sha2" "^5.7.0" + +"@ethersproject/properties@5.7.0", "@ethersproject/properties@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/properties/-/properties-5.7.0.tgz#a6e12cb0439b878aaf470f1902a176033067ed30" + integrity sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw== + dependencies: + "@ethersproject/logger" "^5.7.0" + +"@ethersproject/providers@5.7.2": + version "5.7.2" + resolved "https://registry.yarnpkg.com/@ethersproject/providers/-/providers-5.7.2.tgz#f8b1a4f275d7ce58cf0a2eec222269a08beb18cb" + integrity sha512-g34EWZ1WWAVgr4aptGlVBF8mhl3VWjv+8hoAnzStu8Ah22VHBsuGzP17eb6xDVRzw895G4W7vvx60lFFur/1Rg== + dependencies: + "@ethersproject/abstract-provider" "^5.7.0" + "@ethersproject/abstract-signer" "^5.7.0" + "@ethersproject/address" "^5.7.0" + "@ethersproject/base64" "^5.7.0" + "@ethersproject/basex" "^5.7.0" + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/constants" "^5.7.0" + "@ethersproject/hash" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/networks" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + "@ethersproject/random" "^5.7.0" + "@ethersproject/rlp" "^5.7.0" + "@ethersproject/sha2" "^5.7.0" + "@ethersproject/strings" "^5.7.0" + "@ethersproject/transactions" "^5.7.0" + "@ethersproject/web" "^5.7.0" + bech32 "1.1.4" + ws "7.4.6" + +"@ethersproject/random@5.7.0", "@ethersproject/random@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/random/-/random-5.7.0.tgz#af19dcbc2484aae078bb03656ec05df66253280c" + integrity sha512-19WjScqRA8IIeWclFme75VMXSBvi4e6InrUNuaR4s5pTF2qNhcGdCUwdxUVGtDDqC00sDLCO93jPQoDUH4HVmQ== + dependencies: + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + +"@ethersproject/rlp@5.7.0", "@ethersproject/rlp@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/rlp/-/rlp-5.7.0.tgz#de39e4d5918b9d74d46de93af80b7685a9c21304" + integrity sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w== + dependencies: + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + +"@ethersproject/sha2@5.7.0", "@ethersproject/sha2@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/sha2/-/sha2-5.7.0.tgz#9a5f7a7824ef784f7f7680984e593a800480c9fb" + integrity sha512-gKlH42riwb3KYp0reLsFTokByAKoJdgFCwI+CCiX/k+Jm2mbNs6oOaCjYQSlI1+XBVejwH2KrmCbMAT/GnRDQw== + dependencies: + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + hash.js "1.1.7" + +"@ethersproject/signing-key@5.7.0", "@ethersproject/signing-key@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/signing-key/-/signing-key-5.7.0.tgz#06b2df39411b00bc57c7c09b01d1e41cf1b16ab3" + integrity sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q== + dependencies: + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + bn.js "^5.2.1" + elliptic "6.5.4" + hash.js "1.1.7" + +"@ethersproject/solidity@5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/solidity/-/solidity-5.7.0.tgz#5e9c911d8a2acce2a5ebb48a5e2e0af20b631cb8" + integrity sha512-HmabMd2Dt/raavyaGukF4XxizWKhKQ24DoLtdNbBmNKUOPqwjsKQSdV9GQtj9CBEea9DlzETlVER1gYeXXBGaA== + dependencies: + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/keccak256" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/sha2" "^5.7.0" + "@ethersproject/strings" "^5.7.0" + +"@ethersproject/strings@5.7.0", "@ethersproject/strings@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.7.0.tgz#54c9d2a7c57ae8f1205c88a9d3a56471e14d5ed2" + integrity sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg== + dependencies: + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/constants" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + +"@ethersproject/transactions@5.7.0", "@ethersproject/transactions@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/transactions/-/transactions-5.7.0.tgz#91318fc24063e057885a6af13fdb703e1f993d3b" + integrity sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ== + dependencies: + "@ethersproject/address" "^5.7.0" + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/constants" "^5.7.0" + "@ethersproject/keccak256" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + "@ethersproject/rlp" "^5.7.0" + "@ethersproject/signing-key" "^5.7.0" + +"@ethersproject/units@5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/units/-/units-5.7.0.tgz#637b563d7e14f42deeee39245275d477aae1d8b1" + integrity sha512-pD3xLMy3SJu9kG5xDGI7+xhTEmGXlEqXU4OfNapmfnxLVY4EMSSRp7j1k7eezutBPH7RBN/7QPnwR7hzNlEFeg== + dependencies: + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/constants" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + +"@ethersproject/wallet@5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/wallet/-/wallet-5.7.0.tgz#4e5d0790d96fe21d61d38fb40324e6c7ef350b2d" + integrity sha512-MhmXlJXEJFBFVKrDLB4ZdDzxcBxQ3rLyCkhNqVu3CDYvR97E+8r01UgrI+TI99Le+aYm/in/0vp86guJuM7FCA== + dependencies: + "@ethersproject/abstract-provider" "^5.7.0" + "@ethersproject/abstract-signer" "^5.7.0" + "@ethersproject/address" "^5.7.0" + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/hash" "^5.7.0" + "@ethersproject/hdnode" "^5.7.0" + "@ethersproject/json-wallets" "^5.7.0" + "@ethersproject/keccak256" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + "@ethersproject/random" "^5.7.0" + "@ethersproject/signing-key" "^5.7.0" + "@ethersproject/transactions" "^5.7.0" + "@ethersproject/wordlists" "^5.7.0" + +"@ethersproject/web@5.7.1", "@ethersproject/web@^5.7.0": + version "5.7.1" + resolved "https://registry.yarnpkg.com/@ethersproject/web/-/web-5.7.1.tgz#de1f285b373149bee5928f4eb7bcb87ee5fbb4ae" + integrity sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w== + dependencies: + "@ethersproject/base64" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + "@ethersproject/strings" "^5.7.0" + +"@ethersproject/wordlists@5.7.0", "@ethersproject/wordlists@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/wordlists/-/wordlists-5.7.0.tgz#8fb2c07185d68c3e09eb3bfd6e779ba2774627f5" + integrity sha512-S2TFNJNfHWVHNE6cNDjbVlZ6MgE17MIxMbMg2zv3wn+3XSJGosL1m9ZVv3GXCf/2ymSsQ+hRI5IzoMJTG6aoVA== + dependencies: + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/hash" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + "@ethersproject/strings" "^5.7.0" + +"@jridgewell/resolve-uri@^3.0.3": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz#c08679063f279615a3326583ba3a90d1d82cc721" + integrity sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA== + +"@jridgewell/sourcemap-codec@^1.4.10": + version "1.4.15" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" + integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== + +"@jridgewell/trace-mapping@0.3.9": + version "0.3.9" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9" + integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ== + dependencies: + "@jridgewell/resolve-uri" "^3.0.3" + "@jridgewell/sourcemap-codec" "^1.4.10" + +"@tornado/gas-price-oracle@^0.5.3": + version "0.5.3" + resolved "https://git.tornado.ws/api/packages/tornado-packages/npm/%40tornado%2Fgas-price-oracle/-/0.5.3/gas-price-oracle-0.5.3.tgz#fb5423dddee2f52edbc16174c5ddce90bea5413d" + integrity sha512-LpVfPiPIz3FOmJdiqJf/yoeO5n9/Pd5jgtdY+6hB9lNW0AiWhylhpScojICViS+3OL9QC8CoTlgr+kbfGeO9pQ== + dependencies: + axios "^0.21.2" + bignumber.js "^9.0.0" + node-cache "^5.1.2" + +"@tornado/tornado-config@^2.0.0": + version "2.0.0" + resolved "https://git.tornado.ws/api/packages/tornado-packages/npm/%40tornado%2Ftornado-config/-/2.0.0/tornado-config-2.0.0.tgz#52bbc179ecb2385f71b4d56e060b68e7dd6fb8b4" + integrity sha512-7EkpWNfEm34VEOrbLnPpvd/aUJYnA1L+6/qx2fZ/AfmuJFkjSZ18Z4jvVGNY7ktKIhTu3/Tbze+9l3eNueCNIA== + +"@tsconfig/node10@^1.0.7": + version "1.0.9" + resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.9.tgz#df4907fc07a886922637b15e02d4cebc4c0021b2" + integrity sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA== + +"@tsconfig/node12@^1.0.7": + version "1.0.11" + resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.11.tgz#ee3def1f27d9ed66dac6e46a295cffb0152e058d" + integrity sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag== + +"@tsconfig/node14@^1.0.0": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.3.tgz#e4386316284f00b98435bf40f72f75a09dabf6c1" + integrity sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow== + +"@tsconfig/node16@^1.0.2": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.4.tgz#0b92dcc0cc1c81f6f306a381f28e31b1a56536e9" + integrity sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA== + +"@typechain/ethers-v5@^11.1.1": + version "11.1.1" + resolved "https://registry.yarnpkg.com/@typechain/ethers-v5/-/ethers-v5-11.1.1.tgz#23a358135a302140cf89a186592464dd6bbf1f98" + integrity sha512-D9WyUrCJ4Z5Gg8T00HWLpuqn1CqSDXlCiUOOpLaWoCbnZrE2jSIOUwR9blBZNo6LE5058e3niVu6xk205Et7tg== + dependencies: + lodash "^4.17.15" + ts-essentials "^7.0.1" + +"@types/node@^20.4.10": + version "20.4.10" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.4.10.tgz#73c9480791e3ddeb4887a660fc93a7f59353ad45" + integrity sha512-vwzFiiy8Rn6E0MtA13/Cxxgpan/N6UeNYR9oUu6kuJWxu6zCk98trcDp8CBhbtaeuq9SykCmXkFr2lWLoPcvLg== + +"@types/prettier@^2.1.1": + version "2.7.3" + resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.7.3.tgz#3e51a17e291d01d17d3fc61422015a933af7a08f" + integrity sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA== + +abbrev@1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== + +acorn-walk@^8.1.1: + version "8.2.0" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" + integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== + +acorn@^8.4.1: + version "8.10.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5" + integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== + +aes-js@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-3.0.0.tgz#e21df10ad6c2053295bcbb8dab40b09dbea87e4d" + integrity sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw== + +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +anymatch@~3.1.2: + version "3.1.3" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" + integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +arg@^4.1.0: + version "4.1.3" + resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" + integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== + +array-back@^3.0.1, array-back@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/array-back/-/array-back-3.1.0.tgz#b8859d7a508871c9a7b2cf42f99428f65e96bfb0" + integrity sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q== + +array-back@^4.0.1, array-back@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/array-back/-/array-back-4.0.2.tgz#8004e999a6274586beeb27342168652fdb89fa1e" + integrity sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg== + +axios@^0.21.2: + version "0.21.4" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.4.tgz#c67b90dc0568e5c1cf2b0b858c43ba28e2eda575" + integrity sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg== + dependencies: + follow-redirects "^1.14.0" + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +bech32@1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/bech32/-/bech32-1.1.4.tgz#e38c9f37bf179b8eb16ae3a772b40c356d4832e9" + integrity sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ== + +bignumber.js@^9.0.0, bignumber.js@^9.1.1: + version "9.1.1" + resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.1.1.tgz#c4df7dc496bd849d4c9464344c1aa74228b4dac6" + integrity sha512-pHm4LsMJ6lzgNGVfZHjMoO8sdoRhOzOH4MLmY65Jg70bpxCKu5iOHNJyfF6OyvYw7t8Fpf35RuzUyqnQsj8Vig== + +binary-extensions@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" + integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== + +bn.js@^4.11.9: + version "4.12.0" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" + integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== + +bn.js@^5.2.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70" + integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ== + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +brorand@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" + integrity sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w== + +chalk@^2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chalk@^4.1.0: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +chokidar@^3.5.2: + version "3.5.3" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" + integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + +clone@2.x: + version "2.1.2" + resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f" + integrity sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w== + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +command-line-args@^5.1.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/command-line-args/-/command-line-args-5.2.1.tgz#c44c32e437a57d7c51157696893c5909e9cec42e" + integrity sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg== + dependencies: + array-back "^3.1.0" + find-replace "^3.0.0" + lodash.camelcase "^4.3.0" + typical "^4.0.0" + +command-line-usage@^6.1.0: + version "6.1.3" + resolved "https://registry.yarnpkg.com/command-line-usage/-/command-line-usage-6.1.3.tgz#428fa5acde6a838779dfa30e44686f4b6761d957" + integrity sha512-sH5ZSPr+7UStsloltmDh7Ce5fb8XPlHyoPzTpyyMuYCtervL65+ubVZ6Q61cFtFl62UyJlc8/JwERRbAFPUqgw== + dependencies: + array-back "^4.0.2" + chalk "^2.4.2" + table-layout "^1.0.2" + typical "^5.2.0" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== + +create-require@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" + integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== + +debug@^3.2.7: + version "3.2.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" + integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== + dependencies: + ms "^2.1.1" + +debug@^4.3.1: + version "4.3.4" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + +deep-extend@~0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== + +diff@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" + integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== + +elliptic@6.5.4: + version "6.5.4" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb" + integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ== + dependencies: + bn.js "^4.11.9" + brorand "^1.1.0" + hash.js "^1.0.0" + hmac-drbg "^1.0.1" + inherits "^2.0.4" + minimalistic-assert "^1.0.1" + minimalistic-crypto-utils "^1.0.1" + +escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== + +ethers@5.7: + version "5.7.2" + resolved "https://registry.yarnpkg.com/ethers/-/ethers-5.7.2.tgz#3a7deeabbb8c030d4126b24f84e525466145872e" + integrity sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg== + dependencies: + "@ethersproject/abi" "5.7.0" + "@ethersproject/abstract-provider" "5.7.0" + "@ethersproject/abstract-signer" "5.7.0" + "@ethersproject/address" "5.7.0" + "@ethersproject/base64" "5.7.0" + "@ethersproject/basex" "5.7.0" + "@ethersproject/bignumber" "5.7.0" + "@ethersproject/bytes" "5.7.0" + "@ethersproject/constants" "5.7.0" + "@ethersproject/contracts" "5.7.0" + "@ethersproject/hash" "5.7.0" + "@ethersproject/hdnode" "5.7.0" + "@ethersproject/json-wallets" "5.7.0" + "@ethersproject/keccak256" "5.7.0" + "@ethersproject/logger" "5.7.0" + "@ethersproject/networks" "5.7.1" + "@ethersproject/pbkdf2" "5.7.0" + "@ethersproject/properties" "5.7.0" + "@ethersproject/providers" "5.7.2" + "@ethersproject/random" "5.7.0" + "@ethersproject/rlp" "5.7.0" + "@ethersproject/sha2" "5.7.0" + "@ethersproject/signing-key" "5.7.0" + "@ethersproject/solidity" "5.7.0" + "@ethersproject/strings" "5.7.0" + "@ethersproject/transactions" "5.7.0" + "@ethersproject/units" "5.7.0" + "@ethersproject/wallet" "5.7.0" + "@ethersproject/web" "5.7.1" + "@ethersproject/wordlists" "5.7.0" + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +find-replace@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/find-replace/-/find-replace-3.0.0.tgz#3e7e23d3b05167a76f770c9fbd5258b0def68c38" + integrity sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ== + dependencies: + array-back "^3.0.1" + +follow-redirects@^1.14.0: + version "1.15.2" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13" + integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA== + +fs-extra@^7.0.0: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9" + integrity sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw== + dependencies: + graceful-fs "^4.1.2" + jsonfile "^4.0.0" + universalify "^0.1.0" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== + +fsevents@~2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" + integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + +glob-parent@~5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +glob@7.1.7: + version "7.1.7" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90" + integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +graceful-fs@^4.1.2, graceful-fs@^4.1.6: + version "4.2.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" + integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +hash.js@1.1.7, hash.js@^1.0.0, hash.js@^1.0.3: + version "1.1.7" + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" + integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== + dependencies: + inherits "^2.0.3" + minimalistic-assert "^1.0.1" + +hmac-drbg@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" + integrity sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg== + dependencies: + hash.js "^1.0.3" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.1" + +ignore-by-default@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09" + integrity sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA== + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@^2.0.3, inherits@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== + +is-glob@^4.0.1, is-glob@~4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +js-sha3@0.8.0, js-sha3@^0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840" + integrity sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q== + +jsonfile@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" + integrity sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg== + optionalDependencies: + graceful-fs "^4.1.6" + +lodash.camelcase@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" + integrity sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA== + +lodash@^4.17.15: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +make-error@^1.1.1: + version "1.3.6" + resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" + integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== + +minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== + +minimalistic-crypto-utils@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" + integrity sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg== + +minimatch@^3.0.4, minimatch@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +mkdirp@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" + integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +ms@^2.1.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +node-cache@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/node-cache/-/node-cache-5.1.2.tgz#f264dc2ccad0a780e76253a694e9fd0ed19c398d" + integrity sha512-t1QzWwnk4sjLWaQAS8CHgOJ+RAfmHpxFWmc36IWTiWHQfs0w5JDMBS1b1ZxQteo0vVVuWJvIUKHDkkeK7vIGCg== + dependencies: + clone "2.x" + +nodemon@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-3.0.1.tgz#affe822a2c5f21354466b2fc8ae83277d27dadc7" + integrity sha512-g9AZ7HmkhQkqXkRc20w+ZfQ73cHLbE8hnPbtaFbFtCumZsjyMhKk9LajQ07U5Ux28lvFjZ5X7HvWR1xzU8jHVw== + dependencies: + chokidar "^3.5.2" + debug "^3.2.7" + ignore-by-default "^1.0.1" + minimatch "^3.1.2" + pstree.remy "^1.1.8" + semver "^7.5.3" + simple-update-notifier "^2.0.0" + supports-color "^5.5.0" + touch "^3.1.0" + undefsafe "^2.0.5" + +nopt@~1.0.10: + version "1.0.10" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-1.0.10.tgz#6ddd21bd2a31417b92727dd585f8a6f37608ebee" + integrity sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg== + dependencies: + abbrev "1" + +normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== + dependencies: + wrappy "1" + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== + +picomatch@^2.0.4, picomatch@^2.2.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +prettier@^2.3.1: + version "2.8.8" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da" + integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q== + +prettier@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.0.1.tgz#65271fc9320ce4913c57747a70ce635b30beaa40" + integrity sha512-fcOWSnnpCrovBsmFZIGIy9UqK2FaI7Hqax+DIO0A9UxeVoY4iweyaFjS5TavZN97Hfehph0nhsZnjlVKzEQSrQ== + +pstree.remy@^1.1.8: + version "1.1.8" + resolved "https://registry.yarnpkg.com/pstree.remy/-/pstree.remy-1.1.8.tgz#c242224f4a67c21f686839bbdb4ac282b8373d3a" + integrity sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w== + +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== + dependencies: + picomatch "^2.2.1" + +reduce-flatten@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/reduce-flatten/-/reduce-flatten-2.0.0.tgz#734fd84e65f375d7ca4465c69798c25c9d10ae27" + integrity sha512-EJ4UNY/U1t2P/2k6oqotuX2Cc3T6nxJwsM0N0asT7dhrtH1ltUxDn4NalSYmPE2rCkVpcf/X6R0wDwcFpzhd4w== + +scrypt-js@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-3.0.1.tgz#d314a57c2aef69d1ad98a138a21fe9eafa9ee312" + integrity sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA== + +semver@^7.5.3: + version "7.5.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" + integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== + dependencies: + lru-cache "^6.0.0" + +simple-update-notifier@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz#d70b92bdab7d6d90dfd73931195a30b6e3d7cebb" + integrity sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w== + dependencies: + semver "^7.5.3" + +string-format@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/string-format/-/string-format-2.0.0.tgz#f2df2e7097440d3b65de31b6d40d54c96eaffb9b" + integrity sha512-bbEs3scLeYNXLecRRuk6uJxdXUSj6le/8rNPHChIJTn2V79aXVTR1EH2OH5zLKKoz0V02fOUKZZcw01pLUShZA== + +supports-color@^5.3.0, supports-color@^5.5.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +table-layout@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/table-layout/-/table-layout-1.0.2.tgz#c4038a1853b0136d63365a734b6931cf4fad4a04" + integrity sha512-qd/R7n5rQTRFi+Zf2sk5XVVd9UQl6ZkduPFC3S7WEGJAmetDTjY3qPN50eSKzwuzEyQKy5TN2TiZdkIjos2L6A== + dependencies: + array-back "^4.0.1" + deep-extend "~0.6.0" + typical "^5.2.0" + wordwrapjs "^4.0.0" + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +touch@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/touch/-/touch-3.1.0.tgz#fe365f5f75ec9ed4e56825e0bb76d24ab74af83b" + integrity sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA== + dependencies: + nopt "~1.0.10" + +ts-command-line-args@^2.2.0: + version "2.5.1" + resolved "https://registry.yarnpkg.com/ts-command-line-args/-/ts-command-line-args-2.5.1.tgz#e64456b580d1d4f6d948824c274cf6fa5f45f7f0" + integrity sha512-H69ZwTw3rFHb5WYpQya40YAX2/w7Ut75uUECbgBIsLmM+BNuYnxsltfyyLMxy6sEeKxgijLTnQtLd0nKd6+IYw== + dependencies: + chalk "^4.1.0" + command-line-args "^5.1.1" + command-line-usage "^6.1.0" + string-format "^2.0.0" + +ts-essentials@^7.0.1: + version "7.0.3" + resolved "https://registry.yarnpkg.com/ts-essentials/-/ts-essentials-7.0.3.tgz#686fd155a02133eedcc5362dc8b5056cde3e5a38" + integrity sha512-8+gr5+lqO3G84KdiTSMRLtuyJ+nTBVRKuCrK4lidMPdVeEp0uqC875uE5NMcaA7YYMN7XsNiFQuMvasF8HT/xQ== + +ts-node@^10.9.1: + version "10.9.1" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.1.tgz#e73de9102958af9e1f0b168a6ff320e25adcff4b" + integrity sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw== + dependencies: + "@cspotcode/source-map-support" "^0.8.0" + "@tsconfig/node10" "^1.0.7" + "@tsconfig/node12" "^1.0.7" + "@tsconfig/node14" "^1.0.0" + "@tsconfig/node16" "^1.0.2" + acorn "^8.4.1" + acorn-walk "^8.1.1" + arg "^4.1.0" + create-require "^1.1.0" + diff "^4.0.1" + make-error "^1.1.1" + v8-compile-cache-lib "^3.0.1" + yn "3.1.1" + +typechain@^8.3.1: + version "8.3.1" + resolved "https://registry.yarnpkg.com/typechain/-/typechain-8.3.1.tgz#dccbc839b94877997536c356380eff7325395cfb" + integrity sha512-fA7clol2IP/56yq6vkMTR+4URF1nGjV82Wx6Rf09EsqD4tkzMAvEaqYxVFCavJm/1xaRga/oD55K+4FtuXwQOQ== + dependencies: + "@types/prettier" "^2.1.1" + debug "^4.3.1" + fs-extra "^7.0.0" + glob "7.1.7" + js-sha3 "^0.8.0" + lodash "^4.17.15" + mkdirp "^1.0.4" + prettier "^2.3.1" + ts-command-line-args "^2.2.0" + ts-essentials "^7.0.1" + +typescript@^5.1.6: + version "5.1.6" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.1.6.tgz#02f8ac202b6dad2c0dd5e0913745b47a37998274" + integrity sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA== + +typical@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/typical/-/typical-4.0.0.tgz#cbeaff3b9d7ae1e2bbfaf5a4e6f11eccfde94fc4" + integrity sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw== + +typical@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/typical/-/typical-5.2.0.tgz#4daaac4f2b5315460804f0acf6cb69c52bb93066" + integrity sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg== + +undefsafe@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/undefsafe/-/undefsafe-2.0.5.tgz#38733b9327bdcd226db889fb723a6efd162e6e2c" + integrity sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA== + +universalify@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" + integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== + +v8-compile-cache-lib@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf" + integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg== + +wordwrapjs@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/wordwrapjs/-/wordwrapjs-4.0.1.tgz#d9790bccfb110a0fc7836b5ebce0937b37a8b98f" + integrity sha512-kKlNACbvHrkpIw6oPeYDSmdCTu2hdMHoyXLTcUKala++lx5Y+wjJ/e474Jqv5abnVmwxw08DiTuHmw69lJGksA== + dependencies: + reduce-flatten "^2.0.0" + typical "^5.2.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== + +ws@7.4.6: + version "7.4.6" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c" + integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + +yn@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" + integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==