diff --git a/evm/.env.example b/evm/.env.example new file mode 100644 index 0000000..3dc5a5a --- /dev/null +++ b/evm/.env.example @@ -0,0 +1,17 @@ +REPORT_GAS="true" + +ENV=testnet # alpha, testnet, mainnet + +PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 # dummy hardhat pk +OWNER=0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 # dummy hardhat owner + +POLYGON_URL=https://polygon.llamarpc.com +FANTOM_URL=https://rpc2.fantom.network +ETH_MAINNET_URL=https://eth.llamarpc.com +GOERLI_URL=https://rpc.ankr.com/eth_goerli +HOLESKY_URL=https://ethereum-holesky.publicnode.com +POLYGON_MUMBAI_URL=https://polygon-mumbai-bor.publicnode.com + +POLYGONSCAN_API_KEY=43A14UI3HB6DHBGGE3JRSZB4J9V3P1S9SE +AVALANCHE_API_KEY=QAE2JD7XIBCYB6Z6GSKNJIHKZ8XGVYM8AI +ETHERSCAN_API_KEY=FF9TZXKT2JWZ68M2EJH1FGCX13IB7ZKPUZ diff --git a/evm/.eslintignore b/evm/.eslintignore new file mode 100644 index 0000000..85f5562 --- /dev/null +++ b/evm/.eslintignore @@ -0,0 +1,4 @@ +node_modules +artifacts +cache +coverage diff --git a/evm/.eslintrc.js b/evm/.eslintrc.js new file mode 100644 index 0000000..e53e40b --- /dev/null +++ b/evm/.eslintrc.js @@ -0,0 +1,28 @@ +module.exports = { + env: { + browser: false, + es2021: true, + mocha: true, + node: true, + }, + plugins: ["@typescript-eslint"], + extends: [ + "standard", + "plugin:prettier/recommended", + "plugin:node/recommended", + "eslint:recommended", + ], + parser: "@typescript-eslint/parser", + parserOptions: { + ecmaVersion: 12, + }, + rules: { + "node/no-unsupported-features/es-syntax": [ + "error", + { ignores: ["modules"] }, + ], + "node/no-missing-import": "off", + "node/no-unpublished-import": "off", + camelcase: "off", + }, +}; diff --git a/evm/.github/workflows/build.yml b/evm/.github/workflows/build.yml new file mode 100644 index 0000000..02d2e50 --- /dev/null +++ b/evm/.github/workflows/build.yml @@ -0,0 +1,30 @@ +name: Build + +on: [push, pull_request] + +jobs: + build: + runs-on: ubuntu-latest + + strategy: + matrix: + node-version: [16.x] + + steps: + - uses: actions/checkout@v4 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v3 + - name: Install yarn + run: npm install -g yarn + - name: Setup test env + run: | + touch .env + echo REPORT_GAS=${{ secrets.REPORT_GAS }} >> .env + echo ENV=${{ secrets.ENV }} >> .env + echo PRIVATE_KEY=${{ secrets.PRIVATE_KEY }} >> .env + echo OWNER=${{ secrets.OWNER }} >> .env + cat .env + - name: Installing dependencies + run: yarn install --frozen-lockfile + - name: Test + run: npm run test diff --git a/evm/.gitignore b/evm/.gitignore new file mode 100644 index 0000000..ed15714 --- /dev/null +++ b/evm/.gitignore @@ -0,0 +1,17 @@ +node_modules +.env +.idea + +coverage +coverage.json +typechain +gas-report.txt +docs + +#Hardhat files +cache +artifacts + +#ignore .DS_Store recursively +.DS_Store +.certora_internal diff --git a/evm/.husky/pre-commit b/evm/.husky/pre-commit new file mode 100755 index 0000000..4fc0172 --- /dev/null +++ b/evm/.husky/pre-commit @@ -0,0 +1,5 @@ +#!/usr/bin/env sh +# . "$(dirname -- "$0")/_/husky.sh" +cd "$(dirname -- "$0")" + +npm run lint && git add . diff --git a/evm/.npmignore b/evm/.npmignore new file mode 100644 index 0000000..8fe58fc --- /dev/null +++ b/evm/.npmignore @@ -0,0 +1,21 @@ +hardhat.config.ts +scripts +test +artifacts +cache +coverage +.env +.env.* +.secret +.sol* +.eslint* +walletUtils.* +coverage.json +arguments.js +src/utils/execution.ts +src/utils/multisend.ts +src/Create2Factory.ts +typings/ +.husky/pre-commit +.prettierignore +.prettierrc \ No newline at end of file diff --git a/evm/.prettierignore b/evm/.prettierignore new file mode 100644 index 0000000..f268596 --- /dev/null +++ b/evm/.prettierignore @@ -0,0 +1,5 @@ +node_modules +artifacts +cache +coverage* +gasReporterOutput.json diff --git a/evm/.prettierrc b/evm/.prettierrc new file mode 100644 index 0000000..2b1e868 --- /dev/null +++ b/evm/.prettierrc @@ -0,0 +1,14 @@ +{ + "overrides": [ + { + "files": "*.sol", + "options": { + "printWidth": 80, + "tabWidth": 4, + "useTabs": false, + "singleQuote": false, + "bracketSpacing": false + } + } + ] +} \ No newline at end of file diff --git a/evm/.solcover.js b/evm/.solcover.js new file mode 100644 index 0000000..727e96d --- /dev/null +++ b/evm/.solcover.js @@ -0,0 +1,6 @@ +module.exports = { + configureYulOptimizer: true, + providerOptions: { + allowUnlimitedContractSize: true, + }, +}; \ No newline at end of file diff --git a/evm/.solhint.json b/evm/.solhint.json new file mode 100644 index 0000000..f3e31e8 --- /dev/null +++ b/evm/.solhint.json @@ -0,0 +1,7 @@ +{ + "extends": "solhint:recommended", + "rules": { + "compiler-version": ["error", "^0.8.0"], + "func-visibility": ["warn", { "ignoreConstructors": true }] + } +} diff --git a/evm/.solhintignore b/evm/.solhintignore new file mode 100644 index 0000000..3c3629e --- /dev/null +++ b/evm/.solhintignore @@ -0,0 +1 @@ +node_modules diff --git a/evm/.vscode/settings.json b/evm/.vscode/settings.json new file mode 100644 index 0000000..cf7b770 --- /dev/null +++ b/evm/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "solidity.compileUsingRemoteVersion": "v0.8.18+commit.87f61d96" +} diff --git a/evm/README.md b/evm/README.md new file mode 100644 index 0000000..f729c10 --- /dev/null +++ b/evm/README.md @@ -0,0 +1,51 @@ +# Router Nitro Periphery Contracts + +Router Nitro Periphery Contracts contains smart contracts for various cross-chain products created using Router Nitro. + +Smart Contracts is designed in such a way that it is: + +- Modular => highly customizable and extendable. +- Optimized => highly gas optimized. + +# How to run the project + +This project demonstrates an advanced Hardhat use case, integrating other tools commonly used alongside Hardhat in the ecosystem. + +## 1. Install + +```shell +> npm install +// or +> yarn install +``` + +## 2. Configure + +Place required fields in a `.env` file in the root folder of the project (requirements are stored in .env.example file). + +### 3. Run + +```shell +npx hardhat test + +// other +npx hardhat accounts +npx hardhat compile +npx hardhat clean +npx hardhat node +npx hardhat help +REPORT_GAS=true npx hardhat test +npx hardhat coverage +npx hardhat run scripts/deploy.ts +TS_NODE_FILES=true npx ts-node scripts/deploy.ts +npx eslint '**/*.{js,ts}' +npx eslint '**/*.{js,ts}' --fix +npx prettier '**/*.{json,sol,md}' --check +npx prettier '**/*.{json,sol,md}' --write +npx solhint 'contracts/**/*.sol' +npx solhint 'contracts/**/*.sol' --fix +``` + +# Performance optimizations + +For faster runs of your tests and scripts, consider skipping ts-node's type checking by setting the environment variable `TS_NODE_TRANSPILE_ONLY` to `1` in hardhat's environment. For more details see [the documentation](https://hardhat.org/guides/typescript.html#performance-optimizations). diff --git a/evm/contracts/BatchTransaction.sol b/evm/contracts/BatchTransaction.sol new file mode 100644 index 0000000..f55bc78 --- /dev/null +++ b/evm/contracts/BatchTransaction.sol @@ -0,0 +1,326 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.18; + +import {ReentrancyGuard} from "./utils/ReentrancyGuard.sol"; +import {Basic} from "router-intents/contracts/BaseAdapter.sol"; +import {NitroMessageHandler} from "router-intents/contracts/utils/NitroMessageHandler.sol"; +import {CallLib} from "./CallLib.sol"; +import {IERC20, SafeERC20} from "./utils/SafeERC20.sol"; +import {Errors} from "./Errors.sol"; + +/** + * @title BatchTransaction + * @author Shivam Agrawal + * @notice Batch Transaction Contract for EOAs. + */ +contract BatchTransaction is Basic, NitroMessageHandler, ReentrancyGuard { + using SafeERC20 for IERC20; + + address private immutable _native; + address private immutable _wnative; + + struct RefundData { + address[] tokens; + } + + // user -> token array + mapping(address => RefundData) private tokensToRefund; + + event OperationFailedRefundEvent( + address token, + address recipient, + uint256 amount + ); + event OperationSuccessful(); + + constructor( + address __native, + address __wnative, + address __assetForwarder, + address __dexspan + ) NitroMessageHandler(__assetForwarder, __dexspan) { + _native = __native; + _wnative = __wnative; + } + + /** + * @notice function to return the address of WNative token. + */ + function wnative() public view virtual override returns (address) { + return _wnative; + } + + /** + * @notice function to return the address of Native token. + */ + function native() public view virtual override returns (address) { + return _native; + } + + /** + * @dev function to execute batch calls on the same chain + * @param tokens Addresses of the tokens to fetch from the user + * @param amounts amounts of the tokens to fetch from the user + * @param target Addresses of the contracts to call + * @param value Amounts of native tokens to send along with the transactions + * @param callType Type of call. 1: call, 2: delegatecall + * @param data Data of the transactions + */ + function executeBatchCallsSameChain( + address[] calldata tokens, + uint256[] calldata amounts, + address[] calldata target, + uint256[] calldata value, + uint256[] calldata callType, + bytes[] calldata data + ) external payable { + uint256 tokensLength = tokens.length; + require(tokensLength == amounts.length, Errors.ARRAY_LENGTH_MISMATCH); + uint256 totalValue = 0; + + for (uint256 i = 0; i < tokensLength; ) { + totalValue += _pullTokens(tokens[i], amounts[i]); + tokensToRefund[msg.sender].tokens.push(tokens[i]); + + unchecked { + ++i; + } + } + + require( + msg.value >= totalValue, + Errors.INSUFFICIENT_NATIVE_FUNDS_PASSED + ); + + for (uint256 i = 0; i < callType.length; ) { + // callType can be either 1 or 2 + require(callType[i] < 3, Errors.INVALID_CALL_TYPE); + unchecked { + ++i; + } + } + + _executeBatchCalls(msg.sender, target, value, callType, data); + } + + /** + * @dev function to execute batch calls + * @param refundRecipient Address of recipient of refunds of dust at the end + * @param target Addresses of the contracts to call + * @param value Amounts of native tokens to send along with the transactions + * @param data Data of the transactions + * @param callType Type of call. 1: call, 2: delegatecall + */ + function executeBatchCallsDestChain( + address refundRecipient, + address[] calldata target, + uint256[] calldata value, + uint256[] calldata callType, + bytes[] calldata data + ) external payable { + require(msg.sender == address(this), Errors.ONLY_SELF); + + _executeBatchCalls(refundRecipient, target, value, callType, data); + } + + /** + * @dev function to execute batch calls + * @param target Addresses of the contracts to call + * @param value Amounts of native tokens to send along with the transactions + * @param data Data of the transactions + * @param callType Type of call. 1: call, 2: delegatecall + */ + function _executeBatchCalls( + address refundRecipient, + address[] calldata target, + uint256[] calldata value, + uint256[] calldata callType, + bytes[] calldata data + ) internal { + uint256 targetLength = target.length; + + require( + targetLength != 0 && + targetLength == value.length && + value.length == data.length && + data.length == callType.length, + Errors.WRONG_BATCH_PROVIDED + ); + + if (target.length == 1) { + _execute( + refundRecipient, + target[0], + address(0), + address(0), + value[0], + callType[0], + data[0] + ); + } else { + _execute( + refundRecipient, + target[0], + address(0), + target[1], + value[0], + callType[0], + data[0] + ); + + for (uint256 i = 1; i < targetLength; ) { + if (i != targetLength - 1) { + _execute( + refundRecipient, + target[i], + target[i - 1], + target[i + 1], + value[i], + callType[i], + data[i] + ); + } else { + _execute( + refundRecipient, + target[i], + target[i - 1], + address(0), + value[i], + callType[i], + data[i] + ); + } + + unchecked { + ++i; + } + } + } + + processRefunds(refundRecipient); + } + + function _pullTokens( + address token, + uint256 amount + ) internal returns (uint256) { + uint256 totalValue = 0; + if (token == native()) { + totalValue += amount; + } else { + IERC20(token).safeTransferFrom(msg.sender, address(this), amount); + } + + return totalValue; + } + + function _execute( + address refundRecipient, + address target, + address precedingAdapter, + address succeedingAdapter, + uint256 value, + uint256 callType, + bytes memory data + ) internal { + // 0x64ba4bc1 => execute(address precedingAdapter, address succeedingAdapter, bytes data) + bytes memory _calldata = abi.encodeWithSelector( + 0xf5542f2d, + precedingAdapter, + succeedingAdapter, + data + ); + + bytes memory result; + if (callType == 1) result = CallLib._call(target, value, _calldata); + else if (callType == 2) + result = CallLib._delegateCall(target, _calldata); + + if (result.length != 0) processResult(refundRecipient, result); + } + + function processResult(address user, bytes memory data) internal { + address[] memory tokens = abi.decode(data, (address[])); + + for (uint256 i = 0; i < tokens.length; ) { + tokensToRefund[user].tokens.push(tokens[i]); + + unchecked { + ++i; + } + } + } + + function processRefunds(address user) internal { + address[] memory tokens = tokensToRefund[user].tokens; + delete tokensToRefund[user].tokens; + + uint256 len = tokens.length; + + for (uint256 i = 0; i < len; ) { + withdrawTokens(tokens[i], user, type(uint256).max); + + unchecked { + ++i; + } + } + } + + /** + * @inheritdoc NitroMessageHandler + */ + function handleMessage( + address tokenSent, + uint256 amount, + bytes memory instruction + ) external override onlyNitro nonReentrant { + ( + address refundAddress, + address[] memory target, + uint256[] memory value, + uint256[] memory callType, + bytes[] memory data + ) = abi.decode( + instruction, + (address, address[], uint256[], uint256[], bytes[]) + ); + + for (uint256 i = 0; i < callType.length; ) { + if (callType[i] > 2) { + withdrawTokens(tokenSent, refundAddress, amount); + emit OperationFailedRefundEvent( + tokenSent, + refundAddress, + amount + ); + + return; + } + unchecked { + ++i; + } + } + + // solhint-disable-next-line avoid-low-level-calls + (bool success, ) = address(this).call( + abi.encodeWithSelector( + this.executeBatchCallsDestChain.selector, + refundAddress, + target, + value, + callType, + data + ) + ); + + if (success) { + emit OperationSuccessful(); + } else { + withdrawTokens(tokenSent, refundAddress, amount); + emit OperationFailedRefundEvent(tokenSent, refundAddress, amount); + } + } + + // solhint-disable-next-line no-empty-blocks + receive() external payable {} +} diff --git a/evm/contracts/CallLib.sol b/evm/contracts/CallLib.sol new file mode 100644 index 0000000..1a2f700 --- /dev/null +++ b/evm/contracts/CallLib.sol @@ -0,0 +1,94 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.18; + +library CallLib { + /** + * @dev internal method that fecilitates the extenral calls from SmartAccount + * @dev similar to execute() of Executor.sol + * @param target destination address contract/non-contract + * @param value amount of native tokens + * @param data function singature of destination + */ + function _call( + address target, + uint256 value, + bytes memory data + ) internal returns (bytes memory result) { + // solhint-disable-next-line no-inline-assembly + assembly { + let success := call( + gas(), + target, + value, + add(data, 0x20), + mload(data), + 0, + 0 + ) + + // Get the size of the returned data + let size := returndatasize() + + // Allocate memory for the return data + result := mload(0x40) + + // Set the length of the return data + mstore(result, size) + + // Copy the return data to the allocated memory + returndatacopy(add(result, 0x20), 0, size) + + // Update the free memory pointer + mstore(0x40, add(result, add(0x20, size))) + + if iszero(success) { + revert(result, returndatasize()) + } + } + } + + /** + * @dev internal method that fecilitates the extenral calls from SmartAccount + * @dev similar to execute() of Executor.sol + * @param target destination address contract/non-contract + * @param data function singature of destination + */ + function _delegateCall( + address target, + bytes memory data + ) internal returns (bytes memory result) { + require(target != address(this), "delegatecall to self"); + + // solhint-disable-next-line no-inline-assembly + assembly { + // Perform delegatecall to the target contract + let success := delegatecall( + gas(), + target, + add(data, 0x20), + mload(data), + 0, + 0 + ) + + // Get the size of the returned data + let size := returndatasize() + + // Allocate memory for the return data + result := mload(0x40) + + // Set the length of the return data + mstore(result, size) + + // Copy the return data to the allocated memory + returndatacopy(add(result, 0x20), 0, size) + + // Update the free memory pointer + mstore(0x40, add(result, add(0x20, size))) + + if iszero(success) { + revert(result, returndatasize()) + } + } + } +} diff --git a/evm/contracts/Errors.sol b/evm/contracts/Errors.sol new file mode 100644 index 0000000..d96b98c --- /dev/null +++ b/evm/contracts/Errors.sol @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.18; + +/** + * @title Errors library + * @author Router Intents Error + * @notice Defines the error messages emitted by the contracts on Router Intents + */ +library Errors { + string public constant ARRAY_LENGTH_MISMATCH = "1"; // 'Array lengths mismatch' + string public constant INSUFFICIENT_NATIVE_FUNDS_PASSED = "2"; // 'Insufficient native tokens passed' + string public constant WRONG_BATCH_PROVIDED = "3"; // 'The targetLength, valueLength, callTypeLength, funcLength do not match in executeBatch transaction functions in batch transaction contract' + string public constant INVALID_CALL_TYPE = "4"; // 'The callType value can only be 1 (call)' and 2(delegatecall)' + string public constant ONLY_NITRO = "5"; // 'Only nitro can call this function' + string public constant ONLY_SELF = "6"; // 'Only the current contract can call this function' +} diff --git a/evm/contracts/intent-adapters/erc20/ERC20Approval.sol b/evm/contracts/intent-adapters/erc20/ERC20Approval.sol new file mode 100644 index 0000000..fc25f9a --- /dev/null +++ b/evm/contracts/intent-adapters/erc20/ERC20Approval.sol @@ -0,0 +1,125 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.18; + +import {RouterIntentEoaAdapter, EoaExecutor} from "router-intents/contracts/RouterIntentEoaAdapter.sol"; +import {NitroMessageHandler} from "router-intents/contracts/utils/NitroMessageHandler.sol"; +import {Errors} from "router-intents/contracts/utils/Errors.sol"; +import {DefaultRefundable} from "router-intents/contracts/utils/DefaultRefundable.sol"; +import {IERC20, SafeERC20} from "../../utils/SafeERC20.sol"; + +/** + * @title ERC20Approval + * @author Shivam Agrawal + * @notice Providing approval for ERC20 tokens. + */ +contract ERC20Approval is + RouterIntentEoaAdapter, + NitroMessageHandler, + DefaultRefundable +{ + using SafeERC20 for IERC20; + + constructor( + address __native, + address __wnative, + address __owner, + address __assetForwarder, + address __dexspan, + address __defaultRefundAddress + ) + RouterIntentEoaAdapter(__native, __wnative, __owner) + NitroMessageHandler(__assetForwarder, __dexspan) + DefaultRefundable(__defaultRefundAddress) + // solhint-disable-next-line no-empty-blocks + { + + } + + function name() public pure override returns (string memory) { + return "ERC20Approval"; + } + + /** + * @inheritdoc EoaExecutor + */ + function execute( + address, + address, + bytes calldata data + ) external payable override returns (address[] memory tokens) { + ( + address[] memory _tokens, + uint256[] memory _amounts, + address[] memory _recipients + ) = parseInputs(data); + + require( + _tokens.length != 0 && + _tokens.length != _amounts.length && + _amounts.length != _recipients.length, + Errors.ARRAY_LENGTH_MISMATCH + ); + + for (uint256 i = 0; i < tokens.length; ) { + IERC20(tokens[i]).safeIncreaseAllowance( + _recipients[i], + _amounts[i] + ); + + unchecked { + ++i; + } + } + + bytes memory logData = abi.encode(_tokens, _amounts, _recipients); + + emit ExecutionEvent(name(), logData); + return _tokens; + } + + function _pullTokens( + address token, + uint256 amount + ) internal returns (uint256) { + uint256 totalValue = 0; + if (token == native()) { + totalValue += amount; + } else { + IERC20(token).safeTransferFrom(msg.sender, address(this), amount); + } + + return totalValue; + } + + /** + * @inheritdoc NitroMessageHandler + */ + function handleMessage( + address tokenSent, + uint256 amount, + bytes memory + ) external override onlyNitro nonReentrant { + withdrawTokens(tokenSent, defaultRefundAddress(), amount); + emit UnsupportedOperation(tokenSent, defaultRefundAddress(), amount); + } + + /** + * @dev function to parse input data. + * @param data input data. + */ + function parseInputs( + bytes memory data + ) + public + pure + returns (address[] memory, uint256[] memory, address[] memory) + { + ( + address[] memory _tokens, + uint256[] memory _amounts, + address[] memory _recipients + ) = abi.decode(data, (address[], uint256[], address[])); + + return (_tokens, _amounts, _recipients); + } +} diff --git a/evm/contracts/intent-adapters/erc20/ERC20Transfer.sol b/evm/contracts/intent-adapters/erc20/ERC20Transfer.sol new file mode 100644 index 0000000..285e63b --- /dev/null +++ b/evm/contracts/intent-adapters/erc20/ERC20Transfer.sol @@ -0,0 +1,138 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.18; + +import {RouterIntentEoaAdapter, EoaExecutor} from "router-intents/contracts/RouterIntentEoaAdapter.sol"; +import {NitroMessageHandler} from "router-intents/contracts/utils/NitroMessageHandler.sol"; +import {Errors} from "router-intents/contracts/utils/Errors.sol"; +import {DefaultRefundable} from "router-intents/contracts/utils/DefaultRefundable.sol"; +import {IERC20, SafeERC20} from "../../utils/SafeERC20.sol"; + +/** + * @title ERC20Transfer + * @author Shivam Agrawal + * @notice Transferring ERC20 tokens. + */ +contract ERC20Transfer is + RouterIntentEoaAdapter, + NitroMessageHandler, + DefaultRefundable +{ + using SafeERC20 for IERC20; + + constructor( + address __native, + address __wnative, + address __owner, + address __assetForwarder, + address __dexspan, + address __defaultRefundAddress + ) + RouterIntentEoaAdapter(__native, __wnative, __owner) + NitroMessageHandler(__assetForwarder, __dexspan) + DefaultRefundable(__defaultRefundAddress) + // solhint-disable-next-line no-empty-blocks + { + + } + + function name() public pure override returns (string memory) { + return "ERC20Transfer"; + } + + /** + * @inheritdoc EoaExecutor + */ + function execute( + address, + address, + bytes calldata data + ) external payable override returns (address[] memory tokens) { + ( + address[] memory _tokens, + uint256[] memory _amounts, + address[] memory _recipients + ) = parseInputs(data); + + require( + _tokens.length != 0 && + _tokens.length != _amounts.length && + _amounts.length != _recipients.length, + Errors.ARRAY_LENGTH_MISMATCH + ); + + // If the adapter is called using `call` and not `delegatecall` + if (address(this) == self()) { + uint256 totalValue; + for (uint256 i = 0; i < tokens.length; ) { + totalValue += _pullTokens(_tokens[i], _amounts[i]); + unchecked { + ++i; + } + } + + require( + msg.value == totalValue, + Errors.INSUFFICIENT_NATIVE_FUNDS_PASSED + ); + } + + for (uint256 i = 0; i < tokens.length; ) { + withdrawTokens(_tokens[i], _recipients[i], _amounts[i]); + + unchecked { + ++i; + } + } + + bytes memory logData = abi.encode(_tokens, _amounts, _recipients); + + emit ExecutionEvent(name(), logData); + return _tokens; + } + + function _pullTokens( + address token, + uint256 amount + ) internal returns (uint256) { + uint256 totalValue = 0; + if (token == native()) { + totalValue += amount; + } else { + IERC20(token).safeTransferFrom(msg.sender, address(this), amount); + } + + return totalValue; + } + + /** + * @inheritdoc NitroMessageHandler + */ + function handleMessage( + address tokenSent, + uint256 amount, + bytes memory + ) external override onlyNitro nonReentrant { + withdrawTokens(tokenSent, defaultRefundAddress(), amount); + emit UnsupportedOperation(tokenSent, defaultRefundAddress(), amount); + } + + /** + * @dev function to parse input data. + * @param data input data. + */ + function parseInputs( + bytes memory data + ) + public + pure + returns (address[] memory, uint256[] memory, address[] memory) + { + ( + address[] memory _tokens, + uint256[] memory _amounts, + address[] memory _recipients + ) = abi.decode(data, (address[], uint256[], address[])); + + return (_tokens, _amounts, _recipients); + } +} diff --git a/evm/contracts/intent-adapters/lending-borrowing/AaveV3/AaveV3Borrow.sol b/evm/contracts/intent-adapters/lending-borrowing/AaveV3/AaveV3Borrow.sol new file mode 100644 index 0000000..d542f91 --- /dev/null +++ b/evm/contracts/intent-adapters/lending-borrowing/AaveV3/AaveV3Borrow.sol @@ -0,0 +1,138 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.18; + +import {AaveV3Helpers} from "./AaveV3Helpers.sol"; +import {RouterIntentEoaAdapter, EoaExecutor} from "router-intents/contracts/RouterIntentEoaAdapter.sol"; +import {NitroMessageHandler} from "router-intents/contracts/utils/NitroMessageHandler.sol"; +import {Errors} from "router-intents/contracts/utils/Errors.sol"; +import {DefaultRefundable} from "router-intents/contracts/utils/DefaultRefundable.sol"; +import {IERC20, SafeERC20} from "../../../utils/SafeERC20.sol"; + +/** + * @title AaveV3Borrow + * @author Shivam Agrawal + * @notice Borrowing funds on AaveV3. + */ +contract AaveV3Borrow is + RouterIntentEoaAdapter, + NitroMessageHandler, + DefaultRefundable, + AaveV3Helpers +{ + using SafeERC20 for IERC20; + + constructor( + address __native, + address __wnative, + address __owner, + address __assetForwarder, + address __dexspan, + address __defaultRefundAddress, + address __aaveV3Pool, + address __aaveV3WrappedTokenGateway, + uint16 __aaveV3ReferralCode + ) + RouterIntentEoaAdapter(__native, __wnative, __owner) + NitroMessageHandler(__assetForwarder, __dexspan) + DefaultRefundable(__defaultRefundAddress) + AaveV3Helpers( + __aaveV3Pool, + __aaveV3WrappedTokenGateway, + __aaveV3ReferralCode + ) + // solhint-disable-next-line no-empty-blocks + { + + } + + function name() public pure override returns (string memory) { + return "AaveV3Borrow"; + } + + /** + * @inheritdoc EoaExecutor + */ + function execute( + address, + address, + bytes calldata data + ) external payable override returns (address[] memory tokens) { + ( + uint256 amount, + uint256 rateMode, + address asset, + address onBehalfOf, + address recipient + ) = parseInputs(data); + + bytes memory logData; + + (tokens, logData) = _aaveV3Borrow( + amount, + rateMode, + asset, + onBehalfOf, + recipient + ); + + emit ExecutionEvent(name(), logData); + return tokens; + } + + //////////////////////////// ACTION LOGIC //////////////////////////// + + /** + * @notice function to borrow funds from AaveV3. + * @param amount Amount of asset to be borrowed. + * @param rateMode Rate mode for borrowing. 1 for Stable Rate and 2 for Variable Rate + * @param asset Asset to be borrowed. + * @param onBehalfOf The user who will incur the borrow. + */ + function _aaveV3Borrow( + uint256 amount, + uint256 rateMode, + address asset, + address onBehalfOf, + address recipient + ) private returns (address[] memory tokens, bytes memory logData) { + aaveV3Pool().borrow( + asset, + amount, + rateMode, + aaveV3ReferralCode(), + onBehalfOf + ); + + withdrawTokens(asset, recipient, amount); + + tokens = new address[](1); + tokens[0] = asset; + + logData = abi.encode(amount, rateMode, asset, onBehalfOf); + } + + /** + * @inheritdoc NitroMessageHandler + */ + function handleMessage( + address tokenSent, + uint256 amount, + bytes memory + ) external override onlyNitro nonReentrant { + withdrawTokens(tokenSent, defaultRefundAddress(), amount); + emit UnsupportedOperation(tokenSent, defaultRefundAddress(), amount); + } + + /** + * @dev function to parse input data. + * @param data input data. + */ + function parseInputs( + bytes memory data + ) public pure returns (uint256, uint256, address, address, address) { + return abi.decode(data, (uint256, uint256, address, address, address)); + } + + // solhint-disable-next-line no-empty-blocks + receive() external payable {} +} diff --git a/evm/contracts/intent-adapters/lending-borrowing/AaveV3/AaveV3Helpers.sol b/evm/contracts/intent-adapters/lending-borrowing/AaveV3/AaveV3Helpers.sol new file mode 100644 index 0000000..236c8a5 --- /dev/null +++ b/evm/contracts/intent-adapters/lending-borrowing/AaveV3/AaveV3Helpers.sol @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.18; + +import {IPoolV3} from "./interfaces/IPoolV3.sol"; +import {IWrappedTokenGateway} from "./interfaces/IWrappedTokenGateway.sol"; + +contract AaveV3Helpers { + IPoolV3 private immutable _aaveV3Pool; + IWrappedTokenGateway private immutable _aaveV3WrappedTokenGateway; + uint16 private immutable _aaveV3ReferralCode; + + constructor( + address __aaveV3Pool, + address __aaveV3WrappedTokenGateway, + uint16 __aaveV3ReferralCode + ) { + _aaveV3Pool = IPoolV3(__aaveV3Pool); + _aaveV3WrappedTokenGateway = IWrappedTokenGateway( + __aaveV3WrappedTokenGateway + ); + _aaveV3ReferralCode = __aaveV3ReferralCode; + } + + function aaveV3Pool() public view returns (IPoolV3) { + return _aaveV3Pool; + } + + function aaveV3WrappedTokenGateway() + public + view + returns (IWrappedTokenGateway) + { + return _aaveV3WrappedTokenGateway; + } + + function aaveV3ReferralCode() public view returns (uint16) { + return _aaveV3ReferralCode; + } +} diff --git a/evm/contracts/intent-adapters/lending-borrowing/AaveV3/AaveV3Supply.sol b/evm/contracts/intent-adapters/lending-borrowing/AaveV3/AaveV3Supply.sol new file mode 100644 index 0000000..5570251 --- /dev/null +++ b/evm/contracts/intent-adapters/lending-borrowing/AaveV3/AaveV3Supply.sol @@ -0,0 +1,163 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.18; + +import {AaveV3Helpers} from "./AaveV3Helpers.sol"; +import {RouterIntentEoaAdapter, EoaExecutor} from "router-intents/contracts/RouterIntentEoaAdapter.sol"; +import {NitroMessageHandler} from "router-intents/contracts/utils/NitroMessageHandler.sol"; +import {Errors} from "router-intents/contracts/utils/Errors.sol"; +import {IERC20, SafeERC20} from "../../../utils/SafeERC20.sol"; + +/** + * @title AaveV3Supply + * @author Shivam Agrawal + * @notice Supplying funds on AaveV3. + */ +contract AaveV3Supply is + RouterIntentEoaAdapter, + NitroMessageHandler, + AaveV3Helpers +{ + using SafeERC20 for IERC20; + + event AaveV3SupplyDest(address _token, address _recipient, uint256 _amount); + + constructor( + address __native, + address __wnative, + address __owner, + address __assetForwarder, + address __dexspan, + address __aaveV3Pool, + address __aaveV3WrappedTokenGateway, + uint16 __aaveV3ReferralCode + ) + RouterIntentEoaAdapter(__native, __wnative, __owner) + NitroMessageHandler(__assetForwarder, __dexspan) + AaveV3Helpers( + __aaveV3Pool, + __aaveV3WrappedTokenGateway, + __aaveV3ReferralCode + ) + // solhint-disable-next-line no-empty-blocks + { + + } + + function name() public pure override returns (string memory) { + return "AaveV3Supply"; + } + + /** + * @inheritdoc EoaExecutor + */ + function execute( + address, + address, + bytes calldata data + ) external payable override returns (address[] memory tokens) { + (address _asset, address _recipient, uint256 _amount) = parseInputs( + data + ); + + // If the adapter is called using `call` and not `delegatecall` + if (address(this) == self()) { + if (_asset == native()) + require( + msg.value == _amount, + Errors.INSUFFICIENT_NATIVE_FUNDS_PASSED + ); + else IERC20(_asset).safeTransferFrom(msg.sender, self(), _amount); + } + + bytes memory logData; + + (tokens, logData) = _aaveV3Supply(_asset, _recipient, _amount); + + emit ExecutionEvent(name(), logData); + return tokens; + } + + /** + * @inheritdoc NitroMessageHandler + */ + function handleMessage( + address tokenSent, + uint256 amount, + bytes memory instruction + ) external override onlyNitro nonReentrant { + address recipient = abi.decode(instruction, (address)); + + approveToken(tokenSent, address(aaveV3Pool()), amount); + + if (tokenSent == native()) + try + aaveV3WrappedTokenGateway().depositETH{value: amount}( + address(0), + recipient, + aaveV3ReferralCode() + ) + { + emit AaveV3SupplyDest(native(), recipient, amount); + } catch { + withdrawTokens(native(), recipient, amount); + emit OperationFailedRefundEvent(native(), recipient, amount); + } + else + try + aaveV3Pool().supply( + tokenSent, + amount, + recipient, + aaveV3ReferralCode() + ) + { + emit AaveV3SupplyDest(tokenSent, recipient, amount); + } catch { + withdrawTokens(tokenSent, recipient, amount); + emit OperationFailedRefundEvent(tokenSent, recipient, amount); + } + } + + //////////////////////////// ACTION LOGIC //////////////////////////// + + /** + * @notice function to supply funds to AaveV3. + * @param amount Amount of supply asset to be supplied. + * @param recipient Recipient of aTokens after funds have been supplied. + * @param asset Asset to be supplied. + */ + function _aaveV3Supply( + address asset, + address recipient, + uint256 amount + ) private returns (address[] memory tokens, bytes memory logData) { + approveToken(asset, address(aaveV3Pool()), amount); + + if (asset == native()) + aaveV3WrappedTokenGateway().depositETH{value: amount}( + address(0), + recipient, + aaveV3ReferralCode() + ); + else + aaveV3Pool().supply(asset, amount, recipient, aaveV3ReferralCode()); + + tokens = new address[](1); + tokens[0] = asset; + + logData = abi.encode(asset, recipient, recipient); + } + + /** + * @dev function to parse input data. + * @param data input data. + */ + function parseInputs( + bytes memory data + ) public pure returns (address, address, uint256) { + return abi.decode(data, (address, address, uint256)); + } + + // solhint-disable-next-line no-empty-blocks + receive() external payable {} +} diff --git a/evm/contracts/intent-adapters/lending-borrowing/AaveV3/interfaces/DataTypes.sol b/evm/contracts/intent-adapters/lending-borrowing/AaveV3/interfaces/DataTypes.sol new file mode 100644 index 0000000..1341f72 --- /dev/null +++ b/evm/contracts/intent-adapters/lending-borrowing/AaveV3/interfaces/DataTypes.sol @@ -0,0 +1,268 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.18; + +library DataTypes { + struct ReserveData { + //stores the reserve configuration + ReserveConfigurationMap configuration; + //the liquidity index. Expressed in ray + uint128 liquidityIndex; + //the current supply rate. Expressed in ray + uint128 currentLiquidityRate; + //variable borrow index. Expressed in ray + uint128 variableBorrowIndex; + //the current variable borrow rate. Expressed in ray + uint128 currentVariableBorrowRate; + //the current stable borrow rate. Expressed in ray + uint128 currentStableBorrowRate; + //timestamp of last update + uint40 lastUpdateTimestamp; + //the id of the reserve. Represents the position in the list of the active reserves + uint16 id; + //aToken address + address aTokenAddress; + //stableDebtToken address + address stableDebtTokenAddress; + //variableDebtToken address + address variableDebtTokenAddress; + //address of the interest rate strategy + address interestRateStrategyAddress; + //the current treasury balance, scaled + uint128 accruedToTreasury; + //the outstanding unbacked aTokens minted through the bridging feature + uint128 unbacked; + //the outstanding debt borrowed against this asset in isolation mode + uint128 isolationModeTotalDebt; + } + + struct ReserveConfigurationMap { + //bit 0-15: LTV + //bit 16-31: Liq. threshold + //bit 32-47: Liq. bonus + //bit 48-55: Decimals + //bit 56: reserve is active + //bit 57: reserve is frozen + //bit 58: borrowing is enabled + //bit 59: stable rate borrowing enabled + //bit 60: asset is paused + //bit 61: borrowing in isolation mode is enabled + //bit 62-63: reserved + //bit 64-79: reserve factor + //bit 80-115 borrow cap in whole tokens, borrowCap == 0 => no cap + //bit 116-151 supply cap in whole tokens, supplyCap == 0 => no cap + //bit 152-167 liquidation protocol fee + //bit 168-175 eMode category + //bit 176-211 unbacked mint cap in whole tokens, unbackedMintCap == 0 => minting disabled + //bit 212-251 debt ceiling for isolation mode with (ReserveConfiguration::DEBT_CEILING_DECIMALS) decimals + //bit 252-255 unused + + uint256 data; + } + + struct UserConfigurationMap { + /** + * @dev Bitmap of the users collaterals and borrows. It is divided in pairs of bits, one pair per asset. + * The first bit indicates if an asset is used as collateral by the user, the second whether an + * asset is borrowed by the user. + */ + uint256 data; + } + + struct EModeCategory { + // each eMode category has a custom ltv and liquidation threshold + uint16 ltv; + uint16 liquidationThreshold; + uint16 liquidationBonus; + // each eMode category may or may not have a custom oracle to override the individual assets price oracles + address priceSource; + string label; + } + + enum InterestRateMode { + NONE, + STABLE, + VARIABLE + } + + struct ReserveCache { + uint256 currScaledVariableDebt; + uint256 nextScaledVariableDebt; + uint256 currPrincipalStableDebt; + uint256 currAvgStableBorrowRate; + uint256 currTotalStableDebt; + uint256 nextAvgStableBorrowRate; + uint256 nextTotalStableDebt; + uint256 currLiquidityIndex; + uint256 nextLiquidityIndex; + uint256 currVariableBorrowIndex; + uint256 nextVariableBorrowIndex; + uint256 currLiquidityRate; + uint256 currVariableBorrowRate; + uint256 reserveFactor; + ReserveConfigurationMap reserveConfiguration; + address aTokenAddress; + address stableDebtTokenAddress; + address variableDebtTokenAddress; + uint40 reserveLastUpdateTimestamp; + uint40 stableDebtLastUpdateTimestamp; + } + + struct ExecuteLiquidationCallParams { + uint256 reservesCount; + uint256 debtToCover; + address collateralAsset; + address debtAsset; + address user; + bool receiveAToken; + address priceOracle; + uint8 userEModeCategory; + address priceOracleSentinel; + } + + struct ExecuteSupplyParams { + address asset; + uint256 amount; + address onBehalfOf; + uint16 referralCode; + } + + struct ExecuteBorrowParams { + address asset; + address user; + address onBehalfOf; + uint256 amount; + InterestRateMode interestRateMode; + uint16 referralCode; + bool releaseUnderlying; + uint256 maxStableRateBorrowSizePercent; + uint256 reservesCount; + address oracle; + uint8 userEModeCategory; + address priceOracleSentinel; + } + + struct ExecuteRepayParams { + address asset; + uint256 amount; + InterestRateMode interestRateMode; + address onBehalfOf; + bool useATokens; + } + + struct ExecuteWithdrawParams { + address asset; + uint256 amount; + address to; + uint256 reservesCount; + address oracle; + uint8 userEModeCategory; + } + + struct ExecuteSetUserEModeParams { + uint256 reservesCount; + address oracle; + uint8 categoryId; + } + + struct FinalizeTransferParams { + address asset; + address from; + address to; + uint256 amount; + uint256 balanceFromBefore; + uint256 balanceToBefore; + uint256 reservesCount; + address oracle; + uint8 fromEModeCategory; + } + + struct FlashloanParams { + address receiverAddress; + address[] assets; + uint256[] amounts; + uint256[] interestRateModes; + address onBehalfOf; + bytes params; + uint16 referralCode; + uint256 flashLoanPremiumToProtocol; + uint256 flashLoanPremiumTotal; + uint256 maxStableRateBorrowSizePercent; + uint256 reservesCount; + address addressesProvider; + uint8 userEModeCategory; + bool isAuthorizedFlashBorrower; + } + + struct FlashloanSimpleParams { + address receiverAddress; + address asset; + uint256 amount; + bytes params; + uint16 referralCode; + uint256 flashLoanPremiumToProtocol; + uint256 flashLoanPremiumTotal; + } + + struct FlashLoanRepaymentParams { + uint256 amount; + uint256 totalPremium; + uint256 flashLoanPremiumToProtocol; + address asset; + address receiverAddress; + uint16 referralCode; + } + + struct CalculateUserAccountDataParams { + UserConfigurationMap userConfig; + uint256 reservesCount; + address user; + address oracle; + uint8 userEModeCategory; + } + + struct ValidateBorrowParams { + ReserveCache reserveCache; + UserConfigurationMap userConfig; + address asset; + address userAddress; + uint256 amount; + InterestRateMode interestRateMode; + uint256 maxStableLoanPercent; + uint256 reservesCount; + address oracle; + uint8 userEModeCategory; + address priceOracleSentinel; + bool isolationModeActive; + address isolationModeCollateralAddress; + uint256 isolationModeDebtCeiling; + } + + struct ValidateLiquidationCallParams { + ReserveCache debtReserveCache; + uint256 totalDebt; + uint256 healthFactor; + address priceOracleSentinel; + } + + struct CalculateInterestRatesParams { + uint256 unbacked; + uint256 liquidityAdded; + uint256 liquidityTaken; + uint256 totalStableDebt; + uint256 totalVariableDebt; + uint256 averageStableBorrowRate; + uint256 reserveFactor; + address reserve; + address aToken; + } + + struct InitReserveParams { + address asset; + address aTokenAddress; + address stableDebtAddress; + address variableDebtAddress; + address interestRateStrategyAddress; + uint16 reservesCount; + uint16 maxNumberReserves; + } +} diff --git a/evm/contracts/intent-adapters/lending-borrowing/AaveV3/interfaces/IPoolDataProvider.sol b/evm/contracts/intent-adapters/lending-borrowing/AaveV3/interfaces/IPoolDataProvider.sol new file mode 100644 index 0000000..90b533c --- /dev/null +++ b/evm/contracts/intent-adapters/lending-borrowing/AaveV3/interfaces/IPoolDataProvider.sol @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: AGPL-3.0 +pragma solidity 0.8.18; + +interface IPoolDataProvider { + /** + * @notice Returns the user data in a reserve + * @param asset The address of the underlying asset of the reserve + * @param user The address of the user + * @return currentATokenBalance The current AToken balance of the user + * @return currentStableDebt The current stable debt of the user + * @return currentVariableDebt The current variable debt of the user + * @return principalStableDebt The principal stable debt of the user + * @return scaledVariableDebt The scaled variable debt of the user + * @return stableBorrowRate The stable borrow rate of the user + * @return liquidityRate The liquidity rate of the reserve + * @return stableRateLastUpdated The timestamp of the last update of the user stable rate + * @return usageAsCollateralEnabled True if the user is using the asset as collateral, false + * otherwise + **/ + function getUserReserveData( + address asset, + address user + ) + external + view + returns ( + uint256 currentATokenBalance, + uint256 currentStableDebt, + uint256 currentVariableDebt, + uint256 principalStableDebt, + uint256 scaledVariableDebt, + uint256 stableBorrowRate, + uint256 liquidityRate, + uint40 stableRateLastUpdated, + bool usageAsCollateralEnabled + ); +} diff --git a/evm/contracts/intent-adapters/lending-borrowing/AaveV3/interfaces/IPoolV3.sol b/evm/contracts/intent-adapters/lending-borrowing/AaveV3/interfaces/IPoolV3.sol new file mode 100644 index 0000000..c5bea8b --- /dev/null +++ b/evm/contracts/intent-adapters/lending-borrowing/AaveV3/interfaces/IPoolV3.sol @@ -0,0 +1,773 @@ +// SPDX-License-Identifier: AGPL-3.0 +pragma solidity 0.8.18; + +import {DataTypes} from "./DataTypes.sol"; + +interface IPoolV3 { + /** + * @dev Emitted on mintUnbacked() + * @param reserve The address of the underlying asset of the reserve + * @param user The address initiating the supply + * @param onBehalfOf The beneficiary of the supplied assets, receiving the aTokens + * @param amount The amount of supplied assets + * @param referralCode The referral code used + **/ + event MintUnbacked( + address indexed reserve, + address user, + address indexed onBehalfOf, + uint256 amount, + uint16 indexed referralCode + ); + + /** + * @dev Emitted on backUnbacked() + * @param reserve The address of the underlying asset of the reserve + * @param backer The address paying for the backing + * @param amount The amount added as backing + * @param fee The amount paid in fees + **/ + event BackUnbacked( + address indexed reserve, + address indexed backer, + uint256 amount, + uint256 fee + ); + + /** + * @dev Emitted on supply() + * @param reserve The address of the underlying asset of the reserve + * @param user The address initiating the supply + * @param onBehalfOf The beneficiary of the supply, receiving the aTokens + * @param amount The amount supplied + * @param referralCode The referral code used + **/ + event Supply( + address indexed reserve, + address user, + address indexed onBehalfOf, + uint256 amount, + uint16 indexed referralCode + ); + + /** + * @dev Emitted on withdraw() + * @param reserve The address of the underlying asset being withdrawn + * @param user The address initiating the withdrawal, owner of aTokens + * @param to The address that will receive the underlying + * @param amount The amount to be withdrawn + **/ + event Withdraw( + address indexed reserve, + address indexed user, + address indexed to, + uint256 amount + ); + + /** + * @dev Emitted on borrow() and flashLoan() when debt needs to be opened + * @param reserve The address of the underlying asset being borrowed + * @param user The address of the user initiating the borrow(), receiving the funds on borrow() or just + * initiator of the transaction on flashLoan() + * @param onBehalfOf The address that will be getting the debt + * @param amount The amount borrowed out + * @param interestRateMode The rate mode: 1 for Stable, 2 for Variable + * @param borrowRate The numeric rate at which the user has borrowed, expressed in ray + * @param referralCode The referral code used + **/ + event Borrow( + address indexed reserve, + address user, + address indexed onBehalfOf, + uint256 amount, + DataTypes.InterestRateMode interestRateMode, + uint256 borrowRate, + uint16 indexed referralCode + ); + + /** + * @dev Emitted on repay() + * @param reserve The address of the underlying asset of the reserve + * @param user The beneficiary of the repayment, getting his debt reduced + * @param repayer The address of the user initiating the repay(), providing the funds + * @param amount The amount repaid + * @param useATokens True if the repayment is done using aTokens, `false` if done with underlying asset directly + **/ + event Repay( + address indexed reserve, + address indexed user, + address indexed repayer, + uint256 amount, + bool useATokens + ); + + /** + * @dev Emitted on swapBorrowRateMode() + * @param reserve The address of the underlying asset of the reserve + * @param user The address of the user swapping his rate mode + * @param interestRateMode The current interest rate mode of the position being swapped: 1 for Stable, 2 for Variable + **/ + event SwapBorrowRateMode( + address indexed reserve, + address indexed user, + DataTypes.InterestRateMode interestRateMode + ); + + /** + * @dev Emitted on borrow(), repay() and liquidationCall() when using isolated assets + * @param asset The address of the underlying asset of the reserve + * @param totalDebt The total isolation mode debt for the reserve + */ + event IsolationModeTotalDebtUpdated( + address indexed asset, + uint256 totalDebt + ); + + /** + * @dev Emitted when the user selects a certain asset category for eMode + * @param user The address of the user + * @param categoryId The category id + **/ + event UserEModeSet(address indexed user, uint8 categoryId); + + /** + * @dev Emitted on setUserUseReserveAsCollateral() + * @param reserve The address of the underlying asset of the reserve + * @param user The address of the user enabling the usage as collateral + **/ + event ReserveUsedAsCollateralEnabled( + address indexed reserve, + address indexed user + ); + + /** + * @dev Emitted on setUserUseReserveAsCollateral() + * @param reserve The address of the underlying asset of the reserve + * @param user The address of the user enabling the usage as collateral + **/ + event ReserveUsedAsCollateralDisabled( + address indexed reserve, + address indexed user + ); + + /** + * @dev Emitted on rebalanceStableBorrowRate() + * @param reserve The address of the underlying asset of the reserve + * @param user The address of the user for which the rebalance has been executed + **/ + event RebalanceStableBorrowRate( + address indexed reserve, + address indexed user + ); + + /** + * @dev Emitted on flashLoan() + * @param target The address of the flash loan receiver contract + * @param initiator The address initiating the flash loan + * @param asset The address of the asset being flash borrowed + * @param amount The amount flash borrowed + * @param interestRateMode The flashloan mode: 0 for regular flashloan, 1 for Stable debt, 2 for Variable debt + * @param premium The fee flash borrowed + * @param referralCode The referral code used + **/ + event FlashLoan( + address indexed target, + address initiator, + address indexed asset, + uint256 amount, + DataTypes.InterestRateMode interestRateMode, + uint256 premium, + uint16 indexed referralCode + ); + + /** + * @dev Emitted when a borrower is liquidated. + * @param collateralAsset The address of the underlying asset used as collateral, to receive as result of the liquidation + * @param debtAsset The address of the underlying borrowed asset to be repaid with the liquidation + * @param user The address of the borrower getting liquidated + * @param debtToCover The debt amount of borrowed `asset` the liquidator wants to cover + * @param liquidatedCollateralAmount The amount of collateral received by the liquidator + * @param liquidator The address of the liquidator + * @param receiveAToken True if the liquidators wants to receive the collateral aTokens, `false` if he wants + * to receive the underlying collateral asset directly + **/ + event LiquidationCall( + address indexed collateralAsset, + address indexed debtAsset, + address indexed user, + uint256 debtToCover, + uint256 liquidatedCollateralAmount, + address liquidator, + bool receiveAToken + ); + + /** + * @dev Emitted when the state of a reserve is updated. + * @param reserve The address of the underlying asset of the reserve + * @param liquidityRate The next liquidity rate + * @param stableBorrowRate The next stable borrow rate + * @param variableBorrowRate The next variable borrow rate + * @param liquidityIndex The next liquidity index + * @param variableBorrowIndex The next variable borrow index + **/ + event ReserveDataUpdated( + address indexed reserve, + uint256 liquidityRate, + uint256 stableBorrowRate, + uint256 variableBorrowRate, + uint256 liquidityIndex, + uint256 variableBorrowIndex + ); + + /** + * @dev Emitted when the protocol treasury receives minted aTokens from the accrued interest. + * @param reserve The address of the reserve + * @param amountMinted The amount minted to the treasury + **/ + event MintedToTreasury(address indexed reserve, uint256 amountMinted); + + /** + * @dev Mints an `amount` of aTokens to the `onBehalfOf` + * @param asset The address of the underlying asset to mint + * @param amount The amount to mint + * @param onBehalfOf The address that will receive the aTokens + * @param referralCode Code used to register the integrator originating the operation, for potential rewards. + * 0 if the action is executed directly by the user, without any middle-man + **/ + function mintUnbacked( + address asset, + uint256 amount, + address onBehalfOf, + uint16 referralCode + ) external; + + /** + * @dev Back the current unbacked underlying with `amount` and pay `fee`. + * @param asset The address of the underlying asset to back + * @param amount The amount to back + * @param fee The amount paid in fees + **/ + function backUnbacked(address asset, uint256 amount, uint256 fee) external; + + /** + * @notice Supplies an `amount` of underlying asset into the reserve, receiving in return overlying aTokens. + * - E.g. User supplies 100 USDC and gets in return 100 aUSDC + * @param asset The address of the underlying asset to supply + * @param amount The amount to be supplied + * @param onBehalfOf The address that will receive the aTokens, same as msg.sender if the user + * wants to receive them on his own wallet, or a different address if the beneficiary of aTokens + * is a different wallet + * @param referralCode Code used to register the integrator originating the operation, for potential rewards. + * 0 if the action is executed directly by the user, without any middle-man + **/ + function supply( + address asset, + uint256 amount, + address onBehalfOf, + uint16 referralCode + ) external; + + /** + * @notice Supply with transfer approval of asset to be supplied done via permit function + * see: https://eips.ethereum.org/EIPS/eip-2612 and https://eips.ethereum.org/EIPS/eip-713 + * @param asset The address of the underlying asset to supply + * @param amount The amount to be supplied + * @param onBehalfOf The address that will receive the aTokens, same as msg.sender if the user + * wants to receive them on his own wallet, or a different address if the beneficiary of aTokens + * is a different wallet + * @param deadline The deadline timestamp that the permit is valid + * @param referralCode Code used to register the integrator originating the operation, for potential rewards. + * 0 if the action is executed directly by the user, without any middle-man + * @param permitV The V parameter of ERC712 permit sig + * @param permitR The R parameter of ERC712 permit sig + * @param permitS The S parameter of ERC712 permit sig + **/ + function supplyWithPermit( + address asset, + uint256 amount, + address onBehalfOf, + uint16 referralCode, + uint256 deadline, + uint8 permitV, + bytes32 permitR, + bytes32 permitS + ) external; + + /** + * @notice Withdraws an `amount` of underlying asset from the reserve, burning the equivalent aTokens owned + * E.g. User has 100 aUSDC, calls withdraw() and receives 100 USDC, burning the 100 aUSDC + * @param asset The address of the underlying asset to withdraw + * @param amount The underlying amount to be withdrawn + * - Send the value type(uint256).max in order to withdraw the whole aToken balance + * @param to The address that will receive the underlying, same as msg.sender if the user + * wants to receive it on his own wallet, or a different address if the beneficiary is a + * different wallet + * @return The final amount withdrawn + **/ + function withdraw( + address asset, + uint256 amount, + address to + ) external returns (uint256); + + /** + * @notice Allows users to borrow a specific `amount` of the reserve underlying asset, provided that the borrower + * already supplied enough collateral, or he was given enough allowance by a credit delegator on the + * corresponding debt token (StableDebtToken or VariableDebtToken) + * - E.g. User borrows 100 USDC passing as `onBehalfOf` his own address, receiving the 100 USDC in his wallet + * and 100 stable/variable debt tokens, depending on the `interestRateMode` + * @param asset The address of the underlying asset to borrow + * @param amount The amount to be borrowed + * @param interestRateMode The interest rate mode at which the user wants to borrow: 1 for Stable, 2 for Variable + * @param referralCode The code used to register the integrator originating the operation, for potential rewards. + * 0 if the action is executed directly by the user, without any middle-man + * @param onBehalfOf The address of the user who will receive the debt. Should be the address of the borrower itself + * calling the function if he wants to borrow against his own collateral, or the address of the credit delegator + * if he has been given credit delegation allowance + **/ + function borrow( + address asset, + uint256 amount, + uint256 interestRateMode, + uint16 referralCode, + address onBehalfOf + ) external; + + /** + * @notice Repays a borrowed `amount` on a specific reserve, burning the equivalent debt tokens owned + * - E.g. User repays 100 USDC, burning 100 variable/stable debt tokens of the `onBehalfOf` address + * @param asset The address of the borrowed underlying asset previously borrowed + * @param amount The amount to repay + * - Send the value type(uint256).max in order to repay the whole debt for `asset` on the specific `debtMode` + * @param interestRateMode The interest rate mode at of the debt the user wants to repay: 1 for Stable, 2 for Variable + * @param onBehalfOf The address of the user who will get his debt reduced/removed. Should be the address of the + * user calling the function if he wants to reduce/remove his own debt, or the address of any other + * other borrower whose debt should be removed + * @return The final amount repaid + **/ + function repay( + address asset, + uint256 amount, + uint256 interestRateMode, + address onBehalfOf + ) external returns (uint256); + + /** + * @notice Repay with transfer approval of asset to be repaid done via permit function + * see: https://eips.ethereum.org/EIPS/eip-2612 and https://eips.ethereum.org/EIPS/eip-713 + * @param asset The address of the borrowed underlying asset previously borrowed + * @param amount The amount to repay + * - Send the value type(uint256).max in order to repay the whole debt for `asset` on the specific `debtMode` + * @param interestRateMode The interest rate mode at of the debt the user wants to repay: 1 for Stable, 2 for Variable + * @param onBehalfOf Address of the user who will get his debt reduced/removed. Should be the address of the + * user calling the function if he wants to reduce/remove his own debt, or the address of any other + * other borrower whose debt should be removed + * @param deadline The deadline timestamp that the permit is valid + * @param permitV The V parameter of ERC712 permit sig + * @param permitR The R parameter of ERC712 permit sig + * @param permitS The S parameter of ERC712 permit sig + * @return The final amount repaid + **/ + function repayWithPermit( + address asset, + uint256 amount, + uint256 interestRateMode, + address onBehalfOf, + uint256 deadline, + uint8 permitV, + bytes32 permitR, + bytes32 permitS + ) external returns (uint256); + + /** + * @notice Repays a borrowed `amount` on a specific reserve using the reserve aTokens, burning the + * equivalent debt tokens + * - E.g. User repays 100 USDC using 100 aUSDC, burning 100 variable/stable debt tokens + * @dev Passing uint256.max as amount will clean up any residual aToken dust balance, if the user aToken + * balance is not enough to cover the whole debt + * @param asset The address of the borrowed underlying asset previously borrowed + * @param amount The amount to repay + * - Send the value type(uint256).max in order to repay the whole debt for `asset` on the specific `debtMode` + * @param interestRateMode The interest rate mode at of the debt the user wants to repay: 1 for Stable, 2 for Variable + * @return The final amount repaid + **/ + function repayWithATokens( + address asset, + uint256 amount, + uint256 interestRateMode + ) external returns (uint256); + + /** + * @notice Allows a borrower to swap his debt between stable and variable mode, or vice versa + * @param asset The address of the underlying asset borrowed + * @param interestRateMode The current interest rate mode of the position being swapped: 1 for Stable, 2 for Variable + **/ + function swapBorrowRateMode( + address asset, + uint256 interestRateMode + ) external; + + /** + * @notice Rebalances the stable interest rate of a user to the current stable rate defined on the reserve. + * - Users can be rebalanced if the following conditions are satisfied: + * 1. Usage ratio is above 95% + * 2. the current supply APY is below REBALANCE_UP_THRESHOLD * maxVariableBorrowRate, which means that too + * much has been borrowed at a stable rate and suppliers are not earning enough + * @param asset The address of the underlying asset borrowed + * @param user The address of the user to be rebalanced + **/ + function rebalanceStableBorrowRate(address asset, address user) external; + + /** + * @notice Allows suppliers to enable/disable a specific supplied asset as collateral + * @param asset The address of the underlying asset supplied + * @param useAsCollateral True if the user wants to use the supply as collateral, false otherwise + **/ + function setUserUseReserveAsCollateral( + address asset, + bool useAsCollateral + ) external; + + /** + * @notice Function to liquidate a non-healthy position collateral-wise, with Health Factor below 1 + * - The caller (liquidator) covers `debtToCover` amount of debt of the user getting liquidated, and receives + * a proportionally amount of the `collateralAsset` plus a bonus to cover market risk + * @param collateralAsset The address of the underlying asset used as collateral, to receive as result of the liquidation + * @param debtAsset The address of the underlying borrowed asset to be repaid with the liquidation + * @param user The address of the borrower getting liquidated + * @param debtToCover The debt amount of borrowed `asset` the liquidator wants to cover + * @param receiveAToken True if the liquidators wants to receive the collateral aTokens, `false` if he wants + * to receive the underlying collateral asset directly + **/ + function liquidationCall( + address collateralAsset, + address debtAsset, + address user, + uint256 debtToCover, + bool receiveAToken + ) external; + + /** + * @notice Allows smartcontracts to access the liquidity of the pool within one transaction, + * as long as the amount taken plus a fee is returned. + * @dev IMPORTANT There are security concerns for developers of flashloan receiver contracts that must be kept + * into consideration. For further details please visit https://developers.aave.com + * @param receiverAddress The address of the contract receiving the funds, implementing IFlashLoanReceiver interface + * @param assets The addresses of the assets being flash-borrowed + * @param amounts The amounts of the assets being flash-borrowed + * @param interestRateModes Types of the debt to open if the flash loan is not returned: + * 0 -> Don't open any debt, just revert if funds can't be transferred from the receiver + * 1 -> Open debt at stable rate for the value of the amount flash-borrowed to the `onBehalfOf` address + * 2 -> Open debt at variable rate for the value of the amount flash-borrowed to the `onBehalfOf` address + * @param onBehalfOf The address that will receive the debt in the case of using on `modes` 1 or 2 + * @param params Variadic packed params to pass to the receiver as extra information + * @param referralCode The code used to register the integrator originating the operation, for potential rewards. + * 0 if the action is executed directly by the user, without any middle-man + **/ + function flashLoan( + address receiverAddress, + address[] calldata assets, + uint256[] calldata amounts, + uint256[] calldata interestRateModes, + address onBehalfOf, + bytes calldata params, + uint16 referralCode + ) external; + + /** + * @notice Allows smartcontracts to access the liquidity of the pool within one transaction, + * as long as the amount taken plus a fee is returned. + * @dev IMPORTANT There are security concerns for developers of flashloan receiver contracts that must be kept + * into consideration. For further details please visit https://developers.aave.com + * @param receiverAddress The address of the contract receiving the funds, implementing IFlashLoanSimpleReceiver interface + * @param asset The address of the asset being flash-borrowed + * @param amount The amount of the asset being flash-borrowed + * @param params Variadic packed params to pass to the receiver as extra information + * @param referralCode The code used to register the integrator originating the operation, for potential rewards. + * 0 if the action is executed directly by the user, without any middle-man + **/ + function flashLoanSimple( + address receiverAddress, + address asset, + uint256 amount, + bytes calldata params, + uint16 referralCode + ) external; + + /** + * @notice Returns the user account data across all the reserves + * @param user The address of the user + * @return totalCollateralBase The total collateral of the user in the base currency used by the price feed + * @return totalDebtBase The total debt of the user in the base currency used by the price feed + * @return availableBorrowsBase The borrowing power left of the user in the base currency used by the price feed + * @return currentLiquidationThreshold The liquidation threshold of the user + * @return ltv The loan to value of The user + * @return healthFactor The current health factor of the user + **/ + function getUserAccountData( + address user + ) + external + view + returns ( + uint256 totalCollateralBase, + uint256 totalDebtBase, + uint256 availableBorrowsBase, + uint256 currentLiquidationThreshold, + uint256 ltv, + uint256 healthFactor + ); + + /** + * @notice Initializes a reserve, activating it, assigning an aToken and debt tokens and an + * interest rate strategy + * @dev Only callable by the PoolConfigurator contract + * @param asset The address of the underlying asset of the reserve + * @param aTokenAddress The address of the aToken that will be assigned to the reserve + * @param stableDebtAddress The address of the StableDebtToken that will be assigned to the reserve + * @param variableDebtAddress The address of the VariableDebtToken that will be assigned to the reserve + * @param interestRateStrategyAddress The address of the interest rate strategy contract + **/ + function initReserve( + address asset, + address aTokenAddress, + address stableDebtAddress, + address variableDebtAddress, + address interestRateStrategyAddress + ) external; + + /** + * @notice Drop a reserve + * @dev Only callable by the PoolConfigurator contract + * @param asset The address of the underlying asset of the reserve + **/ + function dropReserve(address asset) external; + + /** + * @notice Updates the address of the interest rate strategy contract + * @dev Only callable by the PoolConfigurator contract + * @param asset The address of the underlying asset of the reserve + * @param rateStrategyAddress The address of the interest rate strategy contract + **/ + function setReserveInterestRateStrategyAddress( + address asset, + address rateStrategyAddress + ) external; + + /** + * @notice Sets the configuration bitmap of the reserve as a whole + * @dev Only callable by the PoolConfigurator contract + * @param asset The address of the underlying asset of the reserve + * @param configuration The new configuration bitmap + **/ + function setConfiguration( + address asset, + DataTypes.ReserveConfigurationMap calldata configuration + ) external; + + /** + * @notice Returns the configuration of the reserve + * @param asset The address of the underlying asset of the reserve + * @return The configuration of the reserve + **/ + function getConfiguration( + address asset + ) external view returns (DataTypes.ReserveConfigurationMap memory); + + /** + * @notice Returns the configuration of the user across all the reserves + * @param user The user address + * @return The configuration of the user + **/ + function getUserConfiguration( + address user + ) external view returns (DataTypes.UserConfigurationMap memory); + + /** + * @notice Returns the normalized income normalized income of the reserve + * @param asset The address of the underlying asset of the reserve + * @return The reserve's normalized income + */ + function getReserveNormalizedIncome( + address asset + ) external view returns (uint256); + + /** + * @notice Returns the normalized variable debt per unit of asset + * @param asset The address of the underlying asset of the reserve + * @return The reserve normalized variable debt + */ + function getReserveNormalizedVariableDebt( + address asset + ) external view returns (uint256); + + /** + * @notice Returns the state and configuration of the reserve + * @param asset The address of the underlying asset of the reserve + * @return The state and configuration data of the reserve + **/ + function getReserveData( + address asset + ) external view returns (DataTypes.ReserveData memory); + + /** + * @notice Validates and finalizes an aToken transfer + * @dev Only callable by the overlying aToken of the `asset` + * @param asset The address of the underlying asset of the aToken + * @param from The user from which the aTokens are transferred + * @param to The user receiving the aTokens + * @param amount The amount being transferred/withdrawn + * @param balanceFromBefore The aToken balance of the `from` user before the transfer + * @param balanceToBefore The aToken balance of the `to` user before the transfer + */ + function finalizeTransfer( + address asset, + address from, + address to, + uint256 amount, + uint256 balanceFromBefore, + uint256 balanceToBefore + ) external; + + /** + * @notice Returns the list of the initialized reserves + * @dev It does not include dropped reserves + * @return The addresses of the reserves + **/ + function getReservesList() external view returns (address[] memory); + + /** + * @notice Updates the protocol fee on the bridging + * @param bridgeProtocolFee The part of the premium sent to the protocol treasury + */ + function updateBridgeProtocolFee(uint256 bridgeProtocolFee) external; + + /** + * @notice Updates flash loan premiums. Flash loan premium consists of two parts: + * - A part is sent to aToken holders as extra, one time accumulated interest + * - A part is collected by the protocol treasury + * @dev The total premium is calculated on the total borrowed amount + * @dev The premium to protocol is calculated on the total premium, being a percentage of `flashLoanPremiumTotal` + * @dev Only callable by the PoolConfigurator contract + * @param flashLoanPremiumTotal The total premium, expressed in bps + * @param flashLoanPremiumToProtocol The part of the premium sent to the protocol treasury, expressed in bps + */ + function updateFlashloanPremiums( + uint128 flashLoanPremiumTotal, + uint128 flashLoanPremiumToProtocol + ) external; + + /** + * @notice Configures a new category for the eMode. + * @dev In eMode, the protocol allows very high borrowing power to borrow assets of the same category. + * The category 0 is reserved as it's the default for volatile assets + * @param id The id of the category + * @param config The configuration of the category + */ + function configureEModeCategory( + uint8 id, + DataTypes.EModeCategory memory config + ) external; + + /** + * @notice Returns the data of an eMode category + * @param id The id of the category + * @return The configuration data of the category + */ + function getEModeCategoryData( + uint8 id + ) external view returns (DataTypes.EModeCategory memory); + + /** + * @notice Allows a user to use the protocol in eMode + * @param categoryId The id of the category + */ + function setUserEMode(uint8 categoryId) external; + + /** + * @notice Returns the eMode the user is using + * @param user The address of the user + * @return The eMode id + */ + function getUserEMode(address user) external view returns (uint256); + + /** + * @notice Resets the isolation mode total debt of the given asset to zero + * @dev It requires the given asset has zero debt ceiling + * @param asset The address of the underlying asset to reset the isolationModeTotalDebt + */ + function resetIsolationModeTotalDebt(address asset) external; + + /** + * @notice Returns the percentage of available liquidity that can be borrowed at once at stable rate + * @return The percentage of available liquidity to borrow, expressed in bps + */ + function MAX_STABLE_RATE_BORROW_SIZE_PERCENT() + external + view + returns (uint256); + + /** + * @notice Returns the total fee on flash loans + * @return The total fee on flashloans + */ + function FLASHLOAN_PREMIUM_TOTAL() external view returns (uint128); + + /** + * @notice Returns the part of the bridge fees sent to protocol + * @return The bridge fee sent to the protocol treasury + */ + function BRIDGE_PROTOCOL_FEE() external view returns (uint256); + + /** + * @notice Returns the part of the flashloan fees sent to protocol + * @return The flashloan fee sent to the protocol treasury + */ + function FLASHLOAN_PREMIUM_TO_PROTOCOL() external view returns (uint128); + + /** + * @notice Returns the maximum number of reserves supported to be listed in this Pool + * @return The maximum number of reserves supported + */ + function MAX_NUMBER_RESERVES() external view returns (uint16); + + /** + * @notice Mints the assets accrued through the reserve factor to the treasury in the form of aTokens + * @param assets The list of reserves for which the minting needs to be executed + **/ + function mintToTreasury(address[] calldata assets) external; + + /** + * @notice Rescue and transfer tokens locked in this contract + * @param token The address of the token + * @param to The address of the recipient + * @param amount The amount of token to transfer + */ + function rescueTokens(address token, address to, uint256 amount) external; + + /** + * @notice Supplies an `amount` of underlying asset into the reserve, receiving in return overlying aTokens. + * - E.g. User supplies 100 USDC and gets in return 100 aUSDC + * @dev Deprecated: Use the `supply` function instead + * @param asset The address of the underlying asset to supply + * @param amount The amount to be supplied + * @param onBehalfOf The address that will receive the aTokens, same as msg.sender if the user + * wants to receive them on his own wallet, or a different address if the beneficiary of aTokens + * is a different wallet + * @param referralCode Code used to register the integrator originating the operation, for potential rewards. + * 0 if the action is executed directly by the user, without any middle-man + **/ + function deposit( + address asset, + uint256 amount, + address onBehalfOf, + uint16 referralCode + ) external; + + /** + * @notice Returns the address of the underlying asset of a reserve by the reserve id as stored in the DataTypes.ReserveData struct + * @param id The id of the reserve as stored in the DataTypes.ReserveData struct + * @return The address of the reserve associated with id + **/ + function getReserveAddressById(uint16 id) external view returns (address); +} diff --git a/evm/contracts/intent-adapters/lending-borrowing/AaveV3/interfaces/IWrappedTokenGateway.sol b/evm/contracts/intent-adapters/lending-borrowing/AaveV3/interfaces/IWrappedTokenGateway.sol new file mode 100644 index 0000000..81cab0c --- /dev/null +++ b/evm/contracts/intent-adapters/lending-borrowing/AaveV3/interfaces/IWrappedTokenGateway.sol @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: AGPL-3.0 +pragma solidity 0.8.18; + +interface IWrappedTokenGateway { + function depositETH( + address, + address onBehalfOf, + uint16 referralCode + ) external payable; +} diff --git a/evm/contracts/intent-adapters/lending-borrowing/Compound/CompoundBorrow.sol b/evm/contracts/intent-adapters/lending-borrowing/Compound/CompoundBorrow.sol new file mode 100644 index 0000000..a98dd48 --- /dev/null +++ b/evm/contracts/intent-adapters/lending-borrowing/Compound/CompoundBorrow.sol @@ -0,0 +1,131 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.18; + +import {CompoundHelpers} from "./CompoundHelpers.sol"; +import {IComet} from "./interfaces/IComet.sol"; +import {RouterIntentEoaAdapter, EoaExecutor} from "router-intents/contracts/RouterIntentEoaAdapter.sol"; +import {NitroMessageHandler} from "router-intents/contracts/utils/NitroMessageHandler.sol"; +import {Errors} from "router-intents/contracts/utils/Errors.sol"; +import {DefaultRefundable} from "router-intents/contracts/utils/DefaultRefundable.sol"; +import {IERC20, SafeERC20} from "../../../utils/SafeERC20.sol"; + +/** + * @title CompoundBorrow + * @author Yashika Goyal + * @notice Borrowing funds on Compound. + */ +contract CompoundBorrow is + RouterIntentEoaAdapter, + NitroMessageHandler, + DefaultRefundable, + CompoundHelpers +{ + using SafeERC20 for IERC20; + + constructor( + address __native, + address __wnative, + address __owner, + address __assetForwarder, + address __dexspan, + address __defaultRefundAddress, + address __usdc, + address __cUSDCV3Pool, + address __cWETHV3Pool + ) + RouterIntentEoaAdapter(__native, __wnative, __owner) + NitroMessageHandler(__assetForwarder, __dexspan) + DefaultRefundable(__defaultRefundAddress) + CompoundHelpers(__usdc, __cUSDCV3Pool, __cWETHV3Pool) + // solhint-disable-next-line no-empty-blocks + { + + } + + function name() public pure override returns (string memory) { + return "CompoundBorrow"; + } + + /** + * @inheritdoc EoaExecutor + */ + function execute( + address, + address, + bytes calldata data + ) external payable override returns (address[] memory tokens) { + ( + uint256 amount, + address asset, + address onBehalfOf, + address recipient + ) = parseInputs(data); + + bytes memory logData; + + (tokens, logData) = _compoundBorrow( + amount, + asset, + onBehalfOf, + recipient + ); + + emit ExecutionEvent(name(), logData); + return tokens; + } + + //////////////////////////// ACTION LOGIC //////////////////////////// + + /** + * @notice function to borrow funds from Compound. + * @param amount Amount of asset to be borrowed. + * @param asset Asset to be borrowed. + * @param onBehalfOf The user who will incur the borrow. + * @param recipient The address to send the withdrawn or borrowed asset. + */ + function _compoundBorrow( + uint256 amount, + address asset, + address onBehalfOf, + address recipient + ) private returns (address[] memory tokens, bytes memory logData) { + IComet _cTokenV3Pool; + if (asset == usdc()) { + _cTokenV3Pool = cUSDCV3Pool(); + } else if (asset == wnative()) { + _cTokenV3Pool = cWETHV3Pool(); + } else revert InvalidBorrowMarket(); + + _cTokenV3Pool.withdrawFrom(onBehalfOf, recipient, asset, amount); + + tokens = new address[](1); + tokens[0] = asset; + + logData = abi.encode(amount, asset, onBehalfOf, recipient); + } + + /** + * @inheritdoc NitroMessageHandler + */ + function handleMessage( + address tokenSent, + uint256 amount, + bytes memory + ) external override onlyNitro nonReentrant { + withdrawTokens(tokenSent, defaultRefundAddress(), amount); + emit UnsupportedOperation(tokenSent, defaultRefundAddress(), amount); + } + + /** + * @dev function to parse input data. + * @param data input data. + */ + function parseInputs( + bytes memory data + ) public pure returns (uint256, address, address, address) { + return abi.decode(data, (uint256, address, address, address)); + } + + // solhint-disable-next-line no-empty-blocks + receive() external payable {} +} diff --git a/evm/contracts/intent-adapters/lending-borrowing/Compound/CompoundHelpers.sol b/evm/contracts/intent-adapters/lending-borrowing/Compound/CompoundHelpers.sol new file mode 100644 index 0000000..48177d0 --- /dev/null +++ b/evm/contracts/intent-adapters/lending-borrowing/Compound/CompoundHelpers.sol @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.18; + +import {IComet} from "./interfaces/IComet.sol"; + +contract CompoundHelpers { + address private immutable _usdc; + IComet private immutable _cUSDCV3Pool; + IComet private immutable _cWETHV3Pool; + + error InvalidBorrowMarket(); + error InvalidSupplyMarket(); + + constructor(address __usdc, address __cUSDCV3Pool, address __cWETHV3Pool) { + _usdc = __usdc; + _cUSDCV3Pool = IComet(__cUSDCV3Pool); + _cWETHV3Pool = IComet(__cWETHV3Pool); + } + + function usdc() public view returns (address) { + return _usdc; + } + + function cUSDCV3Pool() public view returns (IComet) { + return _cUSDCV3Pool; + } + + function cWETHV3Pool() public view returns (IComet) { + return _cWETHV3Pool; + } +} diff --git a/evm/contracts/intent-adapters/lending-borrowing/Compound/CompoundSupply.sol b/evm/contracts/intent-adapters/lending-borrowing/Compound/CompoundSupply.sol new file mode 100644 index 0000000..86ba1fd --- /dev/null +++ b/evm/contracts/intent-adapters/lending-borrowing/Compound/CompoundSupply.sol @@ -0,0 +1,197 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.18; + +import {CompoundHelpers} from "./CompoundHelpers.sol"; +import {IComet} from "./interfaces/IComet.sol"; +import {RouterIntentEoaAdapter, EoaExecutor} from "router-intents/contracts/RouterIntentEoaAdapter.sol"; +import {NitroMessageHandler} from "router-intents/contracts/utils/NitroMessageHandler.sol"; +import {Errors} from "router-intents/contracts/utils/Errors.sol"; +import {IERC20, SafeERC20} from "../../../utils/SafeERC20.sol"; +import {IWETH} from "../../../interfaces/IWETH.sol"; + +/** + * @title CompoundSupply + * @author Yashika Goyal + * @notice Supplying funds on Compound. + */ +contract CompoundSupply is + RouterIntentEoaAdapter, + NitroMessageHandler, + CompoundHelpers +{ + using SafeERC20 for IERC20; + + event CompoundSupplyDest( + address _token, + address _recipient, + uint256 _amount + ); + + constructor( + address __native, + address __wnative, + address __owner, + address __assetForwarder, + address __dexspan, + address __usdc, + address __cUSDCV3Pool, + address __cWETHV3Pool + ) + RouterIntentEoaAdapter(__native, __wnative, __owner) + NitroMessageHandler(__assetForwarder, __dexspan) + CompoundHelpers(__usdc, __cUSDCV3Pool, __cWETHV3Pool) + // solhint-disable-next-line no-empty-blocks + { + + } + + function name() public pure override returns (string memory) { + return "CompoundSupply"; + } + + /** + * @inheritdoc EoaExecutor + */ + function execute( + address, + address, + bytes calldata data + ) external payable override returns (address[] memory tokens) { + ( + address _asset, + address _recipient, + uint256 _amount, + address _market + ) = parseInputs(data); + + // If the adapter is called using `call` and not `delegatecall` + if (address(this) == self()) { + if (_asset == native()) + require( + msg.value == _amount, + Errors.INSUFFICIENT_NATIVE_FUNDS_PASSED + ); + else IERC20(_asset).safeTransferFrom(msg.sender, self(), _amount); + } + + bytes memory logData; + + (tokens, logData) = _compoundSupply( + _asset, + _recipient, + _amount, + _market + ); + + emit ExecutionEvent(name(), logData); + return tokens; + } + + /** + * @inheritdoc NitroMessageHandler + */ + function handleMessage( + address tokenSent, + uint256 amount, + bytes memory instruction + ) external override onlyNitro nonReentrant { + (address recipient, address market) = abi.decode( + instruction, + (address, address) + ); + + IComet _cTokenV3Pool; + + if (market == usdc()) { + _cTokenV3Pool = cUSDCV3Pool(); + } else if (market == wnative()) { + _cTokenV3Pool = cWETHV3Pool(); + } else { + withdrawTokens(tokenSent, recipient, amount); + emit OperationFailedRefundEvent(tokenSent, recipient, amount); + return; + } + + approveToken(tokenSent, address(_cTokenV3Pool), amount); + uint256 supplyAmount = amount; + + if (tokenSent == native()) { + if (wnative() == _cTokenV3Pool.baseToken()) { + if (amount == type(uint256).max) + supplyAmount = _cTokenV3Pool.borrowBalanceOf(msg.sender); + } + IWETH(wnative()).deposit{value: supplyAmount}(); + IWETH(wnative()).approve(address(_cTokenV3Pool), supplyAmount); + + try _cTokenV3Pool.supplyTo(recipient, wnative(), supplyAmount) { + emit CompoundSupplyDest(native(), recipient, amount); + } catch { + withdrawTokens(native(), recipient, amount); + emit OperationFailedRefundEvent(native(), recipient, amount); + } + } else + try _cTokenV3Pool.supplyTo(recipient, tokenSent, amount) { + emit CompoundSupplyDest(tokenSent, recipient, amount); + } catch { + withdrawTokens(tokenSent, recipient, amount); + emit OperationFailedRefundEvent(tokenSent, recipient, amount); + } + } + + //////////////////////////// ACTION LOGIC //////////////////////////// + + /** + * @notice function to supply funds to Compound. + * @param market Address of USDC/WETH address to specify the supply-borrow market to enter. + * @param amount Amount of supply asset to be supplied. + * @param recipient Recipient of aTokens after funds have been supplied. + * @param asset Asset to be supplied. + */ + function _compoundSupply( + address asset, + address recipient, + uint256 amount, + address market + ) private returns (address[] memory tokens, bytes memory logData) { + IComet _cTokenV3Pool; + + if (market == usdc()) { + _cTokenV3Pool = cUSDCV3Pool(); + } else if (market == wnative()) { + _cTokenV3Pool = cWETHV3Pool(); + } else revert InvalidSupplyMarket(); + + approveToken(asset, address(_cTokenV3Pool), amount); + + uint256 supplyAmount = amount; + + if (asset == native()) { + if (wnative() == _cTokenV3Pool.baseToken()) { + if (amount == type(uint256).max) + supplyAmount = _cTokenV3Pool.borrowBalanceOf(msg.sender); + } + IWETH(wnative()).deposit{value: supplyAmount}(); + IWETH(wnative()).approve(address(_cTokenV3Pool), supplyAmount); + + _cTokenV3Pool.supplyTo(recipient, wnative(), supplyAmount); + } else _cTokenV3Pool.supplyTo(recipient, asset, amount); + + tokens = new address[](1); + tokens[0] = asset; + + logData = abi.encode(asset, recipient, recipient, market); + } + + /** + * @dev function to parse input data. + * @param data input data. + */ + function parseInputs( + bytes memory data + ) public pure returns (address, address, uint256, address) { + return abi.decode(data, (address, address, uint256, address)); + } + + // solhint-disable-next-line no-empty-blocks + receive() external payable {} +} diff --git a/evm/contracts/intent-adapters/lending-borrowing/Compound/interfaces/IComet.sol b/evm/contracts/intent-adapters/lending-borrowing/Compound/interfaces/IComet.sol new file mode 100644 index 0000000..4a2f16e --- /dev/null +++ b/evm/contracts/intent-adapters/lending-borrowing/Compound/interfaces/IComet.sol @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.18; + +interface IComet { + function allow(address manager, bool isAllowed) external; + + function baseToken() external view returns (address); + + function borrowBalanceOf(address account) external view returns (uint256); + + function collateralBalanceOf( + address account, + address asset + ) external view returns (uint128); + + function supply(address asset, uint amount) external; + + function supplyTo(address dst, address asset, uint amount) external; + + function supplyFrom( + address from, + address dst, + address asset, + uint amount + ) external; + + function withdraw(address asset, uint amount) external; + + function withdrawTo(address to, address asset, uint amount) external; + + function withdrawFrom( + address src, + address to, + address asset, + uint amount + ) external; +} diff --git a/evm/contracts/intent-adapters/liquid-staking/Ankr/AnkrStakeAvax.sol b/evm/contracts/intent-adapters/liquid-staking/Ankr/AnkrStakeAvax.sol new file mode 100644 index 0000000..56ccfd4 --- /dev/null +++ b/evm/contracts/intent-adapters/liquid-staking/Ankr/AnkrStakeAvax.sol @@ -0,0 +1,144 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.18; + +import {IAnkrStakeAvax} from "./Interfaces.sol"; +import {RouterIntentEoaAdapter, EoaExecutor} from "router-intents/contracts/RouterIntentEoaAdapter.sol"; +import {NitroMessageHandler} from "router-intents/contracts/utils/NitroMessageHandler.sol"; +import {Errors} from "router-intents/contracts/utils/Errors.sol"; +import {IERC20, SafeERC20} from "../../../utils/SafeERC20.sol"; + +/** + * @title AnkrStakeAvax + * @author Yashika Goyal + * @notice Staking AVAX to receive AnkrAVAX on Ankr. + * @notice This contract is only for Avalanche chain. + */ +contract AnkrStakeAvax is RouterIntentEoaAdapter, NitroMessageHandler { + using SafeERC20 for IERC20; + + address private immutable _ankrAvax; + IAnkrStakeAvax private immutable _ankrPool; + + event AnkrStakeAvaxDest( + address _recipient, + uint256 _amount, + uint256 _returnAmount + ); + + constructor( + address __native, + address __wnative, + address __owner, + address __assetForwarder, + address __dexspan, + address __ankrAvax, + address __ankrPool + ) + RouterIntentEoaAdapter(__native, __wnative, __owner) + NitroMessageHandler(__assetForwarder, __dexspan) + { + _ankrAvax = __ankrAvax; + _ankrPool = IAnkrStakeAvax(__ankrPool); + } + + function ankrAvax() public view returns (address) { + return _ankrAvax; + } + + function ankrPool() public view returns (IAnkrStakeAvax) { + return _ankrPool; + } + + function name() public pure override returns (string memory) { + return "AnkrStakeAvax"; + } + + /** + * @inheritdoc EoaExecutor + */ + function execute( + address, + address, + bytes calldata data + ) external payable override returns (address[] memory tokens) { + (address _recipient, uint256 _amount) = parseInputs(data); + + // If the adapter is called using `call` and not `delegatecall` + if (address(this) == self()) { + require( + msg.value == _amount, + Errors.INSUFFICIENT_NATIVE_FUNDS_PASSED + ); + } + + bytes memory logData; + + (tokens, logData) = _stake(_recipient, _amount); + + emit ExecutionEvent(name(), logData); + return tokens; + } + + /** + * @inheritdoc NitroMessageHandler + */ + function handleMessage( + address tokenSent, + uint256 amount, + bytes memory instruction + ) external override onlyNitro nonReentrant { + address recipient = abi.decode(instruction, (address)); + + if (tokenSent != native()) { + withdrawTokens(tokenSent, recipient, amount); + emit OperationFailedRefundEvent(tokenSent, recipient, amount); + return; + } + + try _ankrPool.stakeAndClaimCerts{value: amount}() { + uint256 returnAmount = withdrawTokens( + _ankrAvax, + recipient, + type(uint256).max + ); + + emit AnkrStakeAvaxDest(recipient, amount, returnAmount); + } catch { + withdrawTokens(tokenSent, recipient, amount); + emit OperationFailedRefundEvent(tokenSent, recipient, amount); + } + } + + //////////////////////////// ACTION LOGIC //////////////////////////// + + function _stake( + address _recipient, + uint256 _amount + ) internal returns (address[] memory tokens, bytes memory logData) { + _ankrPool.stakeAndClaimCerts{value: _amount}(); + uint256 returnAmount = withdrawTokens( + _ankrAvax, + _recipient, + type(uint256).max + ); + + tokens = new address[](2); + tokens[0] = native(); + tokens[1] = ankrAvax(); + + logData = abi.encode(_recipient, _amount, returnAmount); + } + + /** + * @dev function to parse input data. + * @param data input data. + */ + function parseInputs( + bytes memory data + ) public pure returns (address, uint256) { + return abi.decode(data, (address, uint256)); + } + + // solhint-disable-next-line no-empty-blocks + receive() external payable {} +} diff --git a/evm/contracts/intent-adapters/liquid-staking/Ankr/AnkrStakeBsc.sol b/evm/contracts/intent-adapters/liquid-staking/Ankr/AnkrStakeBsc.sol new file mode 100644 index 0000000..1371137 --- /dev/null +++ b/evm/contracts/intent-adapters/liquid-staking/Ankr/AnkrStakeBsc.sol @@ -0,0 +1,144 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.18; + +import {IAnkrStakeBsc} from "./Interfaces.sol"; +import {RouterIntentEoaAdapter, EoaExecutor} from "router-intents/contracts/RouterIntentEoaAdapter.sol"; +import {NitroMessageHandler} from "router-intents/contracts/utils/NitroMessageHandler.sol"; +import {Errors} from "router-intents/contracts/utils/Errors.sol"; +import {IERC20, SafeERC20} from "../../../utils/SafeERC20.sol"; + +/** + * @title AnkrStakeBsc + * @author Yashika Goyal + * @notice Staking BSC to receive AnkrBSC on Ankr. + * @notice This contract is only for BSC chain. + */ +contract AnkrStakeBsc is RouterIntentEoaAdapter, NitroMessageHandler { + using SafeERC20 for IERC20; + + address private immutable _ankrBsc; + IAnkrStakeBsc private immutable _ankrPool; + + event AnkrStakeBscDest( + address _recipient, + uint256 _amount, + uint256 _returnAmount + ); + + constructor( + address __native, + address __wnative, + address __owner, + address __assetForwarder, + address __dexspan, + address __ankrBsc, + address __ankrPool + ) + RouterIntentEoaAdapter(__native, __wnative, __owner) + NitroMessageHandler(__assetForwarder, __dexspan) + { + _ankrBsc = __ankrBsc; + _ankrPool = IAnkrStakeBsc(__ankrPool); + } + + function ankrBsc() public view returns (address) { + return _ankrBsc; + } + + function ankrPool() public view returns (IAnkrStakeBsc) { + return _ankrPool; + } + + function name() public pure override returns (string memory) { + return "AnkrStakeBsc"; + } + + /** + * @inheritdoc EoaExecutor + */ + function execute( + address, + address, + bytes calldata data + ) external payable override returns (address[] memory tokens) { + (address _recipient, uint256 _amount) = parseInputs(data); + + // If the adapter is called using `call` and not `delegatecall` + if (address(this) == self()) { + require( + msg.value == _amount, + Errors.INSUFFICIENT_NATIVE_FUNDS_PASSED + ); + } + + bytes memory logData; + + (tokens, logData) = _stake(_recipient, _amount); + + emit ExecutionEvent(name(), logData); + return tokens; + } + + /** + * @inheritdoc NitroMessageHandler + */ + function handleMessage( + address tokenSent, + uint256 amount, + bytes memory instruction + ) external override onlyNitro nonReentrant { + address recipient = abi.decode(instruction, (address)); + + if (tokenSent != native()) { + withdrawTokens(tokenSent, recipient, amount); + emit OperationFailedRefundEvent(tokenSent, recipient, amount); + return; + } + + try _ankrPool.stakeCerts{value: amount}() { + uint256 returnAmount = withdrawTokens( + _ankrBsc, + recipient, + type(uint256).max + ); + + emit AnkrStakeBscDest(recipient, amount, returnAmount); + } catch { + withdrawTokens(tokenSent, recipient, amount); + emit OperationFailedRefundEvent(tokenSent, recipient, amount); + } + } + + //////////////////////////// ACTION LOGIC //////////////////////////// + + function _stake( + address _recipient, + uint256 _amount + ) internal returns (address[] memory tokens, bytes memory logData) { + _ankrPool.stakeCerts{value: _amount}(); + uint256 returnAmount = withdrawTokens( + _ankrBsc, + _recipient, + type(uint256).max + ); + + tokens = new address[](2); + tokens[0] = native(); + tokens[1] = ankrBsc(); + + logData = abi.encode(_recipient, _amount, returnAmount); + } + + /** + * @dev function to parse input data. + * @param data input data. + */ + function parseInputs( + bytes memory data + ) public pure returns (address, uint256) { + return abi.decode(data, (address, uint256)); + } + + // solhint-disable-next-line no-empty-blocks + receive() external payable {} +} diff --git a/evm/contracts/intent-adapters/liquid-staking/Ankr/AnkrStakeEth.sol b/evm/contracts/intent-adapters/liquid-staking/Ankr/AnkrStakeEth.sol new file mode 100644 index 0000000..3baeea9 --- /dev/null +++ b/evm/contracts/intent-adapters/liquid-staking/Ankr/AnkrStakeEth.sol @@ -0,0 +1,144 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.18; + +import {IAnkrStakeEth} from "./Interfaces.sol"; +import {RouterIntentEoaAdapter, EoaExecutor} from "router-intents/contracts/RouterIntentEoaAdapter.sol"; +import {NitroMessageHandler} from "router-intents/contracts/utils/NitroMessageHandler.sol"; +import {Errors} from "router-intents/contracts/utils/Errors.sol"; +import {IERC20, SafeERC20} from "../../../utils/SafeERC20.sol"; + +/** + * @title AnkrStakeEth + * @author Yashika Goyal + * @notice Staking ETH to receive AnkrETH on Ankr. + * @notice This contract is only for Ethereum chain. + */ +contract AnkrStakeEth is RouterIntentEoaAdapter, NitroMessageHandler { + using SafeERC20 for IERC20; + + address private immutable _ankrEth; + IAnkrStakeEth private immutable _ankrPool; + + event AnkrStakeEthDest( + address _recipient, + uint256 _amount, + uint256 _returnAmount + ); + + constructor( + address __native, + address __wnative, + address __owner, + address __assetForwarder, + address __dexspan, + address __ankrEth, + address __ankrPool + ) + RouterIntentEoaAdapter(__native, __wnative, __owner) + NitroMessageHandler(__assetForwarder, __dexspan) + { + _ankrEth = __ankrEth; + _ankrPool = IAnkrStakeEth(__ankrPool); + } + + function ankrEth() public view returns (address) { + return _ankrEth; + } + + function ankrPool() public view returns (IAnkrStakeEth) { + return _ankrPool; + } + + function name() public pure override returns (string memory) { + return "AnkrStakeEth"; + } + + /** + * @inheritdoc EoaExecutor + */ + function execute( + address, + address, + bytes calldata data + ) external payable override returns (address[] memory tokens) { + (address _recipient, uint256 _amount) = parseInputs(data); + + // If the adapter is called using `call` and not `delegatecall` + if (address(this) == self()) { + require( + msg.value == _amount, + Errors.INSUFFICIENT_NATIVE_FUNDS_PASSED + ); + } + + bytes memory logData; + + (tokens, logData) = _stake(_recipient, _amount); + + emit ExecutionEvent(name(), logData); + return tokens; + } + + /** + * @inheritdoc NitroMessageHandler + */ + function handleMessage( + address tokenSent, + uint256 amount, + bytes memory instruction + ) external override onlyNitro nonReentrant { + address recipient = abi.decode(instruction, (address)); + + if (tokenSent != native()) { + withdrawTokens(tokenSent, recipient, amount); + emit OperationFailedRefundEvent(tokenSent, recipient, amount); + return; + } + + try _ankrPool.stake{value: amount}() { + uint256 returnAmount = withdrawTokens( + _ankrEth, + recipient, + type(uint256).max + ); + + emit AnkrStakeEthDest(recipient, amount, returnAmount); + } catch { + withdrawTokens(tokenSent, recipient, amount); + emit OperationFailedRefundEvent(tokenSent, recipient, amount); + } + } + + //////////////////////////// ACTION LOGIC //////////////////////////// + + function _stake( + address _recipient, + uint256 _amount + ) internal returns (address[] memory tokens, bytes memory logData) { + _ankrPool.stake{value: _amount}(); + uint256 returnAmount = withdrawTokens( + _ankrEth, + _recipient, + type(uint256).max + ); + + tokens = new address[](2); + tokens[0] = native(); + tokens[1] = ankrEth(); + + logData = abi.encode(_recipient, _amount, returnAmount); + } + + /** + * @dev function to parse input data. + * @param data input data. + */ + function parseInputs( + bytes memory data + ) public pure returns (address, uint256) { + return abi.decode(data, (address, uint256)); + } + + // solhint-disable-next-line no-empty-blocks + receive() external payable {} +} diff --git a/evm/contracts/intent-adapters/liquid-staking/Ankr/AnkrStakeFantom.sol b/evm/contracts/intent-adapters/liquid-staking/Ankr/AnkrStakeFantom.sol new file mode 100644 index 0000000..5a19de5 --- /dev/null +++ b/evm/contracts/intent-adapters/liquid-staking/Ankr/AnkrStakeFantom.sol @@ -0,0 +1,144 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.18; + +import {IAnkrStakeFtm} from "./Interfaces.sol"; +import {RouterIntentEoaAdapter, EoaExecutor} from "router-intents/contracts/RouterIntentEoaAdapter.sol"; +import {NitroMessageHandler} from "router-intents/contracts/utils/NitroMessageHandler.sol"; +import {Errors} from "router-intents/contracts/utils/Errors.sol"; +import {IERC20, SafeERC20} from "../../../utils/SafeERC20.sol"; + +/** + * @title AnkrStakeFantom + * @author Yashika Goyal + * @notice Staking FTM to receive AnkrFTM on Ankr. + * @notice This contract is only for Fantom chain. + */ +contract AnkrStakeFantom is RouterIntentEoaAdapter, NitroMessageHandler { + using SafeERC20 for IERC20; + + address private immutable _ankrFtm; + IAnkrStakeFtm private immutable _ankrPool; + + event AnkrStakeFantomDest( + address _recipient, + uint256 _amount, + uint256 _returnAmount + ); + + constructor( + address __native, + address __wnative, + address __owner, + address __assetForwarder, + address __dexspan, + address __ankrFtm, + address __ankrPool + ) + RouterIntentEoaAdapter(__native, __wnative, __owner) + NitroMessageHandler(__assetForwarder, __dexspan) + { + _ankrFtm = __ankrFtm; + _ankrPool = IAnkrStakeFtm(__ankrPool); + } + + function ankrEth() public view returns (address) { + return _ankrFtm; + } + + function ankrPool() public view returns (IAnkrStakeFtm) { + return _ankrPool; + } + + function name() public pure override returns (string memory) { + return "AnkrStakeFantom"; + } + + /** + * @inheritdoc EoaExecutor + */ + function execute( + address, + address, + bytes calldata data + ) external payable override returns (address[] memory tokens) { + (address _recipient, uint256 _amount) = parseInputs(data); + + // If the adapter is called using `call` and not `delegatecall` + if (address(this) == self()) { + require( + msg.value == _amount, + Errors.INSUFFICIENT_NATIVE_FUNDS_PASSED + ); + } + + bytes memory logData; + + (tokens, logData) = _stake(_recipient, _amount); + + emit ExecutionEvent(name(), logData); + return tokens; + } + + /** + * @inheritdoc NitroMessageHandler + */ + function handleMessage( + address tokenSent, + uint256 amount, + bytes memory instruction + ) external override onlyNitro nonReentrant { + address recipient = abi.decode(instruction, (address)); + + if (tokenSent != native()) { + withdrawTokens(tokenSent, recipient, amount); + emit OperationFailedRefundEvent(tokenSent, recipient, amount); + return; + } + + try _ankrPool.stakeAndClaimCerts{value: amount}() { + uint256 returnAmount = withdrawTokens( + _ankrFtm, + recipient, + type(uint256).max + ); + + emit AnkrStakeFantomDest(recipient, amount, returnAmount); + } catch { + withdrawTokens(tokenSent, recipient, amount); + emit OperationFailedRefundEvent(tokenSent, recipient, amount); + } + } + + //////////////////////////// ACTION LOGIC //////////////////////////// + + function _stake( + address _recipient, + uint256 _amount + ) internal returns (address[] memory tokens, bytes memory logData) { + _ankrPool.stakeAndClaimCerts{value: _amount}(); + uint256 returnAmount = withdrawTokens( + _ankrFtm, + _recipient, + type(uint256).max + ); + + tokens = new address[](2); + tokens[0] = native(); + tokens[1] = ankrEth(); + + logData = abi.encode(_recipient, _amount, returnAmount); + } + + /** + * @dev function to parse input data. + * @param data input data. + */ + function parseInputs( + bytes memory data + ) public pure returns (address, uint256) { + return abi.decode(data, (address, uint256)); + } + + // solhint-disable-next-line no-empty-blocks + receive() external payable {} +} diff --git a/evm/contracts/intent-adapters/liquid-staking/Ankr/AnkrStakeMatic.sol b/evm/contracts/intent-adapters/liquid-staking/Ankr/AnkrStakeMatic.sol new file mode 100644 index 0000000..34f8392 --- /dev/null +++ b/evm/contracts/intent-adapters/liquid-staking/Ankr/AnkrStakeMatic.sol @@ -0,0 +1,150 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.18; + +import {IAnkrStakeMatic} from "./Interfaces.sol"; +import {RouterIntentEoaAdapter, EoaExecutor} from "router-intents/contracts/RouterIntentEoaAdapter.sol"; +import {NitroMessageHandler} from "router-intents/contracts/utils/NitroMessageHandler.sol"; +import {Errors} from "router-intents/contracts/utils/Errors.sol"; +import {IERC20, SafeERC20} from "../../../utils/SafeERC20.sol"; + +/** + * @title AnkrStakeMatic + * @author Yashika Goyal + * @notice Staking MATIC to receive AnkrMATIC on Ankr. + * @notice This contract is only for Ethereum chain. + */ +contract AnkrStakeMatic is RouterIntentEoaAdapter, NitroMessageHandler { + using SafeERC20 for IERC20; + + address private immutable _ankrMatic; + address private immutable _matic; + IAnkrStakeMatic private immutable _ankrPool; + + event AnkrStakeMaticDest( + address _recipient, + uint256 _amount, + uint256 _returnAmount + ); + + constructor( + address __native, + address __wnative, + address __owner, + address __assetForwarder, + address __dexspan, + address __ankrMatic, + address __matic, + address __ankrPool + ) + RouterIntentEoaAdapter(__native, __wnative, __owner) + NitroMessageHandler(__assetForwarder, __dexspan) + { + _ankrMatic = __ankrMatic; + _matic = __matic; + _ankrPool = IAnkrStakeMatic(__ankrPool); + } + + function ankrMatic() public view returns (address) { + return _ankrMatic; + } + + function matic() public view returns (address) { + return _matic; + } + + function ankrPool() public view returns (IAnkrStakeMatic) { + return _ankrPool; + } + + function name() public pure override returns (string memory) { + return "AnkrStakeMatic"; + } + + /** + * @inheritdoc EoaExecutor + */ + function execute( + address, + address, + bytes calldata data + ) external payable override returns (address[] memory tokens) { + (address _recipient, uint256 _amount) = parseInputs(data); + + // If the adapter is called using `call` and not `delegatecall` + if (address(this) == self()) { + IERC20(_matic).safeTransferFrom(msg.sender, self(), _amount); + } + + bytes memory logData; + + (tokens, logData) = _stake(_recipient, _amount); + + emit ExecutionEvent(name(), logData); + return tokens; + } + + /** + * @inheritdoc NitroMessageHandler + */ + function handleMessage( + address tokenSent, + uint256 amount, + bytes memory instruction + ) external override onlyNitro nonReentrant { + address recipient = abi.decode(instruction, (address)); + + if (tokenSent != matic()) { + withdrawTokens(tokenSent, recipient, amount); + emit OperationFailedRefundEvent(tokenSent, recipient, amount); + return; + } + + IERC20(_matic).safeIncreaseAllowance(address(_ankrPool), amount); + try _ankrPool.stakeAndClaimCerts(amount) { + uint256 returnAmount = withdrawTokens( + _ankrMatic, + recipient, + type(uint256).max + ); + + emit AnkrStakeMaticDest(recipient, amount, returnAmount); + } catch { + withdrawTokens(tokenSent, recipient, amount); + emit OperationFailedRefundEvent(tokenSent, recipient, amount); + } + } + + //////////////////////////// ACTION LOGIC //////////////////////////// + + function _stake( + address _recipient, + uint256 _amount + ) internal returns (address[] memory tokens, bytes memory logData) { + IERC20(_matic).safeIncreaseAllowance(address(_ankrPool), _amount); + _ankrPool.stakeAndClaimCerts(_amount); + uint256 returnAmount = withdrawTokens( + _ankrMatic, + _recipient, + type(uint256).max + ); + + tokens = new address[](2); + tokens[0] = native(); + tokens[1] = ankrMatic(); + + logData = abi.encode(_recipient, _amount, returnAmount); + } + + /** + * @dev function to parse input data. + * @param data input data. + */ + function parseInputs( + bytes memory data + ) public pure returns (address, uint256) { + return abi.decode(data, (address, uint256)); + } + + // solhint-disable-next-line no-empty-blocks + receive() external payable {} +} diff --git a/evm/contracts/intent-adapters/liquid-staking/Ankr/AnkrStakePolygon.sol b/evm/contracts/intent-adapters/liquid-staking/Ankr/AnkrStakePolygon.sol new file mode 100644 index 0000000..3cb356c --- /dev/null +++ b/evm/contracts/intent-adapters/liquid-staking/Ankr/AnkrStakePolygon.sol @@ -0,0 +1,129 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.18; + +import {IAnkrStakePolygon} from "./Interfaces.sol"; +import {RouterIntentEoaAdapter, EoaExecutor} from "router-intents/contracts/RouterIntentEoaAdapter.sol"; +import {NitroMessageHandler} from "router-intents/contracts/utils/NitroMessageHandler.sol"; +import {Errors} from "router-intents/contracts/utils/Errors.sol"; +import {IERC20, SafeERC20} from "../../../utils/SafeERC20.sol"; + +/** + * @title AnkrStakePolygon + * @author Yashika Goyal + * @notice Staking MATIC to receive AnkrMatic on Ankr. + * @notice This contract is only for Polygon chain. + */ +contract AnkrStakePolygon is RouterIntentEoaAdapter, NitroMessageHandler { + using SafeERC20 for IERC20; + + address private immutable _ankrMatic; + IAnkrStakePolygon private immutable _ankrPool; + + event AnkrStakePolygonDest(address _recipient, uint256 _amount); + + constructor( + address __native, + address __wnative, + address __owner, + address __assetForwarder, + address __dexspan, + address __ankrMatic, + address __ankrPool + ) + RouterIntentEoaAdapter(__native, __wnative, __owner) + NitroMessageHandler(__assetForwarder, __dexspan) + { + _ankrMatic = __ankrMatic; + _ankrPool = IAnkrStakePolygon(__ankrPool); + } + + function ankrMatic() public view returns (address) { + return _ankrMatic; + } + + function ankrPool() public view returns (IAnkrStakePolygon) { + return _ankrPool; + } + + function name() public pure override returns (string memory) { + return "AnkrStakePolygon"; + } + + /** + * @inheritdoc EoaExecutor + */ + function execute( + address, + address, + bytes calldata data + ) external payable override returns (address[] memory tokens) { + (address _recipient, uint256 _amount) = parseInputs(data); + + // If the adapter is called using `call` and not `delegatecall` + if (address(this) == self()) { + require( + msg.value == _amount, + Errors.INSUFFICIENT_NATIVE_FUNDS_PASSED + ); + } + + bytes memory logData; + + (tokens, logData) = _stake(_recipient, _amount); + + emit ExecutionEvent(name(), logData); + return tokens; + } + + /** + * @inheritdoc NitroMessageHandler + */ + function handleMessage( + address tokenSent, + uint256 amount, + bytes memory instruction + ) external override onlyNitro nonReentrant { + address recipient = abi.decode(instruction, (address)); + + if (tokenSent != native()) { + withdrawTokens(tokenSent, recipient, amount); + emit OperationFailedRefundEvent(tokenSent, recipient, amount); + return; + } + + try _ankrPool.swapEth{value: amount}(true, amount, recipient) { + emit AnkrStakePolygonDest(recipient, amount); + } catch { + withdrawTokens(tokenSent, recipient, amount); + emit OperationFailedRefundEvent(tokenSent, recipient, amount); + } + } + + //////////////////////////// ACTION LOGIC //////////////////////////// + + function _stake( + address _recipient, + uint256 _amount + ) internal returns (address[] memory tokens, bytes memory logData) { + _ankrPool.swapEth{value: _amount}(true, _amount, _recipient); + + tokens = new address[](2); + tokens[0] = native(); + tokens[1] = ankrMatic(); + + logData = abi.encode(_recipient, _amount); + } + + /** + * @dev function to parse input data. + * @param data input data. + */ + function parseInputs( + bytes memory data + ) public pure returns (address, uint256) { + return abi.decode(data, (address, uint256)); + } + + // solhint-disable-next-line no-empty-blocks + receive() external payable {} +} diff --git a/evm/contracts/intent-adapters/liquid-staking/Ankr/Interfaces.sol b/evm/contracts/intent-adapters/liquid-staking/Ankr/Interfaces.sol new file mode 100644 index 0000000..02ec78b --- /dev/null +++ b/evm/contracts/intent-adapters/liquid-staking/Ankr/Interfaces.sol @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.18; + +interface IAnkrStakeAvax { + function stakeAndClaimCerts() external payable; +} + +interface IAnkrStakeBsc { + function stakeCerts() external payable; +} + +interface IAnkrStakeEth { + function stake() external payable; +} + +interface IAnkrStakeMatic { + function stakeAndClaimCerts(uint256 amount) external; +} + +interface IAnkrStakeFtm { + function stakeAndClaimCerts() external payable; +} + +interface IAnkrStakePolygon { + function swapEth( + bool nativeToCeros, + uint256 amountIn, + address receiver + ) external payable returns (uint256 amountOut); +} diff --git a/evm/contracts/intent-adapters/liquid-staking/Benqi/BenqiStakeAvax.sol b/evm/contracts/intent-adapters/liquid-staking/Benqi/BenqiStakeAvax.sol new file mode 100644 index 0000000..ae1271d --- /dev/null +++ b/evm/contracts/intent-adapters/liquid-staking/Benqi/BenqiStakeAvax.sol @@ -0,0 +1,137 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.18; + +import {IBenqiStakeAvax} from "./Interfaces.sol"; +import {RouterIntentEoaAdapter, EoaExecutor} from "router-intents/contracts/RouterIntentEoaAdapter.sol"; +import {NitroMessageHandler} from "router-intents/contracts/utils/NitroMessageHandler.sol"; +import {Errors} from "router-intents/contracts/utils/Errors.sol"; +import {IERC20, SafeERC20} from "../../../utils/SafeERC20.sol"; + +/** + * @title BenqiStakeAvax + * @author Yashika Goyal + * @notice Staking AVAX to receive BenqiAVAX on Benqi. + * @notice This contract is only for Avalanche chain. + */ +contract BenqiStakeAvax is RouterIntentEoaAdapter, NitroMessageHandler { + using SafeERC20 for IERC20; + + address private immutable _benqiSAvax; + + event BenqiStakeAvaxDest( + address _recipient, + uint256 _amount, + uint256 _receivedSAvax + ); + + constructor( + address __native, + address __wnative, + address __owner, + address __assetForwarder, + address __dexspan, + address __benqiSAvax + ) + RouterIntentEoaAdapter(__native, __wnative, __owner) + NitroMessageHandler(__assetForwarder, __dexspan) + { + _benqiSAvax = __benqiSAvax; + } + + function benqiSAvax() public view returns (address) { + return _benqiSAvax; + } + + function name() public pure override returns (string memory) { + return "BenqiStakeAvax"; + } + + /** + * @inheritdoc EoaExecutor + */ + function execute( + address, + address, + bytes calldata data + ) external payable override returns (address[] memory tokens) { + (address _recipient, uint256 _amount) = parseInputs(data); + + // If the adapter is called using `call` and not `delegatecall` + if (address(this) == self()) { + require( + msg.value == _amount, + Errors.INSUFFICIENT_NATIVE_FUNDS_PASSED + ); + } + + bytes memory logData; + + (tokens, logData) = _stake(_recipient, _amount); + + emit ExecutionEvent(name(), logData); + return tokens; + } + + /** + * @inheritdoc NitroMessageHandler + */ + function handleMessage( + address tokenSent, + uint256 amount, + bytes memory instruction + ) external override onlyNitro nonReentrant { + address recipient = abi.decode(instruction, (address)); + + if (tokenSent != native()) { + withdrawTokens(tokenSent, recipient, amount); + emit OperationFailedRefundEvent(tokenSent, recipient, amount); + return; + } + + try IBenqiStakeAvax(_benqiSAvax).submit{value: amount}() { + uint256 _receivedSAvax = withdrawTokens( + _benqiSAvax, + recipient, + type(uint256).max + ); + + emit BenqiStakeAvaxDest(recipient, amount, _receivedSAvax); + } catch { + withdrawTokens(tokenSent, recipient, amount); + emit OperationFailedRefundEvent(tokenSent, recipient, amount); + } + } + + //////////////////////////// ACTION LOGIC //////////////////////////// + + function _stake( + address _recipient, + uint256 _amount + ) internal returns (address[] memory tokens, bytes memory logData) { + IBenqiStakeAvax(_benqiSAvax).submit{value: _amount}(); + uint256 _receivedSAvax = withdrawTokens( + _benqiSAvax, + _recipient, + type(uint256).max + ); + + tokens = new address[](2); + tokens[0] = native(); + tokens[1] = benqiSAvax(); + + logData = abi.encode(_recipient, _amount, _receivedSAvax); + } + + /** + * @dev function to parse input data. + * @param data input data. + */ + function parseInputs( + bytes memory data + ) public pure returns (address, uint256) { + return abi.decode(data, (address, uint256)); + } + + // solhint-disable-next-line no-empty-blocks + receive() external payable {} +} diff --git a/evm/contracts/intent-adapters/liquid-staking/Benqi/Interfaces.sol b/evm/contracts/intent-adapters/liquid-staking/Benqi/Interfaces.sol new file mode 100644 index 0000000..85b8793 --- /dev/null +++ b/evm/contracts/intent-adapters/liquid-staking/Benqi/Interfaces.sol @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.18; + +interface IBenqiStakeAvax { + function submit() external payable returns (uint); +} diff --git a/evm/contracts/intent-adapters/liquid-staking/Frax/FraxStakeEth.sol b/evm/contracts/intent-adapters/liquid-staking/Frax/FraxStakeEth.sol new file mode 100644 index 0000000..dae6df3 --- /dev/null +++ b/evm/contracts/intent-adapters/liquid-staking/Frax/FraxStakeEth.sol @@ -0,0 +1,184 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.18; + +import {IFraxEthMinter} from "./Interfaces.sol"; +import {RouterIntentEoaAdapter, EoaExecutor} from "router-intents/contracts/RouterIntentEoaAdapter.sol"; +import {NitroMessageHandler} from "router-intents/contracts/utils/NitroMessageHandler.sol"; +import {Errors} from "router-intents/contracts/utils/Errors.sol"; +import {IERC20, SafeERC20} from "../../../utils/SafeERC20.sol"; + +/** + * @title FraxStakeEth + * @author Yashika Goyal + * @notice Staking ETH to receive fraxETH or stakedFraxETH on Frax. + * @notice This contract is only for Ethereum chain. + */ +contract FraxStakeEth is RouterIntentEoaAdapter, NitroMessageHandler { + using SafeERC20 for IERC20; + + IFraxEthMinter private immutable _fraxEthMinter; + address private immutable _fraxEth; + address private immutable _stakedFraxEth; + + event FraxStakeEthDest( + address _recipient, + address token, + uint256 _returnAmount + ); + + error InvalidTxType(); + + constructor( + address __native, + address __wnative, + address __owner, + address __assetForwarder, + address __dexspan, + address __fraxEth, + address __stakedFraxEth, + address __fraxEthMinter + ) + RouterIntentEoaAdapter(__native, __wnative, __owner) + NitroMessageHandler(__assetForwarder, __dexspan) + { + _fraxEth = __fraxEth; + _stakedFraxEth = __stakedFraxEth; + _fraxEthMinter = IFraxEthMinter(__fraxEthMinter); + } + + function fraxEth() public view returns (address) { + return _fraxEth; + } + + function stakedFraxEth() public view returns (address) { + return _stakedFraxEth; + } + + function fraxEthMinter() public view returns (IFraxEthMinter) { + return _fraxEthMinter; + } + + function name() public pure override returns (string memory) { + return "FraxStakeEth"; + } + + /** + * @inheritdoc EoaExecutor + */ + function execute( + address, + address, + bytes calldata data + ) external payable override returns (address[] memory tokens) { + (address _recipient, uint256 _amount, uint256 _txType) = parseInputs( + data + ); + + // If the adapter is called using `call` and not `delegatecall` + if (address(this) == self()) { + require( + msg.value == _amount, + Errors.INSUFFICIENT_NATIVE_FUNDS_PASSED + ); + } + + bytes memory logData; + + (tokens, logData) = _stake(_recipient, _amount, _txType); + + emit ExecutionEvent(name(), logData); + return tokens; + } + + /** + * @inheritdoc NitroMessageHandler + */ + function handleMessage( + address tokenSent, + uint256 amount, + bytes memory instruction + ) external override onlyNitro nonReentrant { + (address recipient, uint256 txType) = abi.decode( + instruction, + (address, uint256) + ); + + if (tokenSent != native()) { + withdrawTokens(tokenSent, recipient, amount); + emit OperationFailedRefundEvent(tokenSent, recipient, amount); + return; + } + + if (txType == 1) { + try _fraxEthMinter.submitAndGive{value: amount}(recipient) { + emit FraxStakeEthDest(recipient, _fraxEth, amount); + } catch { + withdrawTokens(tokenSent, recipient, amount); + emit OperationFailedRefundEvent(tokenSent, recipient, amount); + } + } else if (txType == 2) { + try + _fraxEthMinter.submitAndDeposit{value: amount}(recipient) + returns (uint256 _receivedSFrxEth) { + emit FraxStakeEthDest( + recipient, + _stakedFraxEth, + _receivedSFrxEth + ); + } catch { + withdrawTokens(tokenSent, recipient, amount); + emit OperationFailedRefundEvent(tokenSent, recipient, amount); + } + } else { + revert InvalidTxType(); + } + } + + //////////////////////////// ACTION LOGIC //////////////////////////// + + /** + * @notice function to stake funds on Frax ETH Pool. + * @param _recipient address of the recipient. + * @param _amount amount to be staked. + * @param _txType Type of transaction. + * 1 for staking Eth to get frxEth. + * 2 for staking Eth and then staking frxEth to get sFrxEth. + */ + + function _stake( + address _recipient, + uint256 _amount, + uint256 _txType + ) internal returns (address[] memory tokens, bytes memory logData) { + if (_txType == 1) { + _fraxEthMinter.submitAndGive{value: _amount}(_recipient); + tokens = new address[](2); + tokens[0] = native(); + tokens[1] = fraxEth(); + logData = abi.encode(_recipient, _fraxEth, _amount); + } else if (_txType == 2) { + uint256 _receivedSFrxEth = _fraxEthMinter.submitAndDeposit{ + value: _amount + }(_recipient); + tokens = new address[](2); + tokens[0] = native(); + tokens[1] = stakedFraxEth(); + logData = abi.encode(_recipient, _stakedFraxEth, _receivedSFrxEth); + } else { + revert InvalidTxType(); + } + } + + /** + * @dev function to parse input data. + * @param data input data. + */ + function parseInputs( + bytes memory data + ) public pure returns (address, uint256, uint256) { + return abi.decode(data, (address, uint256, uint256)); + } + + // solhint-disable-next-line no-empty-blocks + receive() external payable {} +} diff --git a/evm/contracts/intent-adapters/liquid-staking/Frax/Interfaces.sol b/evm/contracts/intent-adapters/liquid-staking/Frax/Interfaces.sol new file mode 100644 index 0000000..0fbc0d2 --- /dev/null +++ b/evm/contracts/intent-adapters/liquid-staking/Frax/Interfaces.sol @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.18; + +interface IFraxEthMinter { + function submitAndDeposit( + address recipient + ) external payable returns (uint256 shares); + + function submitAndGive(address recipient) external payable; +} diff --git a/evm/contracts/intent-adapters/liquid-staking/Lido/Interfaces.sol b/evm/contracts/intent-adapters/liquid-staking/Lido/Interfaces.sol new file mode 100644 index 0000000..c7a0291 --- /dev/null +++ b/evm/contracts/intent-adapters/liquid-staking/Lido/Interfaces.sol @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.18; + +interface ILidoStakeEth { + function submit(address _referral) external payable returns (uint256); +} + +interface ILidoStakeMatic { + function submit( + uint256 _amount, + address _referral + ) external returns (uint256); +} diff --git a/evm/contracts/intent-adapters/liquid-staking/Lido/LidoStakeEth.sol b/evm/contracts/intent-adapters/liquid-staking/Lido/LidoStakeEth.sol new file mode 100644 index 0000000..52ae951 --- /dev/null +++ b/evm/contracts/intent-adapters/liquid-staking/Lido/LidoStakeEth.sol @@ -0,0 +1,144 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.18; + +import {ILidoStakeEth} from "./Interfaces.sol"; +import {RouterIntentEoaAdapter, EoaExecutor} from "router-intents/contracts/RouterIntentEoaAdapter.sol"; +import {NitroMessageHandler} from "router-intents/contracts/utils/NitroMessageHandler.sol"; +import {Errors} from "router-intents/contracts/utils/Errors.sol"; +import {IERC20, SafeERC20} from "../../../utils/SafeERC20.sol"; + +/** + * @title LidoStakeEth + * @author Yashika Goyal + * @notice Staking ETH to receive StEth on Lido. + * @notice This contract is only for Ethereum chain. + */ +contract LidoStakeEth is RouterIntentEoaAdapter, NitroMessageHandler { + using SafeERC20 for IERC20; + + address private immutable _lidoStETH; + address private immutable _referralId; + + event LidoStakeEthDest( + address _recipient, + uint256 _amount, + uint256 _receivedStEth + ); + + constructor( + address __native, + address __wnative, + address __owner, + address __assetForwarder, + address __dexspan, + address __lidoStETH, + address __referralId + ) + RouterIntentEoaAdapter(__native, __wnative, __owner) + NitroMessageHandler(__assetForwarder, __dexspan) + { + _lidoStETH = __lidoStETH; + _referralId = __referralId; + } + + function lidoStEth() public view returns (address) { + return _lidoStETH; + } + + function referralId() public view returns (address) { + return _referralId; + } + + function name() public pure override returns (string memory) { + return "LidoStakeEth"; + } + + /** + * @inheritdoc EoaExecutor + */ + function execute( + address, + address, + bytes calldata data + ) external payable override returns (address[] memory tokens) { + (address _recipient, uint256 _amount) = parseInputs(data); + + // If the adapter is called using `call` and not `delegatecall` + if (address(this) == self()) { + require( + msg.value == _amount, + Errors.INSUFFICIENT_NATIVE_FUNDS_PASSED + ); + } + + bytes memory logData; + + (tokens, logData) = _stake(_recipient, _amount); + + emit ExecutionEvent(name(), logData); + return tokens; + } + + /** + * @inheritdoc NitroMessageHandler + */ + function handleMessage( + address tokenSent, + uint256 amount, + bytes memory instruction + ) external override onlyNitro nonReentrant { + address recipient = abi.decode(instruction, (address)); + + if (tokenSent != native()) { + withdrawTokens(tokenSent, recipient, amount); + emit OperationFailedRefundEvent(tokenSent, recipient, amount); + return; + } + + try ILidoStakeEth(_lidoStETH).submit{value: amount}(_referralId) { + uint256 _receivedStEth = withdrawTokens( + _lidoStETH, + recipient, + type(uint256).max + ); + + emit LidoStakeEthDest(recipient, amount, _receivedStEth); + } catch { + withdrawTokens(tokenSent, recipient, amount); + emit OperationFailedRefundEvent(tokenSent, recipient, amount); + } + } + + //////////////////////////// ACTION LOGIC //////////////////////////// + + function _stake( + address _recipient, + uint256 _amount + ) internal returns (address[] memory tokens, bytes memory logData) { + ILidoStakeEth(_lidoStETH).submit{value: _amount}(_referralId); + uint256 _receivedStEth = withdrawTokens( + _lidoStETH, + _recipient, + type(uint256).max + ); + + tokens = new address[](2); + tokens[0] = native(); + tokens[1] = lidoStEth(); + + logData = abi.encode(_recipient, _amount, _receivedStEth); + } + + /** + * @dev function to parse input data. + * @param data input data. + */ + function parseInputs( + bytes memory data + ) public pure returns (address, uint256) { + return abi.decode(data, (address, uint256)); + } + + // solhint-disable-next-line no-empty-blocks + receive() external payable {} +} diff --git a/evm/contracts/intent-adapters/liquid-staking/Lido/LidoStakeMatic.sol b/evm/contracts/intent-adapters/liquid-staking/Lido/LidoStakeMatic.sol new file mode 100644 index 0000000..c5e1f88 --- /dev/null +++ b/evm/contracts/intent-adapters/liquid-staking/Lido/LidoStakeMatic.sol @@ -0,0 +1,151 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.18; + +import {ILidoStakeMatic} from "./Interfaces.sol"; +import {RouterIntentEoaAdapter, EoaExecutor} from "router-intents/contracts/RouterIntentEoaAdapter.sol"; +import {NitroMessageHandler} from "router-intents/contracts/utils/NitroMessageHandler.sol"; +import {Errors} from "router-intents/contracts/utils/Errors.sol"; +import {IERC20, SafeERC20} from "../../../utils/SafeERC20.sol"; + +/** + * @title LidoStakeMatic + * @author Yashika Goyal + * @notice Staking MATIC to receive StMatic on Lido. + * @notice This contract is for chains other than Polygon where liquid staking for Matic + * is supported by Lido + */ +contract LidoStakeMatic is RouterIntentEoaAdapter, NitroMessageHandler { + using SafeERC20 for IERC20; + + address private immutable _lidoStMatic; + address private immutable _matic; + address private immutable _referralId; + + event LidoStakeMaticDest( + address _recipient, + uint256 _amount, + uint256 _receivedStMatic + ); + + constructor( + address __native, + address __wnative, + address __owner, + address __assetForwarder, + address __dexspan, + address __lidoStMatic, + address __matic, + address __referralId + ) + RouterIntentEoaAdapter(__native, __wnative, __owner) + NitroMessageHandler(__assetForwarder, __dexspan) + { + _lidoStMatic = __lidoStMatic; + _matic = __matic; + _referralId = __referralId; + } + + function lidoStMatic() public view returns (address) { + return _lidoStMatic; + } + + function matic() public view returns (address) { + return _matic; + } + + function referralId() public view returns (address) { + return _referralId; + } + + function name() public pure override returns (string memory) { + return "LidoStakeMatic"; + } + + /** + * @inheritdoc EoaExecutor + */ + function execute( + address, + address, + bytes calldata data + ) external payable override returns (address[] memory tokens) { + (address _recipient, uint256 _amount) = parseInputs(data); + + // If the adapter is called using `call` and not `delegatecall` + if (address(this) == self()) { + IERC20(_matic).safeTransferFrom(msg.sender, self(), _amount); + } + + bytes memory logData; + + (tokens, logData) = _stake(_recipient, _amount); + + emit ExecutionEvent(name(), logData); + return tokens; + } + + /** + * @inheritdoc NitroMessageHandler + */ + function handleMessage( + address tokenSent, + uint256 amount, + bytes memory instruction + ) external override onlyNitro nonReentrant { + address recipient = abi.decode(instruction, (address)); + + if (tokenSent != matic()) { + withdrawTokens(tokenSent, recipient, amount); + emit OperationFailedRefundEvent(tokenSent, recipient, amount); + return; + } + + IERC20(_matic).safeIncreaseAllowance(_lidoStMatic, amount); + try ILidoStakeMatic(_lidoStMatic).submit(amount, _referralId) { + uint256 _receivedStMatic = withdrawTokens( + _lidoStMatic, + recipient, + type(uint256).max + ); + + emit LidoStakeMaticDest(recipient, amount, _receivedStMatic); + } catch { + withdrawTokens(tokenSent, recipient, amount); + emit OperationFailedRefundEvent(tokenSent, recipient, amount); + } + } + + //////////////////////////// ACTION LOGIC //////////////////////////// + + function _stake( + address _recipient, + uint256 _amount + ) internal returns (address[] memory tokens, bytes memory logData) { + IERC20(_matic).safeIncreaseAllowance(_lidoStMatic, _amount); + ILidoStakeMatic(_lidoStMatic).submit(_amount, _referralId); + uint256 _receivedStMatic = withdrawTokens( + _lidoStMatic, + _recipient, + type(uint256).max + ); + + tokens = new address[](2); + tokens[0] = native(); + tokens[1] = lidoStMatic(); + + logData = abi.encode(_recipient, _amount, _receivedStMatic); + } + + /** + * @dev function to parse input data. + * @param data input data. + */ + function parseInputs( + bytes memory data + ) public pure returns (address, uint256) { + return abi.decode(data, (address, uint256)); + } + + // solhint-disable-next-line no-empty-blocks + receive() external payable {} +} diff --git a/evm/contracts/intent-adapters/liquid-staking/Metapool/Interfaces.sol b/evm/contracts/intent-adapters/liquid-staking/Metapool/Interfaces.sol new file mode 100644 index 0000000..68b013e --- /dev/null +++ b/evm/contracts/intent-adapters/liquid-staking/Metapool/Interfaces.sol @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.18; + +interface IMetaPoolStakeEth { + function depositETH(address _receiver) external payable returns (uint256); +} diff --git a/evm/contracts/intent-adapters/liquid-staking/Metapool/MetaPoolStakeEth.sol b/evm/contracts/intent-adapters/liquid-staking/Metapool/MetaPoolStakeEth.sol new file mode 100644 index 0000000..f7deb50 --- /dev/null +++ b/evm/contracts/intent-adapters/liquid-staking/Metapool/MetaPoolStakeEth.sol @@ -0,0 +1,137 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.18; + +import {IMetaPoolStakeEth} from "./Interfaces.sol"; +import {RouterIntentEoaAdapter, EoaExecutor} from "router-intents/contracts/RouterIntentEoaAdapter.sol"; +import {NitroMessageHandler} from "router-intents/contracts/utils/NitroMessageHandler.sol"; +import {Errors} from "router-intents/contracts/utils/Errors.sol"; +import {IERC20, SafeERC20} from "../../../utils/SafeERC20.sol"; + +/** + * @title MetaPoolStakeEth + * @author Yashika Goyal + * @notice Staking ETH to receive mpETH on MetaPool. + * @notice This contract is only for Ethereum chain. + */ +contract MetaPoolStakeEth is RouterIntentEoaAdapter, NitroMessageHandler { + using SafeERC20 for IERC20; + + address private immutable _mpEth; + IMetaPoolStakeEth private immutable _metaPoolPool; + + event MetaPoolStakeEthDest( + address _recipient, + uint256 _amount, + uint256 _returnAmount + ); + + constructor( + address __native, + address __wnative, + address __owner, + address __assetForwarder, + address __dexspan, + address __mpEth, + address __metaPoolPool + ) + RouterIntentEoaAdapter(__native, __wnative, __owner) + NitroMessageHandler(__assetForwarder, __dexspan) + { + _mpEth = __mpEth; + _metaPoolPool = IMetaPoolStakeEth(__metaPoolPool); + } + + function mpEth() public view returns (address) { + return _mpEth; + } + + function metaPoolPool() public view returns (IMetaPoolStakeEth) { + return _metaPoolPool; + } + + function name() public pure override returns (string memory) { + return "MetaPoolStakeEth"; + } + + /** + * @inheritdoc EoaExecutor + */ + function execute( + address, + address, + bytes calldata data + ) external payable override returns (address[] memory tokens) { + (address _recipient, uint256 _amount) = parseInputs(data); + + // If the adapter is called using `call` and not `delegatecall` + if (address(this) == self()) { + require( + msg.value == _amount, + Errors.INSUFFICIENT_NATIVE_FUNDS_PASSED + ); + } + + bytes memory logData; + + (tokens, logData) = _stake(_recipient, _amount); + + emit ExecutionEvent(name(), logData); + return tokens; + } + + /** + * @inheritdoc NitroMessageHandler + */ + function handleMessage( + address tokenSent, + uint256 amount, + bytes memory instruction + ) external override onlyNitro nonReentrant { + address recipient = abi.decode(instruction, (address)); + + if (tokenSent != native()) { + withdrawTokens(tokenSent, recipient, amount); + emit OperationFailedRefundEvent(tokenSent, recipient, amount); + return; + } + + try _metaPoolPool.depositETH{value: amount}(recipient) returns ( + uint256 returnAmount + ) { + emit MetaPoolStakeEthDest(recipient, amount, returnAmount); + } catch { + withdrawTokens(tokenSent, recipient, amount); + emit OperationFailedRefundEvent(tokenSent, recipient, amount); + } + } + + //////////////////////////// ACTION LOGIC //////////////////////////// + + function _stake( + address _recipient, + uint256 _amount + ) internal returns (address[] memory tokens, bytes memory logData) { + uint256 _returnAmount = _metaPoolPool.depositETH{value: _amount}( + _recipient + ); + + tokens = new address[](2); + tokens[0] = native(); + tokens[1] = mpEth(); + + logData = abi.encode(_recipient, _amount, _returnAmount); + } + + /** + * @dev function to parse input data. + * @param data input data. + */ + function parseInputs( + bytes memory data + ) public pure returns (address, uint256) { + return abi.decode(data, (address, uint256)); + } + + // solhint-disable-next-line no-empty-blocks + receive() external payable {} +} diff --git a/evm/contracts/intent-adapters/liquid-staking/Origin/Interfaces.sol b/evm/contracts/intent-adapters/liquid-staking/Origin/Interfaces.sol new file mode 100644 index 0000000..cddec24 --- /dev/null +++ b/evm/contracts/intent-adapters/liquid-staking/Origin/Interfaces.sol @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.18; + +interface IOriginStakeEth { + function deposit() external payable returns (uint256); +} diff --git a/evm/contracts/intent-adapters/liquid-staking/Origin/OriginStakeEth.sol b/evm/contracts/intent-adapters/liquid-staking/Origin/OriginStakeEth.sol new file mode 100644 index 0000000..1cc5128 --- /dev/null +++ b/evm/contracts/intent-adapters/liquid-staking/Origin/OriginStakeEth.sol @@ -0,0 +1,144 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.18; + +import {IOriginStakeEth} from "./Interfaces.sol"; +import {RouterIntentEoaAdapter, EoaExecutor} from "router-intents/contracts/RouterIntentEoaAdapter.sol"; +import {NitroMessageHandler} from "router-intents/contracts/utils/NitroMessageHandler.sol"; +import {Errors} from "router-intents/contracts/utils/Errors.sol"; +import {IERC20, SafeERC20} from "../../../utils/SafeERC20.sol"; + +/** + * @title OriginStakeEth + * @author Yashika Goyal + * @notice Staking ETH to receive OETH on Origin. + * @notice This contract is only for Ethereum chain. + */ +contract OriginStakeEth is RouterIntentEoaAdapter, NitroMessageHandler { + using SafeERC20 for IERC20; + + IOriginStakeEth private immutable _oETHZapper; + address private immutable _oETH; + + event OriginStakeEthDest( + address _recipient, + uint256 _amount, + uint256 _receivedOEth + ); + + constructor( + address __native, + address __wnative, + address __owner, + address __assetForwarder, + address __dexspan, + address __oETH, + address __oETHZapper + ) + RouterIntentEoaAdapter(__native, __wnative, __owner) + NitroMessageHandler(__assetForwarder, __dexspan) + { + _oETHZapper = IOriginStakeEth(__oETHZapper); + _oETH = __oETH; + } + + function oEth() public view returns (address) { + return _oETH; + } + + function originPool() public view returns (IOriginStakeEth) { + return _oETHZapper; + } + + function name() public pure override returns (string memory) { + return "OriginStakeEth"; + } + + /** + * @inheritdoc EoaExecutor + */ + function execute( + address, + address, + bytes calldata data + ) external payable override returns (address[] memory tokens) { + (address _recipient, uint256 _amount) = parseInputs(data); + + // If the adapter is called using `call` and not `delegatecall` + if (address(this) == self()) { + require( + msg.value == _amount, + Errors.INSUFFICIENT_NATIVE_FUNDS_PASSED + ); + } + + bytes memory logData; + + (tokens, logData) = _stake(_recipient, _amount); + + emit ExecutionEvent(name(), logData); + return tokens; + } + + /** + * @inheritdoc NitroMessageHandler + */ + function handleMessage( + address tokenSent, + uint256 amount, + bytes memory instruction + ) external override onlyNitro nonReentrant { + address recipient = abi.decode(instruction, (address)); + + if (tokenSent != native()) { + withdrawTokens(tokenSent, recipient, amount); + emit OperationFailedRefundEvent(tokenSent, recipient, amount); + return; + } + + try _oETHZapper.deposit{value: amount}() { + uint256 _receivedOEth = withdrawTokens( + _oETH, + recipient, + type(uint256).max + ); + + emit OriginStakeEthDest(recipient, amount, _receivedOEth); + } catch { + withdrawTokens(tokenSent, recipient, amount); + emit OperationFailedRefundEvent(tokenSent, recipient, amount); + } + } + + //////////////////////////// ACTION LOGIC //////////////////////////// + + function _stake( + address _recipient, + uint256 _amount + ) internal returns (address[] memory tokens, bytes memory logData) { + _oETHZapper.deposit{value: _amount}(); + uint256 _receivedOEth = withdrawTokens( + _oETH, + _recipient, + type(uint256).max + ); + + tokens = new address[](2); + tokens[0] = native(); + tokens[1] = oEth(); + + logData = abi.encode(_recipient, _amount, _receivedOEth); + } + + /** + * @dev function to parse input data. + * @param data input data. + */ + function parseInputs( + bytes memory data + ) public pure returns (address, uint256) { + return abi.decode(data, (address, uint256)); + } + + // solhint-disable-next-line no-empty-blocks + receive() external payable {} +} diff --git a/evm/contracts/intent-adapters/liquid-staking/RocketPool/Interfaces.sol b/evm/contracts/intent-adapters/liquid-staking/RocketPool/Interfaces.sol new file mode 100644 index 0000000..decec54 --- /dev/null +++ b/evm/contracts/intent-adapters/liquid-staking/RocketPool/Interfaces.sol @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.18; + +interface IRocketDepositPool { + function deposit() external payable; +} diff --git a/evm/contracts/intent-adapters/liquid-staking/RocketPool/RPStakeEth.sol b/evm/contracts/intent-adapters/liquid-staking/RocketPool/RPStakeEth.sol new file mode 100644 index 0000000..7d07903 --- /dev/null +++ b/evm/contracts/intent-adapters/liquid-staking/RocketPool/RPStakeEth.sol @@ -0,0 +1,143 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.18; + +import {IRocketDepositPool} from "./Interfaces.sol"; +import {RouterIntentEoaAdapter, EoaExecutor} from "router-intents/contracts/RouterIntentEoaAdapter.sol"; +import {NitroMessageHandler} from "router-intents/contracts/utils/NitroMessageHandler.sol"; +import {Errors} from "router-intents/contracts/utils/Errors.sol"; +import {IERC20, SafeERC20} from "../../../utils/SafeERC20.sol"; + +/** + * @title RPStakeEth + * @author Yashika Goyal + * @notice Staking ETH to receive rETH on RocketPool. + * @notice This contract is only for Ethereum chain. + */ +contract RPStakeEth is RouterIntentEoaAdapter, NitroMessageHandler { + using SafeERC20 for IERC20; + + IRocketDepositPool private immutable _rocketDepositPool; + address private immutable _rEth; + + event RPStakeEthDest( + address _recipient, + uint256 _amount, + uint256 _receivedREth + ); + + constructor( + address __native, + address __wnative, + address __owner, + address __assetForwarder, + address __dexspan, + address __rEth, + address __rocketDepositPool + ) + RouterIntentEoaAdapter(__native, __wnative, __owner) + NitroMessageHandler(__assetForwarder, __dexspan) + { + _rEth = __rEth; + _rocketDepositPool = IRocketDepositPool(__rocketDepositPool); + } + + function rEth() public view returns (address) { + return _rEth; + } + + function rocketDepositPool() public view returns (IRocketDepositPool) { + return _rocketDepositPool; + } + + function name() public pure override returns (string memory) { + return "RPStakeEth"; + } + + /** + * @inheritdoc EoaExecutor + */ + function execute( + address, + address, + bytes calldata data + ) external payable override returns (address[] memory tokens) { + (address _recipient, uint256 _amount) = parseInputs(data); + + // If the adapter is called using `call` and not `delegatecall` + if (address(this) == self()) { + require( + msg.value == _amount, + Errors.INSUFFICIENT_NATIVE_FUNDS_PASSED + ); + } + bytes memory logData; + + (tokens, logData) = _stake(_recipient, _amount); + + emit ExecutionEvent(name(), logData); + return tokens; + } + + /** + * @inheritdoc NitroMessageHandler + */ + function handleMessage( + address tokenSent, + uint256 amount, + bytes memory instruction + ) external override onlyNitro nonReentrant { + address recipient = abi.decode(instruction, (address)); + + if (tokenSent != native()) { + withdrawTokens(tokenSent, recipient, amount); + emit OperationFailedRefundEvent(tokenSent, recipient, amount); + return; + } + + try _rocketDepositPool.deposit{value: amount}() { + uint256 _receivedREth = withdrawTokens( + _rEth, + recipient, + type(uint256).max + ); + + emit RPStakeEthDest(recipient, amount, _receivedREth); + } catch { + withdrawTokens(tokenSent, recipient, amount); + emit OperationFailedRefundEvent(tokenSent, recipient, amount); + } + } + + //////////////////////////// ACTION LOGIC //////////////////////////// + + function _stake( + address _recipient, + uint256 _amount + ) internal returns (address[] memory tokens, bytes memory logData) { + _rocketDepositPool.deposit{value: _amount}(); + uint256 _receivedREth = withdrawTokens( + _rEth, + _recipient, + type(uint256).max + ); + + tokens = new address[](2); + tokens[0] = native(); + tokens[1] = rEth(); + + logData = abi.encode(_recipient, _amount, _receivedREth); + } + + /** + * @dev function to parse input data. + * @param data input data. + */ + function parseInputs( + bytes memory data + ) public pure returns (address, uint256) { + return abi.decode(data, (address, uint256)); + } + + // solhint-disable-next-line no-empty-blocks + receive() external payable {} +} diff --git a/evm/contracts/intent-adapters/liquid-staking/Stader/Interfaces.sol b/evm/contracts/intent-adapters/liquid-staking/Stader/Interfaces.sol new file mode 100644 index 0000000..c62146f --- /dev/null +++ b/evm/contracts/intent-adapters/liquid-staking/Stader/Interfaces.sol @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.18; + +interface IStaderPool { + function deposit(address receiver) external payable returns (uint256); + + function swapMaticForMaticXViaInstantPool() external payable; +} + +interface IMaticX { + function submit(uint256 _amount) external returns (uint256); +} + +interface IStakeManager { + function deposit() external payable; +} diff --git a/evm/contracts/intent-adapters/liquid-staking/Stader/StaderStakeBnb.sol b/evm/contracts/intent-adapters/liquid-staking/Stader/StaderStakeBnb.sol new file mode 100644 index 0000000..a71dbdf --- /dev/null +++ b/evm/contracts/intent-adapters/liquid-staking/Stader/StaderStakeBnb.sol @@ -0,0 +1,145 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.18; + +import {IStakeManager} from "./Interfaces.sol"; +import {RouterIntentEoaAdapter, EoaExecutor} from "router-intents/contracts/RouterIntentEoaAdapter.sol"; +import {NitroMessageHandler} from "router-intents/contracts/utils/NitroMessageHandler.sol"; +import {Errors} from "router-intents/contracts/utils/Errors.sol"; + +import {IERC20, SafeERC20} from "../../../utils/SafeERC20.sol"; + +/** + * @title StaderStakeBnb + * @author Yashika Goyal + * @notice Staking BNB to receive BnbX on Stader. + * @notice This contract is only for Binance chain. + */ +contract StaderStakeBnb is RouterIntentEoaAdapter, NitroMessageHandler { + using SafeERC20 for IERC20; + + address private immutable _bnbx; + IStakeManager private immutable _staderPool; + + event StaderStakeBnbDest( + address _recipient, + uint256 _amount, + uint256 _receivedBnbx + ); + + constructor( + address __native, + address __wnative, + address __owner, + address __assetForwarder, + address __dexspan, + address __bnbx, + address __staderPool + ) + RouterIntentEoaAdapter(__native, __wnative, __owner) + NitroMessageHandler(__assetForwarder, __dexspan) + { + _bnbx = __bnbx; + _staderPool = IStakeManager(__staderPool); + } + + function bnbx() public view returns (address) { + return _bnbx; + } + + function staderPool() public view returns (IStakeManager) { + return _staderPool; + } + + function name() public pure override returns (string memory) { + return "StaderStakeBnb"; + } + + /** + * @inheritdoc EoaExecutor + */ + function execute( + address, + address, + bytes calldata data + ) external payable override returns (address[] memory tokens) { + (address _recipient, uint256 _amount) = parseInputs(data); + + // If the adapter is called using `call` and not `delegatecall` + if (address(this) == self()) { + require( + msg.value == _amount, + Errors.INSUFFICIENT_NATIVE_FUNDS_PASSED + ); + } + + bytes memory logData; + + (tokens, logData) = _stake(_recipient, _amount); + + emit ExecutionEvent(name(), logData); + return tokens; + } + + /** + * @inheritdoc NitroMessageHandler + */ + function handleMessage( + address tokenSent, + uint256 amount, + bytes memory instruction + ) external override onlyNitro nonReentrant { + address recipient = abi.decode(instruction, (address)); + + if (tokenSent != native()) { + withdrawTokens(tokenSent, recipient, amount); + emit OperationFailedRefundEvent(tokenSent, recipient, amount); + return; + } + + try _staderPool.deposit{value: amount}() { + uint256 receivedBnbX = withdrawTokens( + _bnbx, + recipient, + type(uint256).max + ); + + emit StaderStakeBnbDest(recipient, amount, receivedBnbX); + } catch { + withdrawTokens(tokenSent, recipient, amount); + emit OperationFailedRefundEvent(tokenSent, recipient, amount); + } + } + + //////////////////////////// ACTION LOGIC //////////////////////////// + + function _stake( + address _recipient, + uint256 _amount + ) internal returns (address[] memory tokens, bytes memory logData) { + _staderPool.deposit{value: _amount}(); + uint256 receivedBnbX = withdrawTokens( + _bnbx, + _recipient, + type(uint256).max + ); + + tokens = new address[](2); + tokens[0] = native(); + tokens[1] = bnbx(); + + logData = abi.encode(_recipient, _amount, receivedBnbX); + } + + /** + * @dev function to parse input data. + * @param data input data. + */ + function parseInputs( + bytes memory data + ) public pure returns (address, uint256) { + return abi.decode(data, (address, uint256)); + } + + // solhint-disable-next-line no-empty-blocks + receive() external payable {} +} diff --git a/evm/contracts/intent-adapters/liquid-staking/Stader/StaderStakeEth.sol b/evm/contracts/intent-adapters/liquid-staking/Stader/StaderStakeEth.sol new file mode 100644 index 0000000..a8918eb --- /dev/null +++ b/evm/contracts/intent-adapters/liquid-staking/Stader/StaderStakeEth.sol @@ -0,0 +1,129 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.18; + +import {IStaderPool} from "./Interfaces.sol"; +import {RouterIntentEoaAdapter, EoaExecutor} from "router-intents/contracts/RouterIntentEoaAdapter.sol"; +import {NitroMessageHandler} from "router-intents/contracts/utils/NitroMessageHandler.sol"; +import {Errors} from "router-intents/contracts/utils/Errors.sol"; +import {IERC20, SafeERC20} from "../../../utils/SafeERC20.sol"; + +/** + * @title StaderStakeEth + * @author Shivam Agrawal + * @notice Staking ETH to receive EthX on Stader. + * @notice This contract is only for Ethereum chain. + */ +contract StaderStakeEth is RouterIntentEoaAdapter, NitroMessageHandler { + using SafeERC20 for IERC20; + + address private immutable _ethx; + IStaderPool private immutable _staderPool; + + event StaderStakeEthDest(address _recipient, uint256 _amount); + + constructor( + address __native, + address __wnative, + address __owner, + address __assetForwarder, + address __dexspan, + address __ethx, + address __staderPool + ) + RouterIntentEoaAdapter(__native, __wnative, __owner) + NitroMessageHandler(__assetForwarder, __dexspan) + { + _ethx = __ethx; + _staderPool = IStaderPool(__staderPool); + } + + function ethx() public view returns (address) { + return _ethx; + } + + function staderPool() public view returns (IStaderPool) { + return _staderPool; + } + + function name() public pure override returns (string memory) { + return "StaderStakeEth"; + } + + /** + * @inheritdoc EoaExecutor + */ + function execute( + address, + address, + bytes calldata data + ) external payable override returns (address[] memory tokens) { + (address _recipient, uint256 _amount) = parseInputs(data); + + // If the adapter is called using `call` and not `delegatecall` + if (address(this) == self()) { + require( + msg.value == _amount, + Errors.INSUFFICIENT_NATIVE_FUNDS_PASSED + ); + } + + bytes memory logData; + + (tokens, logData) = _stake(_recipient, _amount); + + emit ExecutionEvent(name(), logData); + return tokens; + } + + /** + * @inheritdoc NitroMessageHandler + */ + function handleMessage( + address tokenSent, + uint256 amount, + bytes memory instruction + ) external override onlyNitro nonReentrant { + address recipient = abi.decode(instruction, (address)); + + if (tokenSent != native()) { + withdrawTokens(tokenSent, recipient, amount); + emit OperationFailedRefundEvent(tokenSent, recipient, amount); + return; + } + + try _staderPool.deposit{value: amount}(recipient) { + emit StaderStakeEthDest(recipient, amount); + } catch { + withdrawTokens(tokenSent, recipient, amount); + emit OperationFailedRefundEvent(tokenSent, recipient, amount); + } + } + + //////////////////////////// ACTION LOGIC //////////////////////////// + + function _stake( + address _recipient, + uint256 _amount + ) internal returns (address[] memory tokens, bytes memory logData) { + _staderPool.deposit{value: _amount}(_recipient); + + tokens = new address[](2); + tokens[0] = native(); + tokens[1] = ethx(); + + logData = abi.encode(_recipient, _amount); + } + + /** + * @dev function to parse input data. + * @param data input data. + */ + function parseInputs( + bytes memory data + ) public pure returns (address, uint256) { + return abi.decode(data, (address, uint256)); + } + + // solhint-disable-next-line no-empty-blocks + receive() external payable {} +} diff --git a/evm/contracts/intent-adapters/liquid-staking/Stader/StaderStakeFtm.sol b/evm/contracts/intent-adapters/liquid-staking/Stader/StaderStakeFtm.sol new file mode 100644 index 0000000..31b4de6 --- /dev/null +++ b/evm/contracts/intent-adapters/liquid-staking/Stader/StaderStakeFtm.sol @@ -0,0 +1,144 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.18; + +import {IStakeManager} from "./Interfaces.sol"; +import {RouterIntentEoaAdapter, EoaExecutor} from "router-intents/contracts/RouterIntentEoaAdapter.sol"; +import {NitroMessageHandler} from "router-intents/contracts/utils/NitroMessageHandler.sol"; +import {Errors} from "router-intents/contracts/utils/Errors.sol"; +import {IERC20, SafeERC20} from "../../../utils/SafeERC20.sol"; + +/** + * @title StaderStakeFtm + * @author Yashika Goyal + * @notice Staking FTM to receive FtmX on Stader. + * @notice This contract is only for Fantom chain. + */ +contract StaderStakeFtm is RouterIntentEoaAdapter, NitroMessageHandler { + using SafeERC20 for IERC20; + + address private immutable _sftmx; + IStakeManager private immutable _staderPool; + + event StaderStakeFtmDest( + address _recipient, + uint256 _amount, + uint256 _receivedSFtmx + ); + + constructor( + address __native, + address __wnative, + address __owner, + address __assetForwarder, + address __dexspan, + address __sftmx, + address __staderPool + ) + RouterIntentEoaAdapter(__native, __wnative, __owner) + NitroMessageHandler(__assetForwarder, __dexspan) + { + _sftmx = __sftmx; + _staderPool = IStakeManager(__staderPool); + } + + function sftmx() public view returns (address) { + return _sftmx; + } + + function staderPool() public view returns (IStakeManager) { + return _staderPool; + } + + function name() public pure override returns (string memory) { + return "StaderStakeFtm"; + } + + /** + * @inheritdoc EoaExecutor + */ + function execute( + address, + address, + bytes calldata data + ) external payable override returns (address[] memory tokens) { + (address _recipient, uint256 _amount) = parseInputs(data); + + // If the adapter is called using `call` and not `delegatecall` + if (address(this) == self()) { + require( + msg.value == _amount, + Errors.INSUFFICIENT_NATIVE_FUNDS_PASSED + ); + } + + bytes memory logData; + + (tokens, logData) = _stake(_recipient, _amount); + + emit ExecutionEvent(name(), logData); + return tokens; + } + + /** + * @inheritdoc NitroMessageHandler + */ + function handleMessage( + address tokenSent, + uint256 amount, + bytes memory instruction + ) external override onlyNitro nonReentrant { + address recipient = abi.decode(instruction, (address)); + + if (tokenSent != native()) { + withdrawTokens(tokenSent, recipient, amount); + emit OperationFailedRefundEvent(tokenSent, recipient, amount); + return; + } + + try _staderPool.deposit{value: amount}() { + uint256 receivedSFtmX = withdrawTokens( + _sftmx, + recipient, + type(uint256).max + ); + + emit StaderStakeFtmDest(recipient, amount, receivedSFtmX); + } catch { + withdrawTokens(tokenSent, recipient, amount); + emit OperationFailedRefundEvent(tokenSent, recipient, amount); + } + } + + //////////////////////////// ACTION LOGIC //////////////////////////// + + function _stake( + address _recipient, + uint256 _amount + ) internal returns (address[] memory tokens, bytes memory logData) { + _staderPool.deposit{value: _amount}(); + uint256 receivedSFtmX = withdrawTokens( + _sftmx, + _recipient, + type(uint256).max + ); + + tokens = new address[](2); + tokens[0] = native(); + tokens[1] = sftmx(); + + logData = abi.encode(_recipient, _amount, receivedSFtmX); + } + + /** + * @dev function to parse input data. + * @param data input data. + */ + function parseInputs( + bytes memory data + ) public pure returns (address, uint256) { + return abi.decode(data, (address, uint256)); + } + + // solhint-disable-next-line no-empty-blocks + receive() external payable {} +} diff --git a/evm/contracts/intent-adapters/liquid-staking/Stader/StaderStakeMatic.sol b/evm/contracts/intent-adapters/liquid-staking/Stader/StaderStakeMatic.sol new file mode 100644 index 0000000..1d520a6 --- /dev/null +++ b/evm/contracts/intent-adapters/liquid-staking/Stader/StaderStakeMatic.sol @@ -0,0 +1,135 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.18; + +import {IMaticX} from "./Interfaces.sol"; +import {RouterIntentEoaAdapter, EoaExecutor} from "router-intents/contracts/RouterIntentEoaAdapter.sol"; +import {NitroMessageHandler} from "router-intents/contracts/utils/NitroMessageHandler.sol"; +import {Errors} from "router-intents/contracts/utils/Errors.sol"; +import {IERC20, SafeERC20} from "../../../utils/SafeERC20.sol"; + +/** + * @title StaderStakeMatic + * @author Shivam Agrawal + * @notice Staking Matic to receive MaticX on Stader. + * @notice This contract is only for Ethereum chain. + */ +contract StaderStakeMatic is RouterIntentEoaAdapter, NitroMessageHandler { + using SafeERC20 for IERC20; + + address public immutable _maticx; + address public immutable _matic; + + event StaderStakeMaticDest( + address _recipient, + uint256 _amount, + uint256 _receivedMaticX + ); + + constructor( + address __native, + address __wnative, + address __owner, + address __assetForwarder, + address __dexspan, + address __maticx, + address __matic + ) + RouterIntentEoaAdapter(__native, __wnative, __owner) + NitroMessageHandler(__assetForwarder, __dexspan) + // solhint-disable-next-line no-empty-blocks + { + _matic = __matic; + _maticx = __maticx; + } + + function maticx() public view returns (address) { + return _maticx; + } + + function matic() public view returns (address) { + return _matic; + } + + function name() public pure override returns (string memory) { + return "StaderStakeMatic"; + } + + /** + * @inheritdoc EoaExecutor + */ + function execute( + address, + address, + bytes calldata data + ) external payable override returns (address[] memory tokens) { + (address _recipient, uint256 _amount) = parseInputs(data); + + // If the adapter is called using `call` and not `delegatecall` + if (address(this) == self()) { + IERC20(_matic).safeTransferFrom(msg.sender, self(), _amount); + } + + bytes memory logData; + + (tokens, logData) = _stake(_recipient, _amount); + + emit ExecutionEvent(name(), logData); + return tokens; + } + + /** + * @inheritdoc NitroMessageHandler + */ + function handleMessage( + address tokenSent, + uint256 amount, + bytes memory instruction + ) external override onlyNitro nonReentrant { + address recipient = abi.decode(instruction, (address)); + + if (tokenSent != _matic) { + withdrawTokens(tokenSent, recipient, amount); + emit OperationFailedRefundEvent(tokenSent, recipient, amount); + return; + } + + IERC20(_matic).safeIncreaseAllowance(_maticx, amount); + + try IMaticX(_maticx).submit(amount) { + uint256 receivedMaticX = IERC20(_maticx).balanceOf(address(this)); + withdrawTokens(_maticx, recipient, receivedMaticX); + emit StaderStakeMaticDest(recipient, amount, receivedMaticX); + } catch { + withdrawTokens(tokenSent, recipient, amount); + emit OperationFailedRefundEvent(tokenSent, recipient, amount); + } + } + + //////////////////////////// ACTION LOGIC //////////////////////////// + + function _stake( + address _recipient, + uint256 _amount + ) internal returns (address[] memory tokens, bytes memory logData) { + IERC20(_matic).safeIncreaseAllowance(_maticx, _amount); + IMaticX(_maticx).submit(_amount); + uint256 receivedMaticX = IERC20(_maticx).balanceOf(address(this)); + withdrawTokens(_maticx, _recipient, receivedMaticX); + + tokens = new address[](2); + tokens[0] = _matic; + tokens[1] = _maticx; + + logData = abi.encode(_recipient, _amount, receivedMaticX); + } + + /** + * @dev function to parse input data. + * @param data input data. + */ + function parseInputs( + bytes memory data + ) public pure returns (address, uint256) { + return abi.decode(data, (address, uint256)); + } +} diff --git a/evm/contracts/intent-adapters/liquid-staking/Stader/StaderStakePolygon.sol b/evm/contracts/intent-adapters/liquid-staking/Stader/StaderStakePolygon.sol new file mode 100644 index 0000000..e1cd2ad --- /dev/null +++ b/evm/contracts/intent-adapters/liquid-staking/Stader/StaderStakePolygon.sol @@ -0,0 +1,144 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.18; + +import {IStaderPool} from "./Interfaces.sol"; +import {RouterIntentEoaAdapter, EoaExecutor} from "router-intents/contracts/RouterIntentEoaAdapter.sol"; +import {NitroMessageHandler} from "router-intents/contracts/utils/NitroMessageHandler.sol"; +import {Errors} from "router-intents/contracts/utils/Errors.sol"; +import {IERC20, SafeERC20} from "../../../utils/SafeERC20.sol"; + +/** + * @title StaderStakePolygon + * @author Shivam Agrawal + * @notice Staking MATIC to receive MaticX on Stader. + * @notice This contract is only for Polygon chain. + */ +contract StaderStakePolygon is RouterIntentEoaAdapter, NitroMessageHandler { + using SafeERC20 for IERC20; + + address public immutable _maticx; + IStaderPool public immutable _staderPool; + + event StaderStakePolygonDest( + address _recipient, + uint256 _amount, + uint256 _receivedMaticX + ); + + constructor( + address __native, + address __wnative, + address __owner, + address __assetForwarder, + address __dexspan, + address __maticx, + address __staderPool + ) + RouterIntentEoaAdapter(__native, __wnative, __owner) + NitroMessageHandler(__assetForwarder, __dexspan) + { + _maticx = __maticx; + _staderPool = IStaderPool(__staderPool); + } + + function maticx() public view returns (address) { + return _maticx; + } + + function staderPool() public view returns (IStaderPool) { + return _staderPool; + } + + function name() public pure override returns (string memory) { + return "StaderStakePolygon"; + } + + /** + * @inheritdoc EoaExecutor + */ + function execute( + address, + address, + bytes calldata data + ) external payable override returns (address[] memory tokens) { + (address _recipient, uint256 _amount) = parseInputs(data); + + // If the adapter is called using `call` and not `delegatecall` + if (address(this) == self()) { + require( + msg.value == _amount, + Errors.INSUFFICIENT_NATIVE_FUNDS_PASSED + ); + } + + bytes memory logData; + + (tokens, logData) = _stake(_recipient, _amount); + + emit ExecutionEvent(name(), logData); + return tokens; + } + + /** + * @inheritdoc NitroMessageHandler + */ + function handleMessage( + address tokenSent, + uint256 amount, + bytes memory instruction + ) external override onlyNitro nonReentrant { + address recipient = abi.decode(instruction, (address)); + + if (tokenSent != native()) { + withdrawTokens(tokenSent, recipient, amount); + emit OperationFailedRefundEvent(tokenSent, recipient, amount); + return; + } + + try _staderPool.swapMaticForMaticXViaInstantPool{value: amount}() { + uint256 receivedMaticX = withdrawTokens( + _maticx, + recipient, + type(uint256).max + ); + + emit StaderStakePolygonDest(recipient, amount, receivedMaticX); + } catch { + withdrawTokens(tokenSent, recipient, amount); + emit OperationFailedRefundEvent(tokenSent, recipient, amount); + } + } + + //////////////////////////// ACTION LOGIC //////////////////////////// + + function _stake( + address _recipient, + uint256 _amount + ) internal returns (address[] memory tokens, bytes memory logData) { + _staderPool.swapMaticForMaticXViaInstantPool{value: _amount}(); + uint256 receivedMaticX = withdrawTokens( + _maticx, + _recipient, + type(uint256).max + ); + + tokens = new address[](2); + tokens[0] = native(); + tokens[1] = maticx(); + + logData = abi.encode(_recipient, _amount, receivedMaticX); + } + + /** + * @dev function to parse input data. + * @param data input data. + */ + function parseInputs( + bytes memory data + ) public pure returns (address, uint256) { + return abi.decode(data, (address, uint256)); + } + + // solhint-disable-next-line no-empty-blocks + receive() external payable {} +} diff --git a/evm/contracts/intent-adapters/liquid-staking/Swell/Interfaces.sol b/evm/contracts/intent-adapters/liquid-staking/Swell/Interfaces.sol new file mode 100644 index 0000000..a3b4751 --- /dev/null +++ b/evm/contracts/intent-adapters/liquid-staking/Swell/Interfaces.sol @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.18; + +interface ISwellPool { + function deposit() external payable; +} diff --git a/evm/contracts/intent-adapters/liquid-staking/Swell/SwellStakeEth.sol b/evm/contracts/intent-adapters/liquid-staking/Swell/SwellStakeEth.sol new file mode 100644 index 0000000..d485c5c --- /dev/null +++ b/evm/contracts/intent-adapters/liquid-staking/Swell/SwellStakeEth.sol @@ -0,0 +1,137 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.18; + +import {ISwellPool} from "./Interfaces.sol"; +import {RouterIntentEoaAdapter, EoaExecutor} from "router-intents/contracts/RouterIntentEoaAdapter.sol"; +import {NitroMessageHandler} from "router-intents/contracts/utils/NitroMessageHandler.sol"; +import {Errors} from "router-intents/contracts/utils/Errors.sol"; +import {IERC20, SafeERC20} from "../../../utils/SafeERC20.sol"; + +/** + * @title SwellStakeEth + * @author Yashika Goyal + * @notice Staking ETH to receive swETH on Swell. + * @notice This contract is only for Ethereum chain. + */ +contract SwellStakeEth is RouterIntentEoaAdapter, NitroMessageHandler { + using SafeERC20 for IERC20; + + address private immutable _swEth; + + event SwellStakeEthDest( + address _recipient, + uint256 _amount, + uint256 _receivedSwEth + ); + + constructor( + address __native, + address __wnative, + address __owner, + address __assetForwarder, + address __dexspan, + address __swEth + ) + RouterIntentEoaAdapter(__native, __wnative, __owner) + NitroMessageHandler(__assetForwarder, __dexspan) + { + _swEth = __swEth; + } + + function swEth() public view returns (address) { + return _swEth; + } + + function name() public pure override returns (string memory) { + return "SwellStakeEth"; + } + + /** + * @inheritdoc EoaExecutor + */ + function execute( + address, + address, + bytes calldata data + ) external payable override returns (address[] memory tokens) { + (address _recipient, uint256 _amount) = parseInputs(data); + + // If the adapter is called using `call` and not `delegatecall` + if (address(this) == self()) { + require( + msg.value == _amount, + Errors.INSUFFICIENT_NATIVE_FUNDS_PASSED + ); + } + + bytes memory logData; + + (tokens, logData) = _stake(_recipient, _amount); + + emit ExecutionEvent(name(), logData); + return tokens; + } + + /** + * @inheritdoc NitroMessageHandler + */ + function handleMessage( + address tokenSent, + uint256 amount, + bytes memory instruction + ) external override onlyNitro nonReentrant { + address recipient = abi.decode(instruction, (address)); + + if (tokenSent != native()) { + withdrawTokens(tokenSent, recipient, amount); + emit OperationFailedRefundEvent(tokenSent, recipient, amount); + return; + } + + try ISwellPool(_swEth).deposit{value: amount}() { + uint256 receivedSwEth = withdrawTokens( + _swEth, + recipient, + type(uint256).max + ); + + emit SwellStakeEthDest(recipient, amount, receivedSwEth); + } catch { + withdrawTokens(tokenSent, recipient, amount); + emit OperationFailedRefundEvent(tokenSent, recipient, amount); + } + } + + //////////////////////////// ACTION LOGIC //////////////////////////// + + function _stake( + address _recipient, + uint256 _amount + ) internal returns (address[] memory tokens, bytes memory logData) { + ISwellPool(_swEth).deposit{value: _amount}(); + uint256 receivedSwEth = withdrawTokens( + _swEth, + _recipient, + type(uint256).max + ); + + tokens = new address[](2); + tokens[0] = native(); + tokens[1] = swEth(); + + logData = abi.encode(_recipient, _amount, receivedSwEth); + } + + /** + * @dev function to parse input data. + * @param data input data. + */ + function parseInputs( + bytes memory data + ) public pure returns (address, uint256) { + return abi.decode(data, (address, uint256)); + } + + // solhint-disable-next-line no-empty-blocks + receive() external payable {} +} diff --git a/evm/contracts/intent-adapters/liquid-staking/Synclub/Interfaces.sol b/evm/contracts/intent-adapters/liquid-staking/Synclub/Interfaces.sol new file mode 100644 index 0000000..aeb9f43 --- /dev/null +++ b/evm/contracts/intent-adapters/liquid-staking/Synclub/Interfaces.sol @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.18; + +interface ISynClubPool { + function deposit() external payable; +} diff --git a/evm/contracts/intent-adapters/liquid-staking/Synclub/SynClubStakeBnb.sol b/evm/contracts/intent-adapters/liquid-staking/Synclub/SynClubStakeBnb.sol new file mode 100644 index 0000000..6e41880 --- /dev/null +++ b/evm/contracts/intent-adapters/liquid-staking/Synclub/SynClubStakeBnb.sol @@ -0,0 +1,144 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.18; + +import {ISynClubPool} from "./Interfaces.sol"; +import {RouterIntentEoaAdapter, EoaExecutor} from "router-intents/contracts/RouterIntentEoaAdapter.sol"; +import {NitroMessageHandler} from "router-intents/contracts/utils/NitroMessageHandler.sol"; +import {Errors} from "router-intents/contracts/utils/Errors.sol"; +import {IERC20, SafeERC20} from "../../../utils/SafeERC20.sol"; + +/** + * @title SynClubStakeBnb + * @author Yashika Goyal + * @notice Staking BNB to receive snBNB on SynClub. + * @notice This contract is only for BSC chain. + */ +contract SynClubStakeBnb is RouterIntentEoaAdapter, NitroMessageHandler { + using SafeERC20 for IERC20; + + address private immutable _snBnb; + ISynClubPool private immutable _synClubPool; + + event SynClubStakeBnbDest( + address _recipient, + uint256 _amount, + uint256 _receivedSnBnb + ); + + constructor( + address __native, + address __wnative, + address __owner, + address __assetForwarder, + address __dexspan, + address __snBnb, + address __synClubPool + ) + RouterIntentEoaAdapter(__native, __wnative, __owner) + NitroMessageHandler(__assetForwarder, __dexspan) + { + _snBnb = __snBnb; + _synClubPool = ISynClubPool(__synClubPool); + } + + function snBnb() public view returns (address) { + return _snBnb; + } + + function synClubPool() public view returns (ISynClubPool) { + return _synClubPool; + } + + function name() public pure override returns (string memory) { + return "SynClubStakeBnb"; + } + + /** + * @inheritdoc EoaExecutor + */ + function execute( + address, + address, + bytes calldata data + ) external payable override returns (address[] memory tokens) { + (address _recipient, uint256 _amount) = parseInputs(data); + + // If the adapter is called using `call` and not `delegatecall` + if (address(this) == self()) { + require( + msg.value == _amount, + Errors.INSUFFICIENT_NATIVE_FUNDS_PASSED + ); + } + + bytes memory logData; + + (tokens, logData) = _stake(_recipient, _amount); + + emit ExecutionEvent(name(), logData); + return tokens; + } + + /** + * @inheritdoc NitroMessageHandler + */ + function handleMessage( + address tokenSent, + uint256 amount, + bytes memory instruction + ) external override onlyNitro nonReentrant { + address recipient = abi.decode(instruction, (address)); + + if (tokenSent != native()) { + withdrawTokens(tokenSent, recipient, amount); + emit OperationFailedRefundEvent(tokenSent, recipient, amount); + return; + } + + try _synClubPool.deposit{value: amount}() { + uint256 receivedSnBnb = withdrawTokens( + _snBnb, + recipient, + type(uint256).max + ); + + emit SynClubStakeBnbDest(recipient, amount, receivedSnBnb); + } catch { + withdrawTokens(tokenSent, recipient, amount); + emit OperationFailedRefundEvent(tokenSent, recipient, amount); + } + } + + //////////////////////////// ACTION LOGIC //////////////////////////// + + function _stake( + address _recipient, + uint256 _amount + ) internal returns (address[] memory tokens, bytes memory logData) { + _synClubPool.deposit{value: _amount}(); + uint256 receivedSnBnb = withdrawTokens( + _snBnb, + _recipient, + type(uint256).max + ); + + tokens = new address[](2); + tokens[0] = native(); + tokens[1] = snBnb(); + + logData = abi.encode(_recipient, _amount, receivedSnBnb); + } + + /** + * @dev function to parse input data. + * @param data input data. + */ + function parseInputs( + bytes memory data + ) public pure returns (address, uint256) { + return abi.decode(data, (address, uint256)); + } + + // solhint-disable-next-line no-empty-blocks + receive() external payable {} +} diff --git a/evm/contracts/intent-adapters/lp/Pancakeswap/Interfaces.sol b/evm/contracts/intent-adapters/lp/Pancakeswap/Interfaces.sol new file mode 100644 index 0000000..2d9a6af --- /dev/null +++ b/evm/contracts/intent-adapters/lp/Pancakeswap/Interfaces.sol @@ -0,0 +1,99 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +pragma solidity 0.8.18; + +abstract contract IPancakeswapNonfungiblePositionManager { + struct MintParams { + address token0; + address token1; + uint24 fee; + int24 tickLower; + int24 tickUpper; + uint256 amount0Desired; + uint256 amount1Desired; + uint256 amount0Min; + uint256 amount1Min; + address recipient; + uint256 deadline; + } + + function mint( + MintParams calldata params + ) + external + payable + virtual + returns ( + uint256 tokenId, + uint128 liquidity, + uint256 amount0, + uint256 amount1 + ); + + struct IncreaseLiquidityParams { + uint256 tokenId; + uint256 amount0Desired; + uint256 amount1Desired; + uint256 amount0Min; + uint256 amount1Min; + uint256 deadline; + } + + function increaseLiquidity( + IncreaseLiquidityParams calldata params + ) + external + payable + virtual + returns (uint128 liquidity, uint256 amount0, uint256 amount1); + + struct DecreaseLiquidityParams { + uint256 tokenId; + uint128 liquidity; + uint256 amount0Min; + uint256 amount1Min; + uint256 deadline; + } + + function decreaseLiquidity( + DecreaseLiquidityParams calldata params + ) external payable virtual returns (uint256 amount0, uint256 amount1); + + // set amount0Max and amount1Max to uint256.max to collect all fees + struct CollectParams { + uint256 tokenId; + address recipient; + uint128 amount0Max; + uint128 amount1Max; + } + + function collect( + CollectParams calldata params + ) external payable virtual returns (uint256 amount0, uint256 amount1); + + function burn(uint256 tokenId) external payable virtual; + + function positions( + uint256 tokenId + ) + external + view + virtual + returns ( + uint96 nonce, + address operator, + address token0, + address token1, + uint24 fee, + int24 tickLower, + int24 tickUpper, + uint128 liquidity, + uint256 feeGrowthInside0LastX128, + uint256 feeGrowthInside1LastX128, + uint128 tokensOwed0, + uint128 tokensOwed1 + ); + + function balanceOf( + address owner + ) external view virtual returns (uint256 balance); +} diff --git a/evm/contracts/intent-adapters/lp/Pancakeswap/PancakeswapHelpers.sol b/evm/contracts/intent-adapters/lp/Pancakeswap/PancakeswapHelpers.sol new file mode 100644 index 0000000..6ebf2a1 --- /dev/null +++ b/evm/contracts/intent-adapters/lp/Pancakeswap/PancakeswapHelpers.sol @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.18; + +import {IPancakeswapNonfungiblePositionManager} from "./Interfaces.sol"; + +contract PancakeswapHelpers { + IPancakeswapNonfungiblePositionManager + private immutable _nonFungiblePositionManager; + + constructor(address __nonFungiblePositionManager) { + _nonFungiblePositionManager = IPancakeswapNonfungiblePositionManager( + __nonFungiblePositionManager + ); + } + + function positionManager() + public + view + returns (IPancakeswapNonfungiblePositionManager) + { + return _nonFungiblePositionManager; + } +} diff --git a/evm/contracts/intent-adapters/lp/Pancakeswap/PancakeswapMint.sol b/evm/contracts/intent-adapters/lp/Pancakeswap/PancakeswapMint.sol new file mode 100644 index 0000000..bc47e8b --- /dev/null +++ b/evm/contracts/intent-adapters/lp/Pancakeswap/PancakeswapMint.sol @@ -0,0 +1,161 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.18; + +import {IPancakeswapNonfungiblePositionManager} from "./Interfaces.sol"; +import {RouterIntentEoaAdapter, EoaExecutor} from "router-intents/contracts/RouterIntentEoaAdapter.sol"; +import {NitroMessageHandler} from "router-intents/contracts/utils/NitroMessageHandler.sol"; +import {Errors} from "router-intents/contracts/utils/Errors.sol"; +import {DefaultRefundable} from "router-intents/contracts/utils/DefaultRefundable.sol"; +import {IERC20, SafeERC20} from "../../../utils/SafeERC20.sol"; +import {PancakeswapHelpers} from "./PancakeswapHelpers.sol"; + +/** + * @title PancakeswapMint + * @author Yashika Goyal + * @notice Minting a new position on Pancakeswap. + */ +contract PancakeswapMint is + RouterIntentEoaAdapter, + NitroMessageHandler, + DefaultRefundable, + PancakeswapHelpers +{ + using SafeERC20 for IERC20; + + event PancakeswapMintPositionDest(); + + constructor( + address __native, + address __wnative, + address __owner, + address __assetForwarder, + address __dexspan, + address __defaultRefundAddress, + address __nonFungiblePositionManager + ) + RouterIntentEoaAdapter(__native, __wnative, __owner) + NitroMessageHandler(__assetForwarder, __dexspan) + DefaultRefundable(__defaultRefundAddress) + PancakeswapHelpers(__nonFungiblePositionManager) + // solhint-disable-next-line no-empty-blocks + { + + } + + function name() public pure override returns (string memory) { + return "PancakeswapMint"; + } + + /** + * @inheritdoc EoaExecutor + */ + function execute( + address, + address, + bytes calldata data + ) external payable override returns (address[] memory tokens) { + IPancakeswapNonfungiblePositionManager.MintParams + memory mintParams = parseInputs(data); + + // If the adapter is called using `call` and not `delegatecall` + if (address(this) == self()) { + if (mintParams.token0 != native()) + IERC20(mintParams.token0).safeTransferFrom( + msg.sender, + self(), + mintParams.amount0Desired + ); + else + require( + msg.value == mintParams.amount0Desired, + Errors.INSUFFICIENT_NATIVE_FUNDS_PASSED + ); + + if (mintParams.token1 != native()) + IERC20(mintParams.token1).safeTransferFrom( + msg.sender, + self(), + mintParams.amount1Desired + ); + else + require( + msg.value == mintParams.amount1Desired, + Errors.INSUFFICIENT_NATIVE_FUNDS_PASSED + ); + } + + if (mintParams.token0 == native()) { + convertNativeToWnative(mintParams.amount0Desired); + mintParams.token0 = wnative(); + } + + if (mintParams.token1 == native()) { + convertNativeToWnative(mintParams.amount0Desired); + mintParams.token1 = wnative(); + } + + IERC20(mintParams.token0).safeIncreaseAllowance( + address(positionManager()), + mintParams.amount0Desired + ); + + IERC20(mintParams.token1).safeIncreaseAllowance( + address(positionManager()), + mintParams.amount1Desired + ); + + bytes memory logData; + + (tokens, logData) = _mint(mintParams); + + emit ExecutionEvent(name(), logData); + return tokens; + } + + /** + * @inheritdoc NitroMessageHandler + */ + function handleMessage( + address tokenSent, + uint256 amount, + bytes memory + ) external override onlyNitro nonReentrant { + withdrawTokens(tokenSent, defaultRefundAddress(), amount); + emit UnsupportedOperation(tokenSent, defaultRefundAddress(), amount); + } + + //////////////////////////// ACTION LOGIC //////////////////////////// + + function _mint( + IPancakeswapNonfungiblePositionManager.MintParams memory mintParams + ) internal returns (address[] memory tokens, bytes memory logData) { + (uint256 tokenId, , , ) = positionManager().mint(mintParams); + + tokens = new address[](2); + tokens[0] = mintParams.token0; + tokens[1] = mintParams.token1; + + logData = abi.encode(mintParams, tokenId); + } + + /** + * @dev function to parse input data. + * @param data input data. + */ + function parseInputs( + bytes memory data + ) + public + pure + returns (IPancakeswapNonfungiblePositionManager.MintParams memory) + { + return + abi.decode( + data, + (IPancakeswapNonfungiblePositionManager.MintParams) + ); + } + + // solhint-disable-next-line no-empty-blocks + receive() external payable {} +} diff --git a/evm/contracts/intent-adapters/lp/Quickswap/Interfaces.sol b/evm/contracts/intent-adapters/lp/Quickswap/Interfaces.sol new file mode 100644 index 0000000..1e164ff --- /dev/null +++ b/evm/contracts/intent-adapters/lp/Quickswap/Interfaces.sol @@ -0,0 +1,97 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +pragma solidity 0.8.18; + +abstract contract IQuickswapNonfungiblePositionManager { + struct MintParams { + address token0; + address token1; + int24 tickLower; + int24 tickUpper; + uint256 amount0Desired; + uint256 amount1Desired; + uint256 amount0Min; + uint256 amount1Min; + address recipient; + uint256 deadline; + } + + function mint( + MintParams calldata params + ) + external + payable + virtual + returns ( + uint256 tokenId, + uint128 liquidity, + uint256 amount0, + uint256 amount1 + ); + + struct IncreaseLiquidityParams { + uint256 tokenId; + uint256 amount0Desired; + uint256 amount1Desired; + uint256 amount0Min; + uint256 amount1Min; + uint256 deadline; + } + + function increaseLiquidity( + IncreaseLiquidityParams calldata params + ) + external + payable + virtual + returns (uint128 liquidity, uint256 amount0, uint256 amount1); + + struct DecreaseLiquidityParams { + uint256 tokenId; + uint128 liquidity; + uint256 amount0Min; + uint256 amount1Min; + uint256 deadline; + } + + function decreaseLiquidity( + DecreaseLiquidityParams calldata params + ) external payable virtual returns (uint256 amount0, uint256 amount1); + + // set amount0Max and amount1Max to uint256.max to collect all fees + struct CollectParams { + uint256 tokenId; + address recipient; + uint128 amount0Max; + uint128 amount1Max; + } + + function collect( + CollectParams calldata params + ) external payable virtual returns (uint256 amount0, uint256 amount1); + + function burn(uint256 tokenId) external payable virtual; + + function positions( + uint256 tokenId + ) + external + view + virtual + returns ( + uint96 nonce, + address operator, + address token0, + address token1, + int24 tickLower, + int24 tickUpper, + uint128 liquidity, + uint256 feeGrowthInside0LastX128, + uint256 feeGrowthInside1LastX128, + uint128 tokensOwed0, + uint128 tokensOwed1 + ); + + function balanceOf( + address owner + ) external view virtual returns (uint256 balance); +} diff --git a/evm/contracts/intent-adapters/lp/Quickswap/QuickswapHelpers.sol b/evm/contracts/intent-adapters/lp/Quickswap/QuickswapHelpers.sol new file mode 100644 index 0000000..1f9c4d2 --- /dev/null +++ b/evm/contracts/intent-adapters/lp/Quickswap/QuickswapHelpers.sol @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.18; + +import {IQuickswapNonfungiblePositionManager} from "./Interfaces.sol"; + +contract QuickswapHelpers { + IQuickswapNonfungiblePositionManager + private immutable _nonFungiblePositionManager; + + constructor(address __nonFungiblePositionManager) { + _nonFungiblePositionManager = IQuickswapNonfungiblePositionManager( + __nonFungiblePositionManager + ); + } + + function positionManager() + public + view + returns (IQuickswapNonfungiblePositionManager) + { + return _nonFungiblePositionManager; + } +} diff --git a/evm/contracts/intent-adapters/lp/Quickswap/QuickswapMint.sol b/evm/contracts/intent-adapters/lp/Quickswap/QuickswapMint.sol new file mode 100644 index 0000000..ff723ad --- /dev/null +++ b/evm/contracts/intent-adapters/lp/Quickswap/QuickswapMint.sol @@ -0,0 +1,158 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.18; + +import {IQuickswapNonfungiblePositionManager} from "./Interfaces.sol"; +import {RouterIntentEoaAdapter, EoaExecutor} from "router-intents/contracts/RouterIntentEoaAdapter.sol"; +import {NitroMessageHandler} from "router-intents/contracts/utils/NitroMessageHandler.sol"; +import {Errors} from "router-intents/contracts/utils/Errors.sol"; +import {DefaultRefundable} from "router-intents/contracts/utils/DefaultRefundable.sol"; +import {IERC20, SafeERC20} from "../../../utils/SafeERC20.sol"; +import {QuickswapHelpers} from "./QuickswapHelpers.sol"; + +/** + * @title QuickswapMint + * @author Yashika Goyal + * @notice Minting a new position on Quickswap. + */ +contract QuickswapMint is + RouterIntentEoaAdapter, + NitroMessageHandler, + DefaultRefundable, + QuickswapHelpers +{ + using SafeERC20 for IERC20; + + event QuickswapMintPositionDest(); + + constructor( + address __native, + address __wnative, + address __owner, + address __assetForwarder, + address __dexspan, + address __defaultRefundAddress, + address __nonFungiblePositionManager + ) + RouterIntentEoaAdapter(__native, __wnative, __owner) + NitroMessageHandler(__assetForwarder, __dexspan) + DefaultRefundable(__defaultRefundAddress) + QuickswapHelpers(__nonFungiblePositionManager) + // solhint-disable-next-line no-empty-blocks + { + + } + + function name() public pure override returns (string memory) { + return "QuickswapMint"; + } + + /** + * @inheritdoc EoaExecutor + */ + function execute( + address, + address, + bytes calldata data + ) external payable override returns (address[] memory tokens) { + IQuickswapNonfungiblePositionManager.MintParams + memory mintParams = parseInputs(data); + + // If the adapter is called using `call` and not `delegatecall` + if (address(this) == self()) { + if (mintParams.token0 != native()) + IERC20(mintParams.token0).safeTransferFrom( + msg.sender, + self(), + mintParams.amount0Desired + ); + else + require( + msg.value == mintParams.amount0Desired, + Errors.INSUFFICIENT_NATIVE_FUNDS_PASSED + ); + + if (mintParams.token1 != native()) + IERC20(mintParams.token1).safeTransferFrom( + msg.sender, + self(), + mintParams.amount1Desired + ); + else + require( + msg.value == mintParams.amount1Desired, + Errors.INSUFFICIENT_NATIVE_FUNDS_PASSED + ); + } + + if (mintParams.token0 == native()) { + convertNativeToWnative(mintParams.amount0Desired); + mintParams.token0 = wnative(); + } + + if (mintParams.token1 == native()) { + convertNativeToWnative(mintParams.amount0Desired); + mintParams.token1 = wnative(); + } + + IERC20(mintParams.token0).safeIncreaseAllowance( + address(positionManager()), + mintParams.amount0Desired + ); + + IERC20(mintParams.token1).safeIncreaseAllowance( + address(positionManager()), + mintParams.amount1Desired + ); + + bytes memory logData; + + (tokens, logData) = _mint(mintParams); + + emit ExecutionEvent(name(), logData); + return tokens; + } + + /** + * @inheritdoc NitroMessageHandler + */ + function handleMessage( + address tokenSent, + uint256 amount, + bytes memory + ) external override onlyNitro nonReentrant { + withdrawTokens(tokenSent, defaultRefundAddress(), amount); + emit UnsupportedOperation(tokenSent, defaultRefundAddress(), amount); + } + + //////////////////////////// ACTION LOGIC //////////////////////////// + + function _mint( + IQuickswapNonfungiblePositionManager.MintParams memory mintParams + ) internal returns (address[] memory tokens, bytes memory logData) { + (uint256 tokenId, , , ) = positionManager().mint(mintParams); + + tokens = new address[](2); + tokens[0] = mintParams.token0; + tokens[1] = mintParams.token1; + + logData = abi.encode(mintParams, tokenId); + } + + /** + * @dev function to parse input data. + * @param data input data. + */ + function parseInputs( + bytes memory data + ) + public + pure + returns (IQuickswapNonfungiblePositionManager.MintParams memory) + { + return + abi.decode(data, (IQuickswapNonfungiblePositionManager.MintParams)); + } + + // solhint-disable-next-line no-empty-blocks + receive() external payable {} +} diff --git a/evm/contracts/intent-adapters/lp/Sushiswap/Interfaces.sol b/evm/contracts/intent-adapters/lp/Sushiswap/Interfaces.sol new file mode 100644 index 0000000..274ee5b --- /dev/null +++ b/evm/contracts/intent-adapters/lp/Sushiswap/Interfaces.sol @@ -0,0 +1,99 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +pragma solidity 0.8.18; + +abstract contract ISushiswapNonfungiblePositionManager { + struct MintParams { + address token0; + address token1; + uint24 fee; + int24 tickLower; + int24 tickUpper; + uint256 amount0Desired; + uint256 amount1Desired; + uint256 amount0Min; + uint256 amount1Min; + address recipient; + uint256 deadline; + } + + function mint( + MintParams calldata params + ) + external + payable + virtual + returns ( + uint256 tokenId, + uint128 liquidity, + uint256 amount0, + uint256 amount1 + ); + + struct IncreaseLiquidityParams { + uint256 tokenId; + uint256 amount0Desired; + uint256 amount1Desired; + uint256 amount0Min; + uint256 amount1Min; + uint256 deadline; + } + + function increaseLiquidity( + IncreaseLiquidityParams calldata params + ) + external + payable + virtual + returns (uint128 liquidity, uint256 amount0, uint256 amount1); + + struct DecreaseLiquidityParams { + uint256 tokenId; + uint128 liquidity; + uint256 amount0Min; + uint256 amount1Min; + uint256 deadline; + } + + function decreaseLiquidity( + DecreaseLiquidityParams calldata params + ) external payable virtual returns (uint256 amount0, uint256 amount1); + + // set amount0Max and amount1Max to uint256.max to collect all fees + struct CollectParams { + uint256 tokenId; + address recipient; + uint128 amount0Max; + uint128 amount1Max; + } + + function collect( + CollectParams calldata params + ) external payable virtual returns (uint256 amount0, uint256 amount1); + + function burn(uint256 tokenId) external payable virtual; + + function positions( + uint256 tokenId + ) + external + view + virtual + returns ( + uint96 nonce, + address operator, + address token0, + address token1, + uint24 fee, + int24 tickLower, + int24 tickUpper, + uint128 liquidity, + uint256 feeGrowthInside0LastX128, + uint256 feeGrowthInside1LastX128, + uint128 tokensOwed0, + uint128 tokensOwed1 + ); + + function balanceOf( + address owner + ) external view virtual returns (uint256 balance); +} diff --git a/evm/contracts/intent-adapters/lp/Sushiswap/SushiswapHelpers.sol b/evm/contracts/intent-adapters/lp/Sushiswap/SushiswapHelpers.sol new file mode 100644 index 0000000..5e06979 --- /dev/null +++ b/evm/contracts/intent-adapters/lp/Sushiswap/SushiswapHelpers.sol @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.18; + +import {ISushiswapNonfungiblePositionManager} from "./Interfaces.sol"; + +contract SushiswapHelpers { + ISushiswapNonfungiblePositionManager + private immutable _nonFungiblePositionManager; + + constructor(address __nonFungiblePositionManager) { + _nonFungiblePositionManager = ISushiswapNonfungiblePositionManager( + __nonFungiblePositionManager + ); + } + + function positionManager() + public + view + returns (ISushiswapNonfungiblePositionManager) + { + return _nonFungiblePositionManager; + } +} diff --git a/evm/contracts/intent-adapters/lp/Sushiswap/SushiswapMint.sol b/evm/contracts/intent-adapters/lp/Sushiswap/SushiswapMint.sol new file mode 100644 index 0000000..6c2a03d --- /dev/null +++ b/evm/contracts/intent-adapters/lp/Sushiswap/SushiswapMint.sol @@ -0,0 +1,158 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.18; + +import {ISushiswapNonfungiblePositionManager} from "./Interfaces.sol"; +import {RouterIntentEoaAdapter, EoaExecutor} from "router-intents/contracts/RouterIntentEoaAdapter.sol"; +import {NitroMessageHandler} from "router-intents/contracts/utils/NitroMessageHandler.sol"; +import {Errors} from "router-intents/contracts/utils/Errors.sol"; +import {DefaultRefundable} from "router-intents/contracts/utils/DefaultRefundable.sol"; +import {IERC20, SafeERC20} from "../../../utils/SafeERC20.sol"; +import {SushiswapHelpers} from "./SushiswapHelpers.sol"; + +/** + * @title SushiswapMint + * @author Yashika Goyal + * @notice Minting a new position on Sushiswap. + */ +contract SushiswapMint is + RouterIntentEoaAdapter, + NitroMessageHandler, + DefaultRefundable, + SushiswapHelpers +{ + using SafeERC20 for IERC20; + + event SushiswapMintPositionDest(); + + constructor( + address __native, + address __wnative, + address __owner, + address __assetForwarder, + address __dexspan, + address __defaultRefundAddress, + address __nonFungiblePositionManager + ) + RouterIntentEoaAdapter(__native, __wnative, __owner) + NitroMessageHandler(__assetForwarder, __dexspan) + DefaultRefundable(__defaultRefundAddress) + SushiswapHelpers(__nonFungiblePositionManager) + // solhint-disable-next-line no-empty-blocks + { + + } + + function name() public pure override returns (string memory) { + return "SushiswapMint"; + } + + /** + * @inheritdoc EoaExecutor + */ + function execute( + address, + address, + bytes calldata data + ) external payable override returns (address[] memory tokens) { + ISushiswapNonfungiblePositionManager.MintParams + memory mintParams = parseInputs(data); + + // If the adapter is called using `call` and not `delegatecall` + if (address(this) == self()) { + if (mintParams.token0 != native()) + IERC20(mintParams.token0).safeTransferFrom( + msg.sender, + self(), + mintParams.amount0Desired + ); + else + require( + msg.value == mintParams.amount0Desired, + Errors.INSUFFICIENT_NATIVE_FUNDS_PASSED + ); + + if (mintParams.token1 != native()) + IERC20(mintParams.token1).safeTransferFrom( + msg.sender, + self(), + mintParams.amount1Desired + ); + else + require( + msg.value == mintParams.amount1Desired, + Errors.INSUFFICIENT_NATIVE_FUNDS_PASSED + ); + } + + if (mintParams.token0 == native()) { + convertNativeToWnative(mintParams.amount0Desired); + mintParams.token0 = wnative(); + } + + if (mintParams.token1 == native()) { + convertNativeToWnative(mintParams.amount0Desired); + mintParams.token1 = wnative(); + } + + IERC20(mintParams.token0).safeIncreaseAllowance( + address(positionManager()), + mintParams.amount0Desired + ); + + IERC20(mintParams.token1).safeIncreaseAllowance( + address(positionManager()), + mintParams.amount1Desired + ); + + bytes memory logData; + + (tokens, logData) = _mint(mintParams); + + emit ExecutionEvent(name(), logData); + return tokens; + } + + /** + * @inheritdoc NitroMessageHandler + */ + function handleMessage( + address tokenSent, + uint256 amount, + bytes memory + ) external override onlyNitro nonReentrant { + withdrawTokens(tokenSent, defaultRefundAddress(), amount); + emit UnsupportedOperation(tokenSent, defaultRefundAddress(), amount); + } + + //////////////////////////// ACTION LOGIC //////////////////////////// + + function _mint( + ISushiswapNonfungiblePositionManager.MintParams memory mintParams + ) internal returns (address[] memory tokens, bytes memory logData) { + (uint256 tokenId, , , ) = positionManager().mint(mintParams); + + tokens = new address[](2); + tokens[0] = mintParams.token0; + tokens[1] = mintParams.token1; + + logData = abi.encode(mintParams, tokenId); + } + + /** + * @dev function to parse input data. + * @param data input data. + */ + function parseInputs( + bytes memory data + ) + public + pure + returns (ISushiswapNonfungiblePositionManager.MintParams memory) + { + return + abi.decode(data, (ISushiswapNonfungiblePositionManager.MintParams)); + } + + // solhint-disable-next-line no-empty-blocks + receive() external payable {} +} diff --git a/evm/contracts/intent-adapters/lp/UniswapV3/Interfaces.sol b/evm/contracts/intent-adapters/lp/UniswapV3/Interfaces.sol new file mode 100644 index 0000000..07600b3 --- /dev/null +++ b/evm/contracts/intent-adapters/lp/UniswapV3/Interfaces.sol @@ -0,0 +1,118 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +pragma solidity 0.8.18; + +abstract contract IUniswapV3NonfungiblePositionManager { + struct MintParams { + address token0; + address token1; + uint24 fee; // for fee of 0.3% -> fee = 3000 + int24 tickLower; + int24 tickUpper; + uint256 amount0Desired; + uint256 amount1Desired; + uint256 amount0Min; + uint256 amount1Min; + address recipient; + uint256 deadline; + } + + function mint( + MintParams calldata params + ) + external + payable + virtual + returns ( + uint256 tokenId, + uint128 liquidity, + uint256 amount0, + uint256 amount1 + ); + + struct IncreaseLiquidityParams { + uint256 tokenId; + uint256 amount0Desired; + uint256 amount1Desired; + uint256 amount0Min; + uint256 amount1Min; + uint256 deadline; + } + + function increaseLiquidity( + IncreaseLiquidityParams calldata params + ) + external + payable + virtual + returns (uint128 liquidity, uint256 amount0, uint256 amount1); + + struct DecreaseLiquidityParams { + uint256 tokenId; + uint128 liquidity; + uint256 amount0Min; + uint256 amount1Min; + uint256 deadline; + } + + function decreaseLiquidity( + DecreaseLiquidityParams calldata params + ) external payable virtual returns (uint256 amount0, uint256 amount1); + + // set amount0Max and amount1Max to uint256.max to collect all fees + struct CollectParams { + uint256 tokenId; + address recipient; + uint128 amount0Max; + uint128 amount1Max; + } + + function collect( + CollectParams calldata params + ) external payable virtual returns (uint256 amount0, uint256 amount1); + + function positions( + uint256 tokenId + ) + external + view + virtual + returns ( + uint96 nonce, + address operator, + address token0, + address token1, + uint24 fee, + int24 tickLower, + int24 tickUpper, + uint128 liquidity, + uint256 feeGrowthInside0LastX128, + uint256 feeGrowthInside1LastX128, + uint128 tokensOwed0, + uint128 tokensOwed1 + ); + + function balanceOf( + address owner + ) external view virtual returns (uint256 balance); + + function tokenOfOwnerByIndex( + address owner, + uint256 index + ) external view virtual returns (uint256 tokenId); + + function approve(address to, uint256 tokenId) public virtual; + + /// @notice Creates a new pool if it does not exist, then initializes if not initialized + /// @dev This method can be bundled with others via IMulticall for the first action (e.g. mint) performed against a pool + /// @param token0 The contract address of token0 of the pool + /// @param token1 The contract address of token1 of the pool + /// @param fee The fee amount of the v3 pool for the specified token pair + /// @param sqrtPriceX96 The initial square root price of the pool as a Q64.96 value + /// @return pool Returns the pool address based on the pair of tokens and fee, will return the newly created pool address if necessary + function createAndInitializePoolIfNecessary( + address token0, + address token1, + uint24 fee, + uint160 sqrtPriceX96 + ) external payable virtual returns (address pool); +} diff --git a/evm/contracts/intent-adapters/lp/UniswapV3/UniswapV3Helpers.sol b/evm/contracts/intent-adapters/lp/UniswapV3/UniswapV3Helpers.sol new file mode 100644 index 0000000..37550f3 --- /dev/null +++ b/evm/contracts/intent-adapters/lp/UniswapV3/UniswapV3Helpers.sol @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.18; + +import {IUniswapV3NonfungiblePositionManager} from "./Interfaces.sol"; + +contract UniswapV3Helpers { + IUniswapV3NonfungiblePositionManager + private immutable _nonFungiblePositionManager; + + constructor(address __nonFungiblePositionManager) { + _nonFungiblePositionManager = IUniswapV3NonfungiblePositionManager( + __nonFungiblePositionManager + ); + } + + function positionManager() + public + view + returns (IUniswapV3NonfungiblePositionManager) + { + return _nonFungiblePositionManager; + } +} diff --git a/evm/contracts/intent-adapters/lp/UniswapV3/UniswapV3Mint.sol b/evm/contracts/intent-adapters/lp/UniswapV3/UniswapV3Mint.sol new file mode 100644 index 0000000..da738b7 --- /dev/null +++ b/evm/contracts/intent-adapters/lp/UniswapV3/UniswapV3Mint.sol @@ -0,0 +1,158 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.18; + +import {IUniswapV3NonfungiblePositionManager} from "./Interfaces.sol"; +import {RouterIntentEoaAdapter, EoaExecutor} from "router-intents/contracts/RouterIntentEoaAdapter.sol"; +import {NitroMessageHandler} from "router-intents/contracts/utils/NitroMessageHandler.sol"; +import {Errors} from "router-intents/contracts/utils/Errors.sol"; +import {DefaultRefundable} from "router-intents/contracts/utils/DefaultRefundable.sol"; +import {IERC20, SafeERC20} from "../../../utils/SafeERC20.sol"; +import {UniswapV3Helpers} from "./UniswapV3Helpers.sol"; + +/** + * @title UniswapV3Mint + * @author Shivam Agrawal + * @notice Minting a new position on Uniswap V3. + */ +contract UniswapV3Mint is + RouterIntentEoaAdapter, + NitroMessageHandler, + DefaultRefundable, + UniswapV3Helpers +{ + using SafeERC20 for IERC20; + + event UniswapV3MintPositionDest(); + + constructor( + address __native, + address __wnative, + address __owner, + address __assetForwarder, + address __dexspan, + address __defaultRefundAddress, + address __nonFungiblePositionManager + ) + RouterIntentEoaAdapter(__native, __wnative, __owner) + NitroMessageHandler(__assetForwarder, __dexspan) + DefaultRefundable(__defaultRefundAddress) + UniswapV3Helpers(__nonFungiblePositionManager) + // solhint-disable-next-line no-empty-blocks + { + + } + + function name() public pure override returns (string memory) { + return "UniswapV3Mint"; + } + + /** + * @inheritdoc EoaExecutor + */ + function execute( + address, + address, + bytes calldata data + ) external payable override returns (address[] memory tokens) { + IUniswapV3NonfungiblePositionManager.MintParams + memory mintParams = parseInputs(data); + + // If the adapter is called using `call` and not `delegatecall` + if (address(this) == self()) { + if (mintParams.token0 != native()) + IERC20(mintParams.token0).safeTransferFrom( + msg.sender, + self(), + mintParams.amount0Desired + ); + else + require( + msg.value == mintParams.amount0Desired, + Errors.INSUFFICIENT_NATIVE_FUNDS_PASSED + ); + + if (mintParams.token1 != native()) + IERC20(mintParams.token1).safeTransferFrom( + msg.sender, + self(), + mintParams.amount1Desired + ); + else + require( + msg.value == mintParams.amount1Desired, + Errors.INSUFFICIENT_NATIVE_FUNDS_PASSED + ); + } + + if (mintParams.token0 == native()) { + convertNativeToWnative(mintParams.amount0Desired); + mintParams.token0 = wnative(); + } + + if (mintParams.token1 == native()) { + convertNativeToWnative(mintParams.amount0Desired); + mintParams.token1 = wnative(); + } + + IERC20(mintParams.token0).safeIncreaseAllowance( + address(positionManager()), + mintParams.amount0Desired + ); + + IERC20(mintParams.token1).safeIncreaseAllowance( + address(positionManager()), + mintParams.amount1Desired + ); + + bytes memory logData; + + (tokens, logData) = _mint(mintParams); + + emit ExecutionEvent(name(), logData); + return tokens; + } + + /** + * @inheritdoc NitroMessageHandler + */ + function handleMessage( + address tokenSent, + uint256 amount, + bytes memory + ) external override onlyNitro nonReentrant { + withdrawTokens(tokenSent, defaultRefundAddress(), amount); + emit UnsupportedOperation(tokenSent, defaultRefundAddress(), amount); + } + + //////////////////////////// ACTION LOGIC //////////////////////////// + + function _mint( + IUniswapV3NonfungiblePositionManager.MintParams memory mintParams + ) internal returns (address[] memory tokens, bytes memory logData) { + (uint256 tokenId, , , ) = positionManager().mint(mintParams); + + tokens = new address[](2); + tokens[0] = mintParams.token0; + tokens[1] = mintParams.token1; + + logData = abi.encode(mintParams, tokenId); + } + + /** + * @dev function to parse input data. + * @param data input data. + */ + function parseInputs( + bytes memory data + ) + public + pure + returns (IUniswapV3NonfungiblePositionManager.MintParams memory) + { + return + abi.decode(data, (IUniswapV3NonfungiblePositionManager.MintParams)); + } + + // solhint-disable-next-line no-empty-blocks + receive() external payable {} +} diff --git a/evm/contracts/intent-adapters/swap/DexSpanAdapter.sol b/evm/contracts/intent-adapters/swap/DexSpanAdapter.sol new file mode 100644 index 0000000..ece5de6 --- /dev/null +++ b/evm/contracts/intent-adapters/swap/DexSpanAdapter.sol @@ -0,0 +1,126 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.18; + +import {IDexSpan} from "../../interfaces/IDexSpan.sol"; +import {RouterIntentEoaAdapter, EoaExecutor} from "router-intents/contracts/RouterIntentEoaAdapter.sol"; +import {NitroMessageHandler} from "router-intents/contracts/utils/NitroMessageHandler.sol"; +import {Errors} from "router-intents/contracts/utils/Errors.sol"; +import {DefaultRefundable} from "router-intents/contracts/utils/DefaultRefundable.sol"; +import {IERC20, SafeERC20} from "../../utils/SafeERC20.sol"; + +/** + * @title DexSpanAdapter + * @author Shivam Agrawal + * @notice Swapping tokens using DexSpan contract + */ +contract DexSpanAdapter is + RouterIntentEoaAdapter, + NitroMessageHandler, + DefaultRefundable +{ + using SafeERC20 for IERC20; + + constructor( + address __native, + address __wnative, + address __owner, + address __assetForwarder, + address __dexspan, + address __defaultRefundAddress + ) + RouterIntentEoaAdapter(__native, __wnative, __owner) + NitroMessageHandler(__assetForwarder, __dexspan) + DefaultRefundable(__defaultRefundAddress) + // solhint-disable-next-line no-empty-blocks + { + + } + + function name() public pure override returns (string memory) { + return "DexSpanAdapter"; + } + + /** + * @inheritdoc EoaExecutor + */ + function execute( + address, + address, + bytes calldata data + ) external payable override returns (address[] memory tokens) { + IDexSpan.SwapParams memory swapData = parseInputs(data); + + // If the adapter is called using `call` and not `delegatecall` + if (address(this) == self()) { + if (address(swapData.tokens[0]) != native()) + swapData.tokens[0].safeTransferFrom( + msg.sender, + self(), + swapData.amount + ); + else + require( + msg.value == swapData.amount, + Errors.INSUFFICIENT_NATIVE_FUNDS_PASSED + ); + } + + bytes memory logData; + + (tokens, logData) = _swap(swapData); + + emit ExecutionEvent(name(), logData); + return tokens; + } + + /** + * @inheritdoc NitroMessageHandler + */ + function handleMessage( + address tokenSent, + uint256 amount, + bytes memory + ) external override onlyNitro nonReentrant { + withdrawTokens(tokenSent, defaultRefundAddress(), amount); + emit UnsupportedOperation(tokenSent, defaultRefundAddress(), amount); + } + + //////////////////////////// ACTION LOGIC //////////////////////////// + + function _swap( + IDexSpan.SwapParams memory _swapData + ) internal returns (address[] memory tokens, bytes memory logData) { + withdrawTokens( + address(_swapData.tokens[0]), + dexspan(), + _swapData.amount + ); + + IDexSpan(dexspan()).swapInSameChain( + _swapData.tokens, + _swapData.amount, + _swapData.minReturn, + _swapData.flags, + _swapData.dataTx, + true, + _swapData.recipient, + 0 + ); + + tokens = new address[](2); + tokens[0] = address(_swapData.tokens[0]); + tokens[1] = address(_swapData.tokens[_swapData.tokens.length - 1]); + + logData = abi.encode(_swapData.tokens, _swapData.amount); + } + + /** + * @dev function to parse input data. + * @param data input data. + */ + function parseInputs( + bytes memory data + ) public pure returns (IDexSpan.SwapParams memory swapData) { + swapData = abi.decode(data, (IDexSpan.SwapParams)); + } +} diff --git a/evm/contracts/interfaces/IAssetForwarder.sol b/evm/contracts/interfaces/IAssetForwarder.sol new file mode 100644 index 0000000..0ac2301 --- /dev/null +++ b/evm/contracts/interfaces/IAssetForwarder.sol @@ -0,0 +1,134 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.18; + +/// @title Interface for handler contracts that support deposits and deposit executions. +/// @author Router Protocol. +interface IAssetForwarder { + event FundsDeposited( + uint256 partnerId, + uint256 amount, + bytes32 destChainIdBytes, + uint256 destAmount, + uint256 depositId, + address srcToken, + address depositor, + bytes recipient, + bytes destToken + ); + + // solhint-disable-next-line event-name-camelcase + event iUSDCDeposited( + uint256 partnerId, + uint256 amount, + bytes32 destChainIdBytes, + uint256 usdcNonce, + address srcToken, + bytes32 recipient, + address depositor + ); + + event FundsDepositedWithMessage( + uint256 partnerId, + uint256 amount, + bytes32 destChainIdBytes, + uint256 destAmount, + uint256 depositId, + address srcToken, + bytes recipient, + address depositor, + bytes destToken, + bytes message + ); + event FundsPaid( + bytes32 messageHash, + address forwarder, + uint256 nonce, + string forwarderRouterAddress + ); + + event DepositInfoUpdate( + address srcToken, + uint256 feeAmount, + uint256 depositId, + uint256 eventNonce, + bool initiatewithdrawal, + address depositor + ); + + event FundsPaidWithMessage( + bytes32 messageHash, + address forwarder, + uint256 nonce, + string forwarderRouterAddress, + bool execFlag, + bytes execData + ); + + struct DestDetails { + uint32 domainId; + uint256 fee; + bool isSet; + } + + struct RelayData { + uint256 amount; + bytes32 srcChainId; + uint256 depositId; + address destToken; + address recipient; + } + + struct RelayDataMessage { + uint256 amount; + bytes32 srcChainId; + uint256 depositId; + address destToken; + address recipient; + bytes message; + } + + function iDepositUSDC( + uint256 partnerId, + bytes32 destChainIdBytes, + bytes32 recipient, + uint256 amount + ) external payable; + + function iDeposit( + uint256 partnerId, + bytes32 destChainIdBytes, + bytes calldata recipient, + address srcToken, + uint256 amount, + uint256 destAmount, + bytes calldata destToken + ) external payable; + + function iDepositInfoUpdate( + address srcToken, + uint256 feeAmount, + uint256 depositId, + bool initiatewithdrawal + ) external payable; + + function iDepositMessage( + uint256 partnerId, + bytes32 destChainIdBytes, + bytes calldata recipient, + address srcToken, + uint256 amount, + uint256 destAmount, + bytes calldata destToken, + bytes memory message + ) external payable; + + function iRelay( + RelayData memory relayData, + string memory forwarderRouterAddress + ) external payable; + + function iRelayMessage( + RelayDataMessage memory relayData, + string memory forwarderRouterAddress + ) external payable; +} diff --git a/evm/contracts/interfaces/IDexSpan.sol b/evm/contracts/interfaces/IDexSpan.sol new file mode 100644 index 0000000..884f290 --- /dev/null +++ b/evm/contracts/interfaces/IDexSpan.sol @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.18; + +import {IERC20} from "../utils/SafeERC20.sol"; + +interface IDexSpan { + struct SwapParams { + IERC20[] tokens; + uint256 amount; + uint256 minReturn; + uint256[] flags; + bytes[] dataTx; + address recipient; + } + + function swapInSameChain( + IERC20[] memory tokens, + uint256 amount, + uint256 minReturn, + uint256[] memory flags, + bytes[] memory dataTx, + bool isWrapper, + address recipient, + uint256 widgetID + ) external payable returns (uint256 returnAmount); +} diff --git a/evm/contracts/interfaces/IERC165.sol b/evm/contracts/interfaces/IERC165.sol new file mode 100644 index 0000000..767f2f0 --- /dev/null +++ b/evm/contracts/interfaces/IERC165.sol @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol) + +pragma solidity 0.8.18; + +/** + * @dev Interface of the ERC165 standard, as defined in the + * https://eips.ethereum.org/EIPS/eip-165[EIP]. + * + * Implementers can declare support of contract interfaces, which can then be + * queried by others ({ERC165Checker}). + * + * For an implementation, see {ERC165}. + */ +interface IERC165 { + /** + * @dev Returns true if this contract implements the interface defined by + * `interfaceId`. See the corresponding + * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] + * to learn more about how these ids are created. + * + * This function call must use less than 30 000 gas. + */ + function supportsInterface(bytes4 interfaceId) external view returns (bool); +} diff --git a/evm/contracts/interfaces/IERC20.sol b/evm/contracts/interfaces/IERC20.sol new file mode 100644 index 0000000..5b76e5b --- /dev/null +++ b/evm/contracts/interfaces/IERC20.sol @@ -0,0 +1,41 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.18; + +interface IERC20 { + function name() external view returns (string memory); + + function symbol() external view returns (string memory); + + function decimals() external view returns (uint8); + + function totalSupply() external view returns (uint256 supply); + + function balanceOf(address _owner) external view returns (uint256 balance); + + function transfer( + address _to, + uint256 _value + ) external returns (bool success); + + function transferFrom( + address _from, + address _to, + uint256 _value + ) external returns (bool success); + + function approve( + address _spender, + uint256 _value + ) external returns (bool success); + + function allowance( + address _owner, + address _spender + ) external view returns (uint256 remaining); + + event Approval( + address indexed _owner, + address indexed _spender, + uint256 _value + ); +} diff --git a/evm/contracts/interfaces/IERC721.sol b/evm/contracts/interfaces/IERC721.sol new file mode 100644 index 0000000..f2aec1a --- /dev/null +++ b/evm/contracts/interfaces/IERC721.sol @@ -0,0 +1,160 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/IERC721.sol) +pragma solidity 0.8.18; + +import {IERC165} from "./IERC165.sol"; + +/** + * @dev Required interface of an ERC721 compliant contract. + */ +interface IERC721 is IERC165 { + /** + * @dev Emitted when `tokenId` token is transferred from `from` to `to`. + */ + event Transfer( + address indexed from, + address indexed to, + uint256 indexed tokenId + ); + + /** + * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. + */ + event Approval( + address indexed owner, + address indexed approved, + uint256 indexed tokenId + ); + + /** + * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. + */ + event ApprovalForAll( + address indexed owner, + address indexed operator, + bool approved + ); + + /** + * @dev Returns the number of tokens in ``owner``'s account. + */ + function balanceOf(address owner) external view returns (uint256 balance); + + /** + * @dev Returns the owner of the `tokenId` token. + * + * Requirements: + * + * - `tokenId` must exist. + */ + function ownerOf(uint256 tokenId) external view returns (address owner); + + /** + * @dev Safely transfers `tokenId` token from `from` to `to`. + * + * Requirements: + * + * - `from` cannot be the zero address. + * - `to` cannot be the zero address. + * - `tokenId` token must exist and be owned by `from`. + * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. + * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon + * a safe transfer. + * + * Emits a {Transfer} event. + */ + function safeTransferFrom( + address from, + address to, + uint256 tokenId, + bytes calldata data + ) external; + + /** + * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients + * are aware of the ERC721 protocol to prevent tokens from being forever locked. + * + * Requirements: + * + * - `from` cannot be the zero address. + * - `to` cannot be the zero address. + * - `tokenId` token must exist and be owned by `from`. + * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or + * {setApprovalForAll}. + * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon + * a safe transfer. + * + * Emits a {Transfer} event. + */ + function safeTransferFrom( + address from, + address to, + uint256 tokenId + ) external; + + /** + * @dev Transfers `tokenId` token from `from` to `to`. + * + * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721 + * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must + * understand this adds an external call which potentially creates a reentrancy vulnerability. + * + * Requirements: + * + * - `from` cannot be the zero address. + * - `to` cannot be the zero address. + * - `tokenId` token must be owned by `from`. + * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. + * + * Emits a {Transfer} event. + */ + function transferFrom(address from, address to, uint256 tokenId) external; + + /** + * @dev Gives permission to `to` to transfer `tokenId` token to another account. + * The approval is cleared when the token is transferred. + * + * Only a single account can be approved at a time, so approving the zero address clears previous approvals. + * + * Requirements: + * + * - The caller must own the token or be an approved operator. + * - `tokenId` must exist. + * + * Emits an {Approval} event. + */ + function approve(address to, uint256 tokenId) external; + + /** + * @dev Approve or remove `operator` as an operator for the caller. + * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. + * + * Requirements: + * + * - The `operator` cannot be the address zero. + * + * Emits an {ApprovalForAll} event. + */ + function setApprovalForAll(address operator, bool approved) external; + + /** + * @dev Returns the account approved for `tokenId` token. + * + * Requirements: + * + * - `tokenId` must exist. + */ + function getApproved( + uint256 tokenId + ) external view returns (address operator); + + /** + * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. + * + * See {setApprovalForAll} + */ + function isApprovedForAll( + address owner, + address operator + ) external view returns (bool); +} diff --git a/evm/contracts/interfaces/IWETH.sol b/evm/contracts/interfaces/IWETH.sol new file mode 100644 index 0000000..e29870d --- /dev/null +++ b/evm/contracts/interfaces/IWETH.sol @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.18; + +import {IERC20} from "../utils/SafeERC20.sol"; + +abstract contract IWETH { + function allowance(address, address) public view virtual returns (uint256); + + function balanceOf(address) public view virtual returns (uint256); + + function approve(address, uint256) public virtual; + + function transfer(address, uint256) public virtual returns (bool); + + function transferFrom( + address, + address, + uint256 + ) public virtual returns (bool); + + function deposit() public payable virtual; + + function withdraw(uint256) public virtual; +} diff --git a/evm/contracts/mocks/MockAssetForwarder.sol b/evm/contracts/mocks/MockAssetForwarder.sol new file mode 100644 index 0000000..fd71286 --- /dev/null +++ b/evm/contracts/mocks/MockAssetForwarder.sol @@ -0,0 +1,59 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.18; + +import {IERC20, SafeERC20} from "../utils/SafeERC20.sol"; + +contract MockAssetForwarder { + using SafeERC20 for IERC20; + address public constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; + + error InvalidAmount(); + error ExecutionFailed(); + + function iDeposit( + uint256, + bytes32, + bytes calldata, + address srcToken, + uint256 amount, + uint256, + bytes calldata + ) external payable { + if (srcToken != ETH) { + IERC20(srcToken).safeTransferFrom( + msg.sender, + address(this), + amount + ); + } else { + if (msg.value != amount) { + revert InvalidAmount(); + } + } + } + + function handleMessage( + address tokenSent, + uint256 amount, + bytes memory instruction, + address recipient + ) external payable { + if (tokenSent != ETH) { + IERC20(tokenSent).safeTransferFrom(msg.sender, recipient, amount); + } else { + if (msg.value != amount) { + revert InvalidAmount(); + } + payable(recipient).transfer(amount); + } + + // solhint-disable-next-line avoid-low-level-calls + (bool success, ) = recipient.call( + abi.encodeWithSelector(0xd00a2d5f, tokenSent, amount, instruction) + ); + + if (!success) { + revert ExecutionFailed(); + } + } +} diff --git a/evm/contracts/mocks/MockToken.sol b/evm/contracts/mocks/MockToken.sol new file mode 100644 index 0000000..bcd215d --- /dev/null +++ b/evm/contracts/mocks/MockToken.sol @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.18; + +import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; + +contract MockToken is ERC20 { + // solhint-disable-next-line no-empty-blocks + constructor() ERC20("Token", "TKN") {} + + function mint(address recipient, uint256 amount) external { + _mint(recipient, amount); + } +} diff --git a/evm/contracts/utils/Address.sol b/evm/contracts/utils/Address.sol new file mode 100644 index 0000000..d7b8e19 --- /dev/null +++ b/evm/contracts/utils/Address.sol @@ -0,0 +1,113 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.18; + +library Address { + //insufficient balance + error InsufficientBalance(uint256 available, uint256 required); + //unable to send value, recipient may have reverted + error SendingValueFail(); + //insufficient balance for call + error InsufficientBalanceForCall(uint256 available, uint256 required); + //call to non-contract + error NonContractCall(); + + function isContract(address account) internal view returns (bool) { + // According to EIP-1052, 0x0 is the value returned for not-yet created accounts + // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned + // for accounts without code, i.e. `keccak256('')` + bytes32 codehash; + bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; + // solhint-disable-next-line no-inline-assembly + assembly { + codehash := extcodehash(account) + } + return (codehash != accountHash && codehash != 0x0); + } + + function sendValue(address payable recipient, uint256 amount) internal { + uint256 balance = address(this).balance; + if (balance < amount) { + revert InsufficientBalance(balance, amount); + } + + // solhint-disable-next-line avoid-low-level-calls, avoid-call-value + (bool success, ) = recipient.call{value: amount}(""); + if (!(success)) { + revert SendingValueFail(); + } + } + + function functionCall( + address target, + bytes memory data + ) internal returns (bytes memory) { + return functionCall(target, data, "Address: low-level call failed"); + } + + function functionCall( + address target, + bytes memory data, + string memory errorMessage + ) internal returns (bytes memory) { + return _functionCallWithValue(target, data, 0, errorMessage); + } + + function functionCallWithValue( + address target, + bytes memory data, + uint256 value + ) internal returns (bytes memory) { + return + functionCallWithValue( + target, + data, + value, + "Address: low-level call with value failed" + ); + } + + function functionCallWithValue( + address target, + bytes memory data, + uint256 value, + string memory errorMessage + ) internal returns (bytes memory) { + uint256 balance = address(this).balance; + if (balance < value) { + revert InsufficientBalanceForCall(balance, value); + } + return _functionCallWithValue(target, data, value, errorMessage); + } + + function _functionCallWithValue( + address target, + bytes memory data, + uint256 weiValue, + string memory errorMessage + ) private returns (bytes memory) { + if (!(isContract(target))) { + revert NonContractCall(); + } + + // solhint-disable-next-line avoid-low-level-calls + (bool success, bytes memory returndata) = target.call{value: weiValue}( + data + ); + if (success) { + return returndata; + } else { + // Look for revert reason and bubble it up if present + if (returndata.length > 0) { + // The easiest way to bubble the revert reason is using memory via assembly + + // solhint-disable-next-line no-inline-assembly + assembly { + let returndata_size := mload(returndata) + revert(add(32, returndata), returndata_size) + } + } else { + revert(errorMessage); + } + } + } +} diff --git a/evm/contracts/utils/ReentrancyGuard.sol b/evm/contracts/utils/ReentrancyGuard.sol new file mode 100644 index 0000000..2ecc8b9 --- /dev/null +++ b/evm/contracts/utils/ReentrancyGuard.sol @@ -0,0 +1,50 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.18; + +abstract contract ReentrancyGuard { + // Booleans are more expensive than uint256 or any type that takes up a full + // word because each write operation emits an extra SLOAD to first read the + // slot's contents, replace the bits taken up by the boolean, and then write + // back. This is the compiler's defense against contract upgrades and + // pointer aliasing, and it cannot be disabled. + + // The values being non-zero value makes deployment a bit more expensive, + // but in exchange the refund on every call to nonReentrant will be lower in + // amount. Since refunds are capped to a percentage of the total + // transaction's gas, it is best to keep them low in cases like this one, to + // increase the likelihood of the full refund coming into effect. + uint256 private constant _NOT_ENTERED = 1; + uint256 private constant _ENTERED = 2; + + uint256 private _status; + + error ReentrantCall(); + + constructor() { + _status = _NOT_ENTERED; + } + + /** + * @dev Prevents a contract from calling itself, directly or indirectly. + * Calling a `nonReentrant` function from another `nonReentrant` + * function is not supported. It is possible to prevent this from happening + * by making the `nonReentrant` function external, and make it call a + * `private` function that does the actual work. + */ + modifier nonReentrant() { + // On the first call to nonReentrant, _notEntered will be true + if (_status == _ENTERED) { + revert ReentrantCall(); + } + + // Any calls to nonReentrant after this point will fail + _status = _ENTERED; + + _; + + // By storing the original value once again, a refund is triggered (see + // https://eips.ethereum.org/EIPS/eip-2200) + _status = _NOT_ENTERED; + } +} diff --git a/evm/contracts/utils/SafeERC20.sol b/evm/contracts/utils/SafeERC20.sol new file mode 100644 index 0000000..40c571a --- /dev/null +++ b/evm/contracts/utils/SafeERC20.sol @@ -0,0 +1,98 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.18; + +import {IERC20} from "../interfaces/IERC20.sol"; +import {Address} from "./Address.sol"; +import {SafeMath} from "./SafeMath.sol"; + +library SafeERC20 { + using SafeMath for uint256; + using Address for address; + + function safeTransfer(IERC20 token, address to, uint256 value) internal { + _callOptionalReturn( + token, + abi.encodeWithSelector(token.transfer.selector, to, value) + ); + } + + function safeTransferFrom( + IERC20 token, + address from, + address to, + uint256 value + ) internal { + _callOptionalReturn( + token, + abi.encodeWithSelector(token.transferFrom.selector, from, to, value) + ); + } + + /// @dev Edited so it always first approves 0 and then the value, because of non standard tokens + function safeApprove( + IERC20 token, + address spender, + uint256 value + ) internal { + _callOptionalReturn( + token, + abi.encodeWithSelector(token.approve.selector, spender, 0) + ); + _callOptionalReturn( + token, + abi.encodeWithSelector(token.approve.selector, spender, value) + ); + } + + function safeIncreaseAllowance( + IERC20 token, + address spender, + uint256 value + ) internal { + uint256 newAllowance = token.allowance(address(this), spender).add( + value + ); + _callOptionalReturn( + token, + abi.encodeWithSelector( + token.approve.selector, + spender, + newAllowance + ) + ); + } + + function safeDecreaseAllowance( + IERC20 token, + address spender, + uint256 value + ) internal { + uint256 newAllowance = token.allowance(address(this), spender).sub( + value, + "SafeERC20: decreased allowance below zero" + ); + _callOptionalReturn( + token, + abi.encodeWithSelector( + token.approve.selector, + spender, + newAllowance + ) + ); + } + + function _callOptionalReturn(IERC20 token, bytes memory data) private { + bytes memory returndata = address(token).functionCall( + data, + "SafeERC20: low-level call failed" + ); + if (returndata.length > 0) { + // Return data is optional + // solhint-disable-next-line max-line-length + require( + abi.decode(returndata, (bool)), + "SafeERC20: operation failed" + ); + } + } +} diff --git a/evm/contracts/utils/SafeMath.sol b/evm/contracts/utils/SafeMath.sol new file mode 100644 index 0000000..a0bb1e4 --- /dev/null +++ b/evm/contracts/utils/SafeMath.sol @@ -0,0 +1,69 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.18; + +library SafeMath { + function add(uint256 a, uint256 b) internal pure returns (uint256) { + uint256 c = a + b; + require(c >= a, "SafeMath: addition overflow"); + + return c; + } + + function sub(uint256 a, uint256 b) internal pure returns (uint256) { + return sub(a, b, "SafeMath: subtraction overflow"); + } + + function sub( + uint256 a, + uint256 b, + string memory errorMessage + ) internal pure returns (uint256) { + require(b <= a, errorMessage); + uint256 c = a - b; + + return c; + } + + function mul(uint256 a, uint256 b) internal pure returns (uint256) { + // Gas optimization: this is cheaper than requiring 'a' not being zero, but the + // benefit is lost if 'b' is also tested. + // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 + if (a == 0) { + return 0; + } + + uint256 c = a * b; + require(c / a == b, "SafeMath: mul overflow"); + + return c; + } + + function div(uint256 a, uint256 b) internal pure returns (uint256) { + return div(a, b, "SafeMath: division by zero"); + } + + function div( + uint256 a, + uint256 b, + string memory errorMessage + ) internal pure returns (uint256) { + require(b > 0, errorMessage); + uint256 c = a / b; + // assert(a == b * c + a % b); // There is no case in which this doesn't hold + + return c; + } + + function mod(uint256 a, uint256 b) internal pure returns (uint256) { + return mod(a, b, "SafeMath: modulo by zero"); + } + + function mod( + uint256 a, + uint256 b, + string memory errorMessage + ) internal pure returns (uint256) { + require(b != 0, errorMessage); + return a % b; + } +} diff --git a/evm/deployment/deployments.json b/evm/deployment/deployments.json new file mode 100644 index 0000000..8068488 --- /dev/null +++ b/evm/deployment/deployments.json @@ -0,0 +1 @@ +{"testnet":{"5":{"StaderStakeEth":"0x06B8207cf2fC3F4AFa38fbA9E99d401d01750CB8","BatchTransaction":"0x81B8743b9e8454e910aFD2Ea52845B993CA54faE","DexSpanAdapter":"0xb37a4D800a9AF6E142b8078F1392122E06762aA6","SwellStakeEth":"0xF99cC97E0d8DCBa8c3b802F7ae7660f53B2E2C27","LidoStakeEth":"0xceF0795f20d37Afd1F651DC3Cf62fda3a1ffa285","LidoStakeMatic":"0xf70e0fc433A4bD6524684623B81D8349e2553B04","MetaPoolStakeEth":"0xDc42915f788729f64E813c75F290Ff68be7148eb"},"43113":{"AaveV3Supply":"0xCDd33Bcb542d8095D6A4C7142d393c008dCd2691","AaveV3Borrow":"0x03607a998a563548b98A4B6F6906fb80D84C3746"},"80001":{"DexSpanAdapter":"0xA6d70E82Ed1F8a93dfE6350f9D846cBe6C75543A","AaveV3Supply":"0xE51eB3318d9616f8D84A23f4C05d1360E43F2Fa5","BatchTransaction":"0x4c5CfbD2967E399bcf2f326647F50FBDEEa1323A","AaveV3Borrow":"0x7a0DbcF70CAd57515B34d971A6eB545336ae7375"}}} \ No newline at end of file diff --git a/evm/hardhat.config.ts b/evm/hardhat.config.ts new file mode 100644 index 0000000..0c55f25 --- /dev/null +++ b/evm/hardhat.config.ts @@ -0,0 +1,309 @@ +import * as dotenv from "dotenv"; + +import { HardhatUserConfig, task } from "hardhat/config"; +import "@nomiclabs/hardhat-etherscan"; +import "@nomiclabs/hardhat-waffle"; +import "@typechain/hardhat"; +import "hardhat-gas-reporter"; +import "solidity-coverage"; +import "solidity-docgen"; +import "hardhat-deploy"; +import "@nomiclabs/hardhat-ethers"; +import "hardhat-dependency-compiler"; +import "./tasks"; + +dotenv.config(); + +// This is a sample Hardhat task. To learn how to create your own go to +// https://hardhat.org/guides/create-task.html +task("accounts", "Prints the list of accounts", async (taskArgs, hre) => { + const accounts = await hre.ethers.getSigners(); + + for (const account of accounts) { + console.log(account.address); + } +}); + +// You need to export an object to set up your config +// Go to https://hardhat.org/config/ to learn more + +const config: HardhatUserConfig = { + paths: { + artifacts: "artifacts", + cache: "cache", + deploy: "src/deploy", + sources: "contracts", + }, + mocha: { + timeout: 1000000, + }, + namedAccounts: { + deployer: 0, + verifiedSigner: 5, + }, + solidity: { + compilers: [ + { + version: "0.8.18", + settings: { + optimizer: { enabled: true, runs: 1000000 }, + viaIR: true, + }, + }, + ], + }, + networks: { + hardhat: { + accounts: { + accountsBalance: "10000000000000000000000000", + }, + allowUnlimitedContractSize: true, + chainId: 31337, + }, + ganache: { + chainId: 1337, + url: "http://localhost:8545", + accounts: { + mnemonic: + "garbage miracle journey siren inch method pulse learn month grid frame business", + path: "m/44'/60'/0'/0", + initialIndex: 0, + count: 20, + }, + }, + mainnet: { + url: process.env.ETH_MAINNET_URL || "", + chainId: 1, + accounts: + process.env.PRIVATE_KEY !== undefined + ? [process.env.PRIVATE_KEY] + : [""], + }, + goerli: { + url: process.env.GOERLI_URL || "", + chainId: 5, + accounts: + process.env.PRIVATE_KEY !== undefined + ? [process.env.PRIVATE_KEY] + : [""], + }, + holesky: { + url: process.env.HOLESKY_URL || "", + chainId: 17000, + accounts: + process.env.PRIVATE_KEY !== undefined + ? [process.env.PRIVATE_KEY] + : [""], + }, + polygon: { + url: process.env.POLYGON_URL || "", + chainId: 137, + accounts: + process.env.PRIVATE_KEY !== undefined + ? [process.env.PRIVATE_KEY] + : [""], + }, + polygonMumbai: { + url: process.env.POLYGON_MUMBAI_URL || "", + chainId: 80001, + accounts: + process.env.PRIVATE_KEY !== undefined + ? [process.env.PRIVATE_KEY] + : [""], + }, + bsc: { + url: "https://bsc-dataseed2.binance.org", + chainId: 56, + accounts: + process.env.PRIVATE_KEY !== undefined + ? [process.env.PRIVATE_KEY] + : [""], + }, + bscTestnet: { + url: + process.env.BSC_TESTNET_URL || + "https://wandering-broken-tree.bsc-testnet.quiknode.pro/7992da20f9e4f97c2a117bea9af37c1c266f63ec/", + chainId: 97, + accounts: + process.env.PRIVATE_KEY !== undefined + ? [process.env.PRIVATE_KEY] + : [""], + gasPrice: 50e9, + }, + fantom: { + url: + process.env.FANTOM_URL || + "https://fantom.blockpi.network/v1/rpc/public", + accounts: + process.env.PRIVATE_KEY !== undefined + ? [process.env.PRIVATE_KEY] + : [""], + chainId: 250, + }, + fantomTest: { + url: "https://rpc.ankr.com/fantom_testnet", + accounts: + process.env.PRIVATE_KEY !== undefined + ? [process.env.PRIVATE_KEY] + : [""], + chainId: 4002, + }, + avalanche: { + url: "https://api.avax.network/ext/bc/C/rpc", + accounts: + process.env.PRIVATE_KEY !== undefined + ? [process.env.PRIVATE_KEY] + : [""], + chainId: 43114, + }, + avalancheFuji: { + url: "https://api.avax-test.network/ext/bc/C/rpc", + accounts: + process.env.PRIVATE_KEY !== undefined + ? [process.env.PRIVATE_KEY] + : [""], + chainId: 43113, + }, + arbitrum: { + url: "https://arb1.arbitrum.io/rpc", + accounts: + process.env.PRIVATE_KEY !== undefined + ? [process.env.PRIVATE_KEY] + : [""], + chainId: 42161, + }, + arbitrumGoerli: { + url: "https://goerli-rollup.arbitrum.io/rpc", + accounts: + process.env.PRIVATE_KEY !== undefined + ? [process.env.PRIVATE_KEY] + : [""], + chainId: 421613, + }, + arbitrumRinkeby: { + url: "https://rinkeby.arbitrum.io/rpc", + accounts: + process.env.PRIVATE_KEY !== undefined + ? [process.env.PRIVATE_KEY] + : [""], + chainId: 421611, + }, + arbitrumNova: { + url: "https://nova.arbitrum.io/rpc", + accounts: + process.env.PRIVATE_KEY !== undefined + ? [process.env.PRIVATE_KEY] + : [""], + chainId: 42170, + }, + zkevm: { + url: process.env.ZKEVM_MAINNET_URL || "https://zkevm-rpc.com", + chainId: 1101, + accounts: + process.env.PRIVATE_KEY !== undefined + ? [process.env.PRIVATE_KEY] + : [""], + }, + zkevmTestnet: { + url: process.env.ZKEVM_TESTNET_URL || "https://rpc.public.zkevm-test.net", + chainId: 1442, + accounts: + process.env.PRIVATE_KEY !== undefined + ? [process.env.PRIVATE_KEY] + : [""], + }, + optimismGoerli: { + url: `https://goerli.optimism.io`, + accounts: + process.env.PRIVATE_KEY !== undefined + ? [process.env.PRIVATE_KEY] + : [""], + chainId: 420, + }, + optimism: { + url: `https://mainnet.optimism.io`, + accounts: + process.env.PRIVATE_KEY !== undefined + ? [process.env.PRIVATE_KEY] + : [""], + chainId: 10, + }, + moonbeam: { + url: "https://rpc.api.moonbeam.network", + chainId: 1284, + accounts: + process.env.PRIVATE_KEY !== undefined + ? [process.env.PRIVATE_KEY] + : [""], + }, + moonbeamTestnet: { + url: "https://rpc.api.moonbase.moonbeam.network", + accounts: + process.env.PRIVATE_KEY !== undefined + ? [process.env.PRIVATE_KEY] + : [""], + chainId: 1287, + }, + celoTestnet: { + url: `https://alfajores-forno.celo-testnet.org`, + accounts: + process.env.PRIVATE_KEY !== undefined + ? [process.env.PRIVATE_KEY] + : [""], + chainId: 44787, + // gasPrice: 6400000 + }, + celo: { + url: `https://forno.celo.org`, + accounts: + process.env.PRIVATE_KEY !== undefined + ? [process.env.PRIVATE_KEY] + : [""], + chainId: 42220, + // gasPrice: 6400000 + }, + neonDevnet: { + url: `https://proxy.devnet.neonlabs.org/solana`, + accounts: + process.env.PRIVATE_KEY !== undefined + ? [process.env.PRIVATE_KEY] + : [""], + chainId: 245022926, + // gasPrice: 6400000 + }, + }, + + gasReporter: { + outputFile: "gas-report.txt", + enabled: process.env.REPORT_GAS !== undefined, + currency: "USD", + noColors: true, + coinmarketcap: process.env.COIN_MARKETCAP_API_KEY || "", + token: "ETH", + }, + + etherscan: { + apiKey: { + mainnet: process.env.ETHERSCAN_API_KEY || "", + goerli: process.env.ETHERSCAN_API_KEY || "", + holesky: process.env.ETHERSCAN_API_KEY || "", + polygonMumbai: process.env.POLYGONSCAN_API_KEY || "", + polygon: process.env.POLYGONSCAN_API_KEY || "", + opera: process.env.FTMSCAN_API_KEY || "", + ftmTestnet: process.env.FTMSCAN_API_KEY || "", + bscTestnet: process.env.BSCSCAN_API_KEY || "", + bsc: process.env.BSCSCAN_API_KEY || "", + moonbeam: process.env.MOONBEAM_KEY || "", + moonbaseAlpha: process.env.MOONBEAM_KEY || "", + avalancheFujiTestnet: process.env.AVALANCHE_API_KEY || "", + avalanche: process.env.AVALANCHE_API_KEY || "", + arbitrumGoerli: process.env.ARBITRUM_API_KEY || "", + arbitrumTestnet: process.env.ARBITRUM_API_KEY || "", + arbitrumOne: process.env.ARBITRUM_API_KEY || "", + optimisticGoerli: process.env.OPTIMISTIC_API_KEY || "", + optimisticEthereum: process.env.OPTIMISTIC_API_KEY || "", + }, + }, +}; + +export default config; diff --git a/evm/package.json b/evm/package.json new file mode 100644 index 0000000..9c37284 --- /dev/null +++ b/evm/package.json @@ -0,0 +1,93 @@ +{ + "name": "router-intents-eoa", + "version": "1.0.0", + "description": "Smart contracts implementing Router Intents with cross chain compatibility using Router Nitro", + "main": "index.js", + "scripts": { + "clean": "npx hardhat clean", + "build": "npm run clean && npx hardhat compile", + "test": "npx hardhat test", + "lint": "prettier --write 'contracts/**/*.sol'", + "postinstall": "husky install .husky", + "prepack": "pinst --disable", + "postpack": "pinst --enable", + "coverage": "COVERAGE=1 DISABLE_VIA_IR=true hardhat coverage", + "prepare": "husky install .husky", + "compile": "npx hardhat compile", + "ci:clean": "rm -rf ./artifacts ./cache", + "compile:clean": "npm run ci:clean && npm run compile", + "docgen": "npx hardhat docgen" + }, + "keywords": [ + "blockchain", + "ethereum", + "hardhat", + "smart-contracts", + "solidity" + ], + "author": "", + "license": "ISC", + "devDependencies": { + "@nomiclabs/hardhat-ethers": "npm:hardhat-deploy-ethers@^0.3.0-beta.13", + "@nomiclabs/hardhat-etherscan": "^3.1.7", + "@nomiclabs/hardhat-truffle5": "^2.0.6", + "@nomiclabs/hardhat-waffle": "^2.0.3", + "@nomiclabs/hardhat-web3": "^2.0.0", + "@openzeppelin/contracts": "4.9.3", + "@typechain/ethers-v5": "^7.2.0", + "@typechain/hardhat": "^2.3.1", + "@types/chai": "^4.3.1", + "@types/chai-as-promised": "^7.1.5", + "@types/chai-string": "^1.4.2", + "@types/mocha": "^9.1.1", + "@types/node": "^12.20.54", + "@typescript-eslint/eslint-plugin": "^4.33.0", + "@typescript-eslint/parser": "^4.33.0", + "@uniswap/sdk-core": "^4.0.9", + "@uniswap/v3-core": "^1.0.1", + "@uniswap/v3-sdk": "^3.10.0", + "bignumber.js": "^9.1.2", + "chai": "^4.3.6", + "chai-as-promised": "^7.1.1", + "chai-string": "^1.5.0", + "dotenv": "^16.0.1", + "eslint": "^7.32.0", + "eslint-config-prettier": "^8.5.0", + "eslint-config-standard": "^16.0.3", + "eslint-plugin-import": "^2.26.0", + "eslint-plugin-node": "^11.1.0", + "eslint-plugin-prettier": "^3.4.1", + "eslint-plugin-promise": "^5.2.0", + "ethereum-waffle": "^4.0.10", + "ethers": "^5.7.2", + "hardhat": "^2.9.7", + "hardhat-dependency-compiler": "^1.1.3", + "hardhat-deploy": "^0.11.26", + "hardhat-gas-reporter": "^1.0.8", + "husky": "^8.0.3", + "pinst": "^3.0.0", + "prettier": "^2.6.2", + "prettier-plugin-solidity": "^1.1.2", + "solc": "^0.8.15", + "solhint": "^3.3.7", + "solhint-plugin-prettier": "^0.0.5", + "solidity-coverage": "^0.8.2", + "ts-node": "^10.8.1", + "typechain": "^8.3.1", + "typescript": "^4.7.3", + "web3": "^1.7.4" + }, + "dependencies": { + "@ethersproject/abstract-signer": "^5.6.2", + "@ethersproject/constants": "^5.6.1", + "axios": "^1.5.0", + "ethereumjs-util": "^7.1.0", + "router-intents": "^4.0.1", + "solidity-docgen": "^0.6.0-beta.36" + }, + "husky": { + "hooks": { + "pre-commit": "" + } + } +} diff --git a/evm/tasks/BatchTransaction.deploy.ts b/evm/tasks/BatchTransaction.deploy.ts new file mode 100644 index 0000000..4377464 --- /dev/null +++ b/evm/tasks/BatchTransaction.deploy.ts @@ -0,0 +1,83 @@ +import { HardhatRuntimeEnvironment, TaskArguments } from "hardhat/types"; +import { + ASSET_FORWARDER, + CONTRACT_NAME, + DEFAULT_ENV, + DEPLOY_BATCH_TRANSACTION, + DEXSPAN, + NATIVE, + VERIFY_BATCH_TRANSACTION, + WNATIVE, +} from "./constants"; +import { task } from "hardhat/config"; +import { + IDeployment, + getDeployments, + recordAllDeployments, + saveDeployments, +} from "./utils"; + +const contractName: string = CONTRACT_NAME.BatchTransaction; + +task(DEPLOY_BATCH_TRANSACTION) + .addFlag("verify", "pass true to verify the contract") + .setAction(async function ( + _taskArguments: TaskArguments, + _hre: HardhatRuntimeEnvironment + ) { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + + const network = await _hre.getChainId(); + + console.log(`Deploying ${contractName} Contract on chainId ${network}....`); + const factory = await _hre.ethers.getContractFactory(contractName); + const instance = await factory.deploy( + NATIVE, + WNATIVE[env][network], + ASSET_FORWARDER[env][network], + DEXSPAN[env][network] + ); + await instance.deployed(); + + const deployment: IDeployment = await recordAllDeployments( + env, + network, + contractName, + instance.address + ); + + await saveDeployments(deployment); + + console.log(`${contractName} contract deployed at`, instance.address); + + if (_taskArguments.verify === true) { + await _hre.run(VERIFY_BATCH_TRANSACTION); + } + }); + +task(VERIFY_BATCH_TRANSACTION).setAction(async function ( + _taskArguments: TaskArguments, + _hre: HardhatRuntimeEnvironment +) { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + + const network = await _hre.getChainId(); + + const deployments: IDeployment = getDeployments(); + const address = deployments[env][network][contractName]; + + console.log(`Verifying ${contractName} Contract....`); + await _hre.run("verify:verify", { + address, + constructorArguments: [ + NATIVE, + WNATIVE[env][network], + ASSET_FORWARDER[env][network], + DEXSPAN[env][network], + ], + }); + + console.log(`Verified ${contractName} contract address `, address); +}); diff --git a/evm/tasks/aaveV3/AaveV3Borrow.deploy.ts b/evm/tasks/aaveV3/AaveV3Borrow.deploy.ts new file mode 100644 index 0000000..56c152c --- /dev/null +++ b/evm/tasks/aaveV3/AaveV3Borrow.deploy.ts @@ -0,0 +1,112 @@ +import { HardhatRuntimeEnvironment, TaskArguments } from "hardhat/types"; +import { + ASSET_FORWARDER, + CONTRACT_NAME, + DEFAULT_ENV, + DEFAULT_OWNER, + DEFAULT_REFUND_ADDRESS, + DEPLOY_AAVE_V3_BORROW_ADAPTER, + DEXSPAN, + NATIVE, + VERIFY_AAVE_V3_BORROW_ADAPTER, + WNATIVE, +} from "../constants"; +import { task } from "hardhat/config"; +import { + IDeployment, + getDeployments, + recordAllDeployments, + saveDeployments, +} from "../utils"; +import { + AAVE_V3_POOL, + AAVE_V3_REFERRAL_CODE, + AAVE_V3_WRAPPED_TOKEN_GATEWAY, +} from "./constants"; + +const contractName: string = CONTRACT_NAME.AaveV3Borrow; + +task(DEPLOY_AAVE_V3_BORROW_ADAPTER) + .addFlag("verify", "pass true to verify the contract") + .setAction(async function ( + _taskArguments: TaskArguments, + _hre: HardhatRuntimeEnvironment + ) { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + + let defaultRefundAddress = process.env.DEFAULT_REFUND_ADDRESS; + if (!defaultRefundAddress) defaultRefundAddress = DEFAULT_REFUND_ADDRESS; + + let owner = process.env.OWNER; + if (!owner) owner = DEFAULT_OWNER; + + const network = await _hre.getChainId(); + + console.log(`Deploying ${contractName} Contract on chainId ${network}....`); + const factory = await _hre.ethers.getContractFactory(contractName); + const instance = await factory.deploy( + NATIVE, + WNATIVE[env][network], + owner, + ASSET_FORWARDER[env][network], + DEXSPAN[env][network], + defaultRefundAddress, + AAVE_V3_POOL[network], + AAVE_V3_WRAPPED_TOKEN_GATEWAY[network], + AAVE_V3_REFERRAL_CODE + ); + await instance.deployed(); + + const deployment: IDeployment = await recordAllDeployments( + env, + network, + contractName, + instance.address + ); + + await saveDeployments(deployment); + + console.log(`${contractName} contract deployed at`, instance.address); + + if (_taskArguments.verify === true) { + await _hre.run(VERIFY_AAVE_V3_BORROW_ADAPTER); + } + }); + +task(VERIFY_AAVE_V3_BORROW_ADAPTER).setAction(async function ( + _taskArguments: TaskArguments, + _hre: HardhatRuntimeEnvironment +) { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + + let defaultRefundAddress = process.env.DEFAULT_REFUND_ADDRESS; + if (!defaultRefundAddress) defaultRefundAddress = DEFAULT_REFUND_ADDRESS; + + let owner = process.env.OWNER; + if (!owner) owner = DEFAULT_OWNER; + + const network = await _hre.getChainId(); + + const deployments: IDeployment = getDeployments(); + const address = deployments[env][network][contractName]; + + console.log(`Verifying ${contractName} Contract....`); + await _hre.run("verify:verify", { + address, + constructorArguments: [ + NATIVE, + WNATIVE[env][network], + owner, + ASSET_FORWARDER[env][network], + DEXSPAN[env][network], + defaultRefundAddress, + AAVE_V3_POOL[network], + AAVE_V3_WRAPPED_TOKEN_GATEWAY[network], + AAVE_V3_REFERRAL_CODE, + ], + }); + + console.log(`Verified ${contractName} contract address `, address); +}); diff --git a/evm/tasks/aaveV3/AaveV3Supply.deploy.ts b/evm/tasks/aaveV3/AaveV3Supply.deploy.ts new file mode 100644 index 0000000..bb05567 --- /dev/null +++ b/evm/tasks/aaveV3/AaveV3Supply.deploy.ts @@ -0,0 +1,110 @@ +import { HardhatRuntimeEnvironment, TaskArguments } from "hardhat/types"; +import { + ASSET_FORWARDER, + CONTRACT_NAME, + DEFAULT_ENV, + DEFAULT_OWNER, + DEFAULT_REFUND_ADDRESS, + DEPLOY_AAVE_V3_SUPPLY_ADAPTER, + DEXSPAN, + NATIVE, + VERIFY_AAVE_V3_SUPPLY_ADAPTER, + WNATIVE, +} from "../constants"; +import { task } from "hardhat/config"; +import { + IDeployment, + getDeployments, + recordAllDeployments, + saveDeployments, +} from "../utils"; +import { + AAVE_V3_POOL, + AAVE_V3_REFERRAL_CODE, + AAVE_V3_WRAPPED_TOKEN_GATEWAY, +} from "./constants"; + +const contractName: string = CONTRACT_NAME.AaveV3Supply; + +task(DEPLOY_AAVE_V3_SUPPLY_ADAPTER) + .addFlag("verify", "pass true to verify the contract") + .setAction(async function ( + _taskArguments: TaskArguments, + _hre: HardhatRuntimeEnvironment + ) { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + + let defaultRefundAddress = process.env.DEFAULT_REFUND_ADDRESS; + if (!defaultRefundAddress) defaultRefundAddress = DEFAULT_REFUND_ADDRESS; + + let owner = process.env.OWNER; + if (!owner) owner = DEFAULT_OWNER; + + const network = await _hre.getChainId(); + + console.log(`Deploying ${contractName} Contract on chainId ${network}....`); + const factory = await _hre.ethers.getContractFactory(contractName); + const instance = await factory.deploy( + NATIVE, + WNATIVE[env][network], + owner, + ASSET_FORWARDER[env][network], + DEXSPAN[env][network], + AAVE_V3_POOL[network], + AAVE_V3_WRAPPED_TOKEN_GATEWAY[network], + AAVE_V3_REFERRAL_CODE + ); + await instance.deployed(); + + const deployment: IDeployment = await recordAllDeployments( + env, + network, + contractName, + instance.address + ); + + await saveDeployments(deployment); + + console.log(`${contractName} contract deployed at`, instance.address); + + if (_taskArguments.verify === true) { + await _hre.run(VERIFY_AAVE_V3_SUPPLY_ADAPTER); + } + }); + +task(VERIFY_AAVE_V3_SUPPLY_ADAPTER).setAction(async function ( + _taskArguments: TaskArguments, + _hre: HardhatRuntimeEnvironment +) { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + + let defaultRefundAddress = process.env.DEFAULT_REFUND_ADDRESS; + if (!defaultRefundAddress) defaultRefundAddress = DEFAULT_REFUND_ADDRESS; + + let owner = process.env.OWNER; + if (!owner) owner = DEFAULT_OWNER; + + const network = await _hre.getChainId(); + + const deployments: IDeployment = getDeployments(); + const address = deployments[env][network][contractName]; + + console.log(`Verifying ${contractName} Contract....`); + await _hre.run("verify:verify", { + address, + constructorArguments: [ + NATIVE, + WNATIVE[env][network], + owner, + ASSET_FORWARDER[env][network], + DEXSPAN[env][network], + AAVE_V3_POOL[network], + AAVE_V3_WRAPPED_TOKEN_GATEWAY[network], + AAVE_V3_REFERRAL_CODE, + ], + }); + + console.log(`Verified ${contractName} contract address `, address); +}); diff --git a/evm/tasks/aaveV3/constants.ts b/evm/tasks/aaveV3/constants.ts new file mode 100644 index 0000000..1bf69e8 --- /dev/null +++ b/evm/tasks/aaveV3/constants.ts @@ -0,0 +1,16 @@ +export const AAVE_V3_POOL: { [chainId: string]: string } = { + "80001": "0xcC6114B983E4Ed2737E9BD3961c9924e6216c704", + "43113": "0xccEa5C65f6d4F465B71501418b88FBe4e7071283", +}; + +export const AAVE_V3_WRAPPED_TOKEN_GATEWAY: { [chainId: string]: string } = { + "80001": "0x8dA9412AbB78db20d0B496573D9066C474eA21B8", + "43113": "0x8A007E495449ffeda4C2d65f14eE31f8Bcb022CF", +}; + +export const AAVE_V3_POOL_DATA_PROVIDER: { [chainId: string]: string } = { + "80001": "0x9e2DDb6aA91399546Bd875E2e63E8d6df276922e", + "43113": "0x544b4e38fC2E74DAd9a3C2f783A15776C0C25c51", +}; + +export const AAVE_V3_REFERRAL_CODE = 0; diff --git a/evm/tasks/aaveV3/index.ts b/evm/tasks/aaveV3/index.ts new file mode 100644 index 0000000..5259cad --- /dev/null +++ b/evm/tasks/aaveV3/index.ts @@ -0,0 +1,2 @@ +import "./AaveV3Supply.deploy"; +import "./AaveV3Borrow.deploy"; diff --git a/evm/tasks/ankr/AnkrStakeAvax.deploy.ts b/evm/tasks/ankr/AnkrStakeAvax.deploy.ts new file mode 100644 index 0000000..af6f9c2 --- /dev/null +++ b/evm/tasks/ankr/AnkrStakeAvax.deploy.ts @@ -0,0 +1,104 @@ +import { HardhatRuntimeEnvironment, TaskArguments } from "hardhat/types"; +import { + ASSET_FORWARDER, + CONTRACT_NAME, + DEFAULT_ENV, + DEFAULT_OWNER, + DEFAULT_REFUND_ADDRESS, + DEPLOY_ANKR_STAKE_AVAX_ADAPTER, + DEXSPAN, + NATIVE, + VERIFY_ANKR_STAKE_AVAX_ADAPTER, + WNATIVE, +} from "../constants"; +import { task } from "hardhat/config"; +import { + IDeployment, + getDeployments, + recordAllDeployments, + saveDeployments, +} from "../utils"; +import { ANKR_LSD_TOKEN, ANKR_POOL } from "./constants"; + +const contractName: string = CONTRACT_NAME.AnkrStakeAvax; + +task(DEPLOY_ANKR_STAKE_AVAX_ADAPTER) + .addFlag("verify", "pass true to verify the contract") + .setAction(async function ( + _taskArguments: TaskArguments, + _hre: HardhatRuntimeEnvironment + ) { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + + let defaultRefundAddress = process.env.DEFAULT_REFUND_ADDRESS; + if (!defaultRefundAddress) defaultRefundAddress = DEFAULT_REFUND_ADDRESS; + + let owner = process.env.OWNER; + if (!owner) owner = DEFAULT_OWNER; + + const network = await _hre.getChainId(); + + console.log(`Deploying ${contractName} Contract on chainId ${network}....`); + const factory = await _hre.ethers.getContractFactory(contractName); + const instance = await factory.deploy( + NATIVE, + WNATIVE[env][network], + owner, + ASSET_FORWARDER[env][network], + DEXSPAN[env][network], + ANKR_LSD_TOKEN[network], + ANKR_POOL[network] + ); + await instance.deployed(); + + const deployment: IDeployment = await recordAllDeployments( + env, + network, + contractName, + instance.address + ); + + await saveDeployments(deployment); + + console.log(`${contractName} contract deployed at`, instance.address); + + if (_taskArguments.verify === true) { + await _hre.run(VERIFY_ANKR_STAKE_AVAX_ADAPTER); + } + }); + +task(VERIFY_ANKR_STAKE_AVAX_ADAPTER).setAction(async function ( + _taskArguments: TaskArguments, + _hre: HardhatRuntimeEnvironment +) { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + + let defaultRefundAddress = process.env.DEFAULT_REFUND_ADDRESS; + if (!defaultRefundAddress) defaultRefundAddress = DEFAULT_REFUND_ADDRESS; + + let owner = process.env.OWNER; + if (!owner) owner = DEFAULT_OWNER; + + const network = await _hre.getChainId(); + + const deployments: IDeployment = getDeployments(); + const address = deployments[env][network][contractName]; + + console.log(`Verifying ${contractName} Contract....`); + await _hre.run("verify:verify", { + address, + constructorArguments: [ + NATIVE, + WNATIVE[env][network], + owner, + ASSET_FORWARDER[env][network], + DEXSPAN[env][network], + ANKR_LSD_TOKEN[network], + ANKR_POOL[network], + ], + }); + + console.log(`Verified ${contractName} contract address `, address); +}); diff --git a/evm/tasks/ankr/AnkrStakeBsc.deploy.ts b/evm/tasks/ankr/AnkrStakeBsc.deploy.ts new file mode 100644 index 0000000..07f221e --- /dev/null +++ b/evm/tasks/ankr/AnkrStakeBsc.deploy.ts @@ -0,0 +1,104 @@ +import { HardhatRuntimeEnvironment, TaskArguments } from "hardhat/types"; +import { + ASSET_FORWARDER, + CONTRACT_NAME, + DEFAULT_ENV, + DEFAULT_OWNER, + DEFAULT_REFUND_ADDRESS, + DEPLOY_ANKR_STAKE_BSC_ADAPTER, + DEXSPAN, + NATIVE, + VERIFY_ANKR_STAKE_BSC_ADAPTER, + WNATIVE, +} from "../constants"; +import { task } from "hardhat/config"; +import { + IDeployment, + getDeployments, + recordAllDeployments, + saveDeployments, +} from "../utils"; +import { ANKR_LSD_TOKEN, ANKR_POOL } from "./constants"; + +const contractName: string = CONTRACT_NAME.AnkrStakeBsc; + +task(DEPLOY_ANKR_STAKE_BSC_ADAPTER) + .addFlag("verify", "pass true to verify the contract") + .setAction(async function ( + _taskArguments: TaskArguments, + _hre: HardhatRuntimeEnvironment + ) { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + + let defaultRefundAddress = process.env.DEFAULT_REFUND_ADDRESS; + if (!defaultRefundAddress) defaultRefundAddress = DEFAULT_REFUND_ADDRESS; + + let owner = process.env.OWNER; + if (!owner) owner = DEFAULT_OWNER; + + const network = await _hre.getChainId(); + + console.log(`Deploying ${contractName} Contract on chainId ${network}....`); + const factory = await _hre.ethers.getContractFactory(contractName); + const instance = await factory.deploy( + NATIVE, + WNATIVE[env][network], + owner, + ASSET_FORWARDER[env][network], + DEXSPAN[env][network], + ANKR_LSD_TOKEN[network], + ANKR_POOL[network] + ); + await instance.deployed(); + + const deployment: IDeployment = await recordAllDeployments( + env, + network, + contractName, + instance.address + ); + + await saveDeployments(deployment); + + console.log(`${contractName} contract deployed at`, instance.address); + + if (_taskArguments.verify === true) { + await _hre.run(VERIFY_ANKR_STAKE_BSC_ADAPTER); + } + }); + +task(VERIFY_ANKR_STAKE_BSC_ADAPTER).setAction(async function ( + _taskArguments: TaskArguments, + _hre: HardhatRuntimeEnvironment +) { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + + let defaultRefundAddress = process.env.DEFAULT_REFUND_ADDRESS; + if (!defaultRefundAddress) defaultRefundAddress = DEFAULT_REFUND_ADDRESS; + + let owner = process.env.OWNER; + if (!owner) owner = DEFAULT_OWNER; + + const network = await _hre.getChainId(); + + const deployments: IDeployment = getDeployments(); + const address = deployments[env][network][contractName]; + + console.log(`Verifying ${contractName} Contract....`); + await _hre.run("verify:verify", { + address, + constructorArguments: [ + NATIVE, + WNATIVE[env][network], + owner, + ASSET_FORWARDER[env][network], + DEXSPAN[env][network], + ANKR_LSD_TOKEN[network], + ANKR_POOL[network], + ], + }); + + console.log(`Verified ${contractName} contract address `, address); +}); diff --git a/evm/tasks/ankr/AnkrStakeEth.deploy.ts b/evm/tasks/ankr/AnkrStakeEth.deploy.ts new file mode 100644 index 0000000..84061f7 --- /dev/null +++ b/evm/tasks/ankr/AnkrStakeEth.deploy.ts @@ -0,0 +1,104 @@ +import { HardhatRuntimeEnvironment, TaskArguments } from "hardhat/types"; +import { + ASSET_FORWARDER, + CONTRACT_NAME, + DEFAULT_ENV, + DEFAULT_OWNER, + DEFAULT_REFUND_ADDRESS, + DEPLOY_ANKR_STAKE_ETH_ADAPTER, + DEXSPAN, + NATIVE, + VERIFY_ANKR_STAKE_ETH_ADAPTER, + WNATIVE, +} from "../constants"; +import { task } from "hardhat/config"; +import { + IDeployment, + getDeployments, + recordAllDeployments, + saveDeployments, +} from "../utils"; +import { ANKR_LSD_TOKEN, ANKR_POOL } from "./constants"; + +const contractName: string = CONTRACT_NAME.AnkrStakeEth; + +task(DEPLOY_ANKR_STAKE_ETH_ADAPTER) + .addFlag("verify", "pass true to verify the contract") + .setAction(async function ( + _taskArguments: TaskArguments, + _hre: HardhatRuntimeEnvironment + ) { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + + let defaultRefundAddress = process.env.DEFAULT_REFUND_ADDRESS; + if (!defaultRefundAddress) defaultRefundAddress = DEFAULT_REFUND_ADDRESS; + + let owner = process.env.OWNER; + if (!owner) owner = DEFAULT_OWNER; + + const network = await _hre.getChainId(); + + console.log(`Deploying ${contractName} Contract on chainId ${network}....`); + const factory = await _hre.ethers.getContractFactory(contractName); + const instance = await factory.deploy( + NATIVE, + WNATIVE[env][network], + owner, + ASSET_FORWARDER[env][network], + DEXSPAN[env][network], + ANKR_LSD_TOKEN[network], + ANKR_POOL[network] + ); + await instance.deployed(); + + const deployment: IDeployment = await recordAllDeployments( + env, + network, + contractName, + instance.address + ); + + await saveDeployments(deployment); + + console.log(`${contractName} contract deployed at`, instance.address); + + if (_taskArguments.verify === true) { + await _hre.run(VERIFY_ANKR_STAKE_ETH_ADAPTER); + } + }); + +task(VERIFY_ANKR_STAKE_ETH_ADAPTER).setAction(async function ( + _taskArguments: TaskArguments, + _hre: HardhatRuntimeEnvironment +) { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + + let defaultRefundAddress = process.env.DEFAULT_REFUND_ADDRESS; + if (!defaultRefundAddress) defaultRefundAddress = DEFAULT_REFUND_ADDRESS; + + let owner = process.env.OWNER; + if (!owner) owner = DEFAULT_OWNER; + + const network = await _hre.getChainId(); + + const deployments: IDeployment = getDeployments(); + const address = deployments[env][network][contractName]; + + console.log(`Verifying ${contractName} Contract....`); + await _hre.run("verify:verify", { + address, + constructorArguments: [ + NATIVE, + WNATIVE[env][network], + owner, + ASSET_FORWARDER[env][network], + DEXSPAN[env][network], + ANKR_LSD_TOKEN[network], + ANKR_POOL[network], + ], + }); + + console.log(`Verified ${contractName} contract address `, address); +}); diff --git a/evm/tasks/ankr/AnkrStakeFantom.deploy.ts b/evm/tasks/ankr/AnkrStakeFantom.deploy.ts new file mode 100644 index 0000000..b788099 --- /dev/null +++ b/evm/tasks/ankr/AnkrStakeFantom.deploy.ts @@ -0,0 +1,104 @@ +import { HardhatRuntimeEnvironment, TaskArguments } from "hardhat/types"; +import { + ASSET_FORWARDER, + CONTRACT_NAME, + DEFAULT_ENV, + DEFAULT_OWNER, + DEFAULT_REFUND_ADDRESS, + DEPLOY_ANKR_STAKE_FANTOM_ADAPTER, + DEXSPAN, + NATIVE, + VERIFY_ANKR_STAKE_FANTOM_ADAPTER, + WNATIVE, +} from "../constants"; +import { task } from "hardhat/config"; +import { + IDeployment, + getDeployments, + recordAllDeployments, + saveDeployments, +} from "../utils"; +import { ANKR_LSD_TOKEN, ANKR_POOL } from "./constants"; + +const contractName: string = CONTRACT_NAME.AnkrStakeFantom; + +task(DEPLOY_ANKR_STAKE_FANTOM_ADAPTER) + .addFlag("verify", "pass true to verify the contract") + .setAction(async function ( + _taskArguments: TaskArguments, + _hre: HardhatRuntimeEnvironment + ) { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + + let defaultRefundAddress = process.env.DEFAULT_REFUND_ADDRESS; + if (!defaultRefundAddress) defaultRefundAddress = DEFAULT_REFUND_ADDRESS; + + let owner = process.env.OWNER; + if (!owner) owner = DEFAULT_OWNER; + + const network = await _hre.getChainId(); + + console.log(`Deploying ${contractName} Contract on chainId ${network}....`); + const factory = await _hre.ethers.getContractFactory(contractName); + const instance = await factory.deploy( + NATIVE, + WNATIVE[env][network], + owner, + ASSET_FORWARDER[env][network], + DEXSPAN[env][network], + ANKR_LSD_TOKEN[network], + ANKR_POOL[network] + ); + await instance.deployed(); + + const deployment: IDeployment = await recordAllDeployments( + env, + network, + contractName, + instance.address + ); + + await saveDeployments(deployment); + + console.log(`${contractName} contract deployed at`, instance.address); + + if (_taskArguments.verify === true) { + await _hre.run(VERIFY_ANKR_STAKE_FANTOM_ADAPTER); + } + }); + +task(VERIFY_ANKR_STAKE_FANTOM_ADAPTER).setAction(async function ( + _taskArguments: TaskArguments, + _hre: HardhatRuntimeEnvironment +) { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + + let defaultRefundAddress = process.env.DEFAULT_REFUND_ADDRESS; + if (!defaultRefundAddress) defaultRefundAddress = DEFAULT_REFUND_ADDRESS; + + let owner = process.env.OWNER; + if (!owner) owner = DEFAULT_OWNER; + + const network = await _hre.getChainId(); + + const deployments: IDeployment = getDeployments(); + const address = deployments[env][network][contractName]; + + console.log(`Verifying ${contractName} Contract....`); + await _hre.run("verify:verify", { + address, + constructorArguments: [ + NATIVE, + WNATIVE[env][network], + owner, + ASSET_FORWARDER[env][network], + DEXSPAN[env][network], + ANKR_LSD_TOKEN[network], + ANKR_POOL[network], + ], + }); + + console.log(`Verified ${contractName} contract address `, address); +}); diff --git a/evm/tasks/ankr/AnkrStakeMatic.deploy.ts b/evm/tasks/ankr/AnkrStakeMatic.deploy.ts new file mode 100644 index 0000000..9fac35f --- /dev/null +++ b/evm/tasks/ankr/AnkrStakeMatic.deploy.ts @@ -0,0 +1,106 @@ +import { HardhatRuntimeEnvironment, TaskArguments } from "hardhat/types"; +import { + ASSET_FORWARDER, + CONTRACT_NAME, + DEFAULT_ENV, + DEFAULT_OWNER, + DEFAULT_REFUND_ADDRESS, + DEPLOY_ANKR_STAKE_MATIC_ADAPTER, + DEXSPAN, + NATIVE, + VERIFY_ANKR_STAKE_MATIC_ADAPTER, + WNATIVE, +} from "../constants"; +import { task } from "hardhat/config"; +import { + IDeployment, + getDeployments, + recordAllDeployments, + saveDeployments, +} from "../utils"; +import { ANKR_MATIC, ANKR_MATIC_POOL, MATIC } from "./constants"; + +const contractName: string = CONTRACT_NAME.AnkrStakeMatic; + +task(DEPLOY_ANKR_STAKE_MATIC_ADAPTER) + .addFlag("verify", "pass true to verify the contract") + .setAction(async function ( + _taskArguments: TaskArguments, + _hre: HardhatRuntimeEnvironment + ) { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + + let defaultRefundAddress = process.env.DEFAULT_REFUND_ADDRESS; + if (!defaultRefundAddress) defaultRefundAddress = DEFAULT_REFUND_ADDRESS; + + let owner = process.env.OWNER; + if (!owner) owner = DEFAULT_OWNER; + + const network = await _hre.getChainId(); + + console.log(`Deploying ${contractName} Contract on chainId ${network}....`); + const factory = await _hre.ethers.getContractFactory(contractName); + const instance = await factory.deploy( + NATIVE, + WNATIVE[env][network], + owner, + ASSET_FORWARDER[env][network], + DEXSPAN[env][network], + ANKR_MATIC[network], + MATIC[network], + ANKR_MATIC_POOL[network] + ); + await instance.deployed(); + + const deployment: IDeployment = await recordAllDeployments( + env, + network, + contractName, + instance.address + ); + + await saveDeployments(deployment); + + console.log(`${contractName} contract deployed at`, instance.address); + + if (_taskArguments.verify === true) { + await _hre.run(VERIFY_ANKR_STAKE_MATIC_ADAPTER); + } + }); + +task(VERIFY_ANKR_STAKE_MATIC_ADAPTER).setAction(async function ( + _taskArguments: TaskArguments, + _hre: HardhatRuntimeEnvironment +) { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + + let defaultRefundAddress = process.env.DEFAULT_REFUND_ADDRESS; + if (!defaultRefundAddress) defaultRefundAddress = DEFAULT_REFUND_ADDRESS; + + let owner = process.env.OWNER; + if (!owner) owner = DEFAULT_OWNER; + + const network = await _hre.getChainId(); + + const deployments: IDeployment = getDeployments(); + const address = deployments[env][network][contractName]; + + console.log(`Verifying ${contractName} Contract....`); + await _hre.run("verify:verify", { + address, + constructorArguments: [ + NATIVE, + WNATIVE[env][network], + owner, + ASSET_FORWARDER[env][network], + DEXSPAN[env][network], + ANKR_MATIC[network], + MATIC[network], + ANKR_MATIC_POOL[network] + ], + }); + + console.log(`Verified ${contractName} contract address `, address); +}); diff --git a/evm/tasks/ankr/AnkrStakePolygon.deploy.ts b/evm/tasks/ankr/AnkrStakePolygon.deploy.ts new file mode 100644 index 0000000..2f93e19 --- /dev/null +++ b/evm/tasks/ankr/AnkrStakePolygon.deploy.ts @@ -0,0 +1,104 @@ +import { HardhatRuntimeEnvironment, TaskArguments } from "hardhat/types"; +import { + ASSET_FORWARDER, + CONTRACT_NAME, + DEFAULT_ENV, + DEFAULT_OWNER, + DEFAULT_REFUND_ADDRESS, + DEPLOY_ANKR_STAKE_POLYGON_ADAPTER, + DEXSPAN, + NATIVE, + VERIFY_ANKR_STAKE_POLYGON_ADAPTER, + WNATIVE, +} from "../constants"; +import { task } from "hardhat/config"; +import { + IDeployment, + getDeployments, + recordAllDeployments, + saveDeployments, +} from "../utils"; +import { ANKR_LSD_TOKEN, ANKR_POOL } from "./constants"; + +const contractName: string = CONTRACT_NAME.AnkrStakePolygon; + +task(DEPLOY_ANKR_STAKE_POLYGON_ADAPTER) + .addFlag("verify", "pass true to verify the contract") + .setAction(async function ( + _taskArguments: TaskArguments, + _hre: HardhatRuntimeEnvironment + ) { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + + let defaultRefundAddress = process.env.DEFAULT_REFUND_ADDRESS; + if (!defaultRefundAddress) defaultRefundAddress = DEFAULT_REFUND_ADDRESS; + + let owner = process.env.OWNER; + if (!owner) owner = DEFAULT_OWNER; + + const network = await _hre.getChainId(); + + console.log(`Deploying ${contractName} Contract on chainId ${network}....`); + const factory = await _hre.ethers.getContractFactory(contractName); + const instance = await factory.deploy( + NATIVE, + WNATIVE[env][network], + owner, + ASSET_FORWARDER[env][network], + DEXSPAN[env][network], + ANKR_LSD_TOKEN[network], + ANKR_POOL[network] + ); + await instance.deployed(); + + const deployment: IDeployment = await recordAllDeployments( + env, + network, + contractName, + instance.address + ); + + await saveDeployments(deployment); + + console.log(`${contractName} contract deployed at`, instance.address); + + if (_taskArguments.verify === true) { + await _hre.run(VERIFY_ANKR_STAKE_POLYGON_ADAPTER); + } + }); + +task(VERIFY_ANKR_STAKE_POLYGON_ADAPTER).setAction(async function ( + _taskArguments: TaskArguments, + _hre: HardhatRuntimeEnvironment +) { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + + let defaultRefundAddress = process.env.DEFAULT_REFUND_ADDRESS; + if (!defaultRefundAddress) defaultRefundAddress = DEFAULT_REFUND_ADDRESS; + + let owner = process.env.OWNER; + if (!owner) owner = DEFAULT_OWNER; + + const network = await _hre.getChainId(); + + const deployments: IDeployment = getDeployments(); + const address = deployments[env][network][contractName]; + + console.log(`Verifying ${contractName} Contract....`); + await _hre.run("verify:verify", { + address, + constructorArguments: [ + NATIVE, + WNATIVE[env][network], + owner, + ASSET_FORWARDER[env][network], + DEXSPAN[env][network], + ANKR_LSD_TOKEN[network], + ANKR_POOL[network], + ], + }); + + console.log(`Verified ${contractName} contract address `, address); +}); diff --git a/evm/tasks/ankr/constants.ts b/evm/tasks/ankr/constants.ts new file mode 100644 index 0000000..0e8fe5d --- /dev/null +++ b/evm/tasks/ankr/constants.ts @@ -0,0 +1,27 @@ +export const ANKR_POOL: { [chainId: string]: string } = { + "1": "0x84db6eE82b7Cf3b47E8F19270abdE5718B936670", + "43114": "0x7BAa1E3bFe49db8361680785182B80BB420A836D", + "56": "0x9e347Af362059bf2E55839002c699F7A5BaFE86E", + "250": "0x84db6eE82b7Cf3b47E8F19270abdE5718B936670", + "137": "0x62A509BA95c75Cabc7190469025E5aBeE4eDdb2a", + }; + + export const ANKR_LSD_TOKEN: { [chainId: string]: string } = { + "1": "0xE95A203B1a91a908F9B9CE46459d101078c2c3cb", + "43114": "0xc3344870d52688874b06d844E0C36cc39FC727F6", + "56": "0x52F24a5e03aee338Da5fd9Df68D2b6FAe1178827", + "250": "0xCfC785741Dc0e98ad4c9F6394Bb9d43Cd1eF5179", + "137": "0x0E9b89007eEE9c958c0EDA24eF70723C2C93dD58", + }; + + export const ANKR_MATIC_POOL: { [chainId: string]: string } = { + "1": "0xCfD4B4Bc15C8bF0Fd820B0D4558c725727B3ce89", + }; + + export const ANKR_MATIC: { [chainId: string]: string } = { + "1": "0x26dcFbFa8Bc267b250432c01C982Eaf81cC5480C", + }; + + export const MATIC: { [chainId: string]: string } = { + "1": "0x7D1AfA7B718fb893dB30A3aBc0Cfc608AaCfeBB0", + }; \ No newline at end of file diff --git a/evm/tasks/ankr/index.ts b/evm/tasks/ankr/index.ts new file mode 100644 index 0000000..9eac76a --- /dev/null +++ b/evm/tasks/ankr/index.ts @@ -0,0 +1,6 @@ +import "./AnkrStakeAvax.deploy"; +import "./AnkrStakeEth.deploy"; +import "./AnkrStakeBsc.deploy"; +import "./AnkrStakePolygon.deploy"; +import "./AnkrStakeFantom.deploy"; +import "./AnkrStakeMatic.deploy"; \ No newline at end of file diff --git a/evm/tasks/benqi/BenqiStakeAvax.deploy.ts b/evm/tasks/benqi/BenqiStakeAvax.deploy.ts new file mode 100644 index 0000000..a73f45b --- /dev/null +++ b/evm/tasks/benqi/BenqiStakeAvax.deploy.ts @@ -0,0 +1,102 @@ +import { HardhatRuntimeEnvironment, TaskArguments } from "hardhat/types"; +import { + ASSET_FORWARDER, + CONTRACT_NAME, + DEFAULT_ENV, + DEFAULT_OWNER, + DEFAULT_REFUND_ADDRESS, + DEPLOY_BENQI_STAKE_AVAX_ADAPTER, + DEXSPAN, + NATIVE, + VERIFY_BENQI_STAKE_AVAX_ADAPTER, + WNATIVE, +} from "../constants"; +import { task } from "hardhat/config"; +import { + IDeployment, + getDeployments, + recordAllDeployments, + saveDeployments, +} from "../utils"; +import { BENQI_S_AVAX } from "./constants"; + +const contractName: string = CONTRACT_NAME.BenqiStakeAvax; + +task(DEPLOY_BENQI_STAKE_AVAX_ADAPTER) + .addFlag("verify", "pass true to verify the contract") + .setAction(async function ( + _taskArguments: TaskArguments, + _hre: HardhatRuntimeEnvironment + ) { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + + let defaultRefundAddress = process.env.DEFAULT_REFUND_ADDRESS; + if (!defaultRefundAddress) defaultRefundAddress = DEFAULT_REFUND_ADDRESS; + + let owner = process.env.OWNER; + if (!owner) owner = DEFAULT_OWNER; + + const network = await _hre.getChainId(); + + console.log(`Deploying ${contractName} Contract on chainId ${network}....`); + const factory = await _hre.ethers.getContractFactory(contractName); + const instance = await factory.deploy( + NATIVE, + WNATIVE[env][network], + owner, + ASSET_FORWARDER[env][network], + DEXSPAN[env][network], + BENQI_S_AVAX[network], + ); + await instance.deployed(); + + const deployment: IDeployment = await recordAllDeployments( + env, + network, + contractName, + instance.address + ); + + await saveDeployments(deployment); + + console.log(`${contractName} contract deployed at`, instance.address); + + if (_taskArguments.verify === true) { + await _hre.run(VERIFY_BENQI_STAKE_AVAX_ADAPTER); + } + }); + +task(VERIFY_BENQI_STAKE_AVAX_ADAPTER).setAction(async function ( + _taskArguments: TaskArguments, + _hre: HardhatRuntimeEnvironment +) { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + + let defaultRefundAddress = process.env.DEFAULT_REFUND_ADDRESS; + if (!defaultRefundAddress) defaultRefundAddress = DEFAULT_REFUND_ADDRESS; + + let owner = process.env.OWNER; + if (!owner) owner = DEFAULT_OWNER; + + const network = await _hre.getChainId(); + + const deployments: IDeployment = getDeployments(); + const address = deployments[env][network][contractName]; + + console.log(`Verifying ${contractName} Contract....`); + await _hre.run("verify:verify", { + address, + constructorArguments: [ + NATIVE, + WNATIVE[env][network], + owner, + ASSET_FORWARDER[env][network], + DEXSPAN[env][network], + BENQI_S_AVAX[network], + ], + }); + + console.log(`Verified ${contractName} contract address `, address); +}); diff --git a/evm/tasks/benqi/constants.ts b/evm/tasks/benqi/constants.ts new file mode 100644 index 0000000..b9e7b1c --- /dev/null +++ b/evm/tasks/benqi/constants.ts @@ -0,0 +1,3 @@ +export const BENQI_S_AVAX: { [chainId: string]: string } = { + "43114": "0x2b2C81e08f1Af8835a78Bb2A90AE924ACE0eA4bE", + }; \ No newline at end of file diff --git a/evm/tasks/benqi/index.ts b/evm/tasks/benqi/index.ts new file mode 100644 index 0000000..8463601 --- /dev/null +++ b/evm/tasks/benqi/index.ts @@ -0,0 +1 @@ +import "./BenqiStakeAvax.deploy"; diff --git a/evm/tasks/compound/CompoundBorrow.deploy.ts b/evm/tasks/compound/CompoundBorrow.deploy.ts new file mode 100644 index 0000000..23f9f26 --- /dev/null +++ b/evm/tasks/compound/CompoundBorrow.deploy.ts @@ -0,0 +1,113 @@ +import { HardhatRuntimeEnvironment, TaskArguments } from "hardhat/types"; +import { + ASSET_FORWARDER, + CONTRACT_NAME, + DEFAULT_ENV, + DEFAULT_OWNER, + DEFAULT_REFUND_ADDRESS, + DEPLOY_COMPOUND_BORROW_ADAPTER, + DEXSPAN, + NATIVE, + VERIFY_COMPOUND_BORROW_ADAPTER, + WNATIVE, +} from "../constants"; +import { task } from "hardhat/config"; +import { + IDeployment, + getDeployments, + recordAllDeployments, + saveDeployments, +} from "../utils"; +import { + COMPOUND_USDC_POOL, + COMPOUND_WETH_POOL, + USDC, + WETH +} from "./constants"; + +const contractName: string = CONTRACT_NAME.CompoundBorrow; + +task(DEPLOY_COMPOUND_BORROW_ADAPTER) + .addFlag("verify", "pass true to verify the contract") + .setAction(async function ( + _taskArguments: TaskArguments, + _hre: HardhatRuntimeEnvironment + ) { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + + let defaultRefundAddress = process.env.DEFAULT_REFUND_ADDRESS; + if (!defaultRefundAddress) defaultRefundAddress = DEFAULT_REFUND_ADDRESS; + + let owner = process.env.OWNER; + if (!owner) owner = DEFAULT_OWNER; + + const network = await _hre.getChainId(); + + console.log(`Deploying ${contractName} Contract on chainId ${network}....`); + const factory = await _hre.ethers.getContractFactory(contractName); + const instance = await factory.deploy( + NATIVE, + WETH[network], + owner, + ASSET_FORWARDER[env][network], + DEXSPAN[env][network], + DEFAULT_REFUND_ADDRESS, + USDC[network], + COMPOUND_USDC_POOL[network], + COMPOUND_WETH_POOL[network] + ); + await instance.deployed(); + + const deployment: IDeployment = await recordAllDeployments( + env, + network, + contractName, + instance.address + ); + + await saveDeployments(deployment); + + console.log(`${contractName} contract deployed at`, instance.address); + + if (_taskArguments.verify === true) { + await _hre.run(VERIFY_COMPOUND_BORROW_ADAPTER); + } + }); + +task(VERIFY_COMPOUND_BORROW_ADAPTER).setAction(async function ( + _taskArguments: TaskArguments, + _hre: HardhatRuntimeEnvironment +) { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + + let defaultRefundAddress = process.env.DEFAULT_REFUND_ADDRESS; + if (!defaultRefundAddress) defaultRefundAddress = DEFAULT_REFUND_ADDRESS; + + let owner = process.env.OWNER; + if (!owner) owner = DEFAULT_OWNER; + + const network = await _hre.getChainId(); + + const deployments: IDeployment = getDeployments(); + const address = deployments[env][network][contractName]; + + console.log(`Verifying ${contractName} Contract....`); + await _hre.run("verify:verify", { + address, + constructorArguments: [ + NATIVE, + WETH[network], + owner, + ASSET_FORWARDER[env][network], + DEXSPAN[env][network], + DEFAULT_REFUND_ADDRESS, + USDC[network], + COMPOUND_USDC_POOL[network], + COMPOUND_WETH_POOL[network] + ], + }); + + console.log(`Verified ${contractName} contract address `, address); +}); diff --git a/evm/tasks/compound/CompoundSupply.deploy.ts b/evm/tasks/compound/CompoundSupply.deploy.ts new file mode 100644 index 0000000..625bacc --- /dev/null +++ b/evm/tasks/compound/CompoundSupply.deploy.ts @@ -0,0 +1,111 @@ +import { HardhatRuntimeEnvironment, TaskArguments } from "hardhat/types"; +import { + ASSET_FORWARDER, + CONTRACT_NAME, + DEFAULT_ENV, + DEFAULT_OWNER, + DEFAULT_REFUND_ADDRESS, + DEPLOY_COMPOUND_SUPPLY_ADAPTER, + DEXSPAN, + NATIVE, + VERIFY_COMPOUND_SUPPLY_ADAPTER, + WNATIVE, +} from "../constants"; +import { task } from "hardhat/config"; +import { + IDeployment, + getDeployments, + recordAllDeployments, + saveDeployments, +} from "../utils"; +import { + COMPOUND_USDC_POOL, + COMPOUND_WETH_POOL, + USDC, + WETH +} from "./constants"; + +const contractName: string = CONTRACT_NAME.CompoundSupply; + +task(DEPLOY_COMPOUND_SUPPLY_ADAPTER) + .addFlag("verify", "pass true to verify the contract") + .setAction(async function ( + _taskArguments: TaskArguments, + _hre: HardhatRuntimeEnvironment + ) { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + + let defaultRefundAddress = process.env.DEFAULT_REFUND_ADDRESS; + if (!defaultRefundAddress) defaultRefundAddress = DEFAULT_REFUND_ADDRESS; + + let owner = process.env.OWNER; + if (!owner) owner = DEFAULT_OWNER; + + const network = await _hre.getChainId(); + + console.log(`Deploying ${contractName} Contract on chainId ${network}....`); + const factory = await _hre.ethers.getContractFactory(contractName); + const instance = await factory.deploy( + NATIVE, + WETH[network], + owner, + ASSET_FORWARDER[env][network], + DEXSPAN[env][network], + USDC[network], + COMPOUND_USDC_POOL[network], + COMPOUND_WETH_POOL[network] + ); + await instance.deployed(); + + const deployment: IDeployment = await recordAllDeployments( + env, + network, + contractName, + instance.address + ); + + await saveDeployments(deployment); + + console.log(`${contractName} contract deployed at`, instance.address); + + if (_taskArguments.verify === true) { + await _hre.run(VERIFY_COMPOUND_SUPPLY_ADAPTER); + } + }); + +task(VERIFY_COMPOUND_SUPPLY_ADAPTER).setAction(async function ( + _taskArguments: TaskArguments, + _hre: HardhatRuntimeEnvironment +) { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + + let defaultRefundAddress = process.env.DEFAULT_REFUND_ADDRESS; + if (!defaultRefundAddress) defaultRefundAddress = DEFAULT_REFUND_ADDRESS; + + let owner = process.env.OWNER; + if (!owner) owner = DEFAULT_OWNER; + + const network = await _hre.getChainId(); + + const deployments: IDeployment = getDeployments(); + const address = deployments[env][network][contractName]; + + console.log(`Verifying ${contractName} Contract....`); + await _hre.run("verify:verify", { + address, + constructorArguments: [ + NATIVE, + WETH[network], + owner, + ASSET_FORWARDER[env][network], + DEXSPAN[env][network], + USDC[network], + COMPOUND_USDC_POOL[network], + COMPOUND_WETH_POOL[network] + ], + }); + + console.log(`Verified ${contractName} contract address `, address); +}); diff --git a/evm/tasks/compound/constants.ts b/evm/tasks/compound/constants.ts new file mode 100644 index 0000000..513613c --- /dev/null +++ b/evm/tasks/compound/constants.ts @@ -0,0 +1,31 @@ +export const COMPOUND_USDC_POOL: { [chainId: string]: string } = { + "5": "0x3EE77595A8459e93C2888b13aDB354017B198188", + "421613": "0x1d573274E19174260c5aCE3f2251598959d24456", + "43113": "0x59BF4753899C20EA152dEefc6f6A14B2a5CC3021", + "80001":"0xF09F0369aB0a875254fB565E52226c88f10Bc839", + "84531":"0xe78Fc55c884704F9485EDa042fb91BfE16fD55c1", +}; + +export const COMPOUND_WETH_POOL: { [chainId: string]: string } = { + "5": "0x9A539EEc489AAA03D588212a164d0abdB5F08F5F", + "421613": "0x1d573274E19174260c5aCE3f2251598959d24456", + "43113": "0x59BF4753899C20EA152dEefc6f6A14B2a5CC3021", + "80001":"0xF09F0369aB0a875254fB565E52226c88f10Bc839", + "84531":"0xED94f3052638620fE226a9661ead6a39C2a265bE", +}; + +export const USDC: {[chainId: string]: string} = { + "5": "0x07865c6E87B9F70255377e024ace6630C1Eaa37F", + "421613": "0x8FB1E3fC51F3b789dED7557E680551d93Ea9d892", + "43113": "0x4fed3d02D095f7D92AF161311fA6Ef23dc8dA040", + "80001":"0xDB3cB4f2688daAB3BFf59C24cC42D4B6285828e9", + "84531":"0x31D3A7711a74b4Ec970F50c3eaf1ee47ba803A95", +}; + +export const WETH: { [chainId: string]: string } = { + "5": "0x42a71137C09AE83D8d05974960fd607d40033499", + "421613": "0xe39Ab88f8A4777030A534146A9Ca3B52bd5D43A3", + "43113": "0xA2c25E48269e3f89A60b2CC8e02AAfEeB3BAb761", + "80001":"0xfec23a9E1DBA805ADCF55E0338Bf5E03488FC7Fb", + "84531":"0x4200000000000000000000000000000000000006", +}; diff --git a/evm/tasks/compound/index.ts b/evm/tasks/compound/index.ts new file mode 100644 index 0000000..51b3eb0 --- /dev/null +++ b/evm/tasks/compound/index.ts @@ -0,0 +1,2 @@ +import "./CompoundSupply.deploy"; +import "./CompoundBorrow.deploy"; diff --git a/evm/tasks/constants.ts b/evm/tasks/constants.ts new file mode 100644 index 0000000..7e5833b --- /dev/null +++ b/evm/tasks/constants.ts @@ -0,0 +1,193 @@ +export const NATIVE = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"; +export const DEFAULT_ENV = "testnet"; +export const DEFAULT_REFUND_ADDRESS = + "0x54485755c209Cb47A4c7aAeAF3a14818CFe675A5"; +export const DEFAULT_OWNER = "0x54485755c209Cb47A4c7aAeAF3a14818CFe675A5"; + +export const DEPLOY_BATCH_TRANSACTION = "DEPLOY_BATCH_TRANSACTION"; +export const VERIFY_BATCH_TRANSACTION = "VERIFY_BATCH_TRANSACTION"; +export const DEPLOY_LIDO_STAKE_ETH_ADAPTER = "DEPLOY_LIDO_STAKE_ETH_ADAPTER"; +export const VERIFY_LIDO_STAKE_ETH_ADAPTER = "VERIFY_LIDO_STAKE_ETH_ADAPTER"; +export const DEPLOY_LIDO_STAKE_MATIC_ADAPTER = + "DEPLOY_LIDO_STAKE_MATIC_ADAPTER"; +export const VERIFY_LIDO_STAKE_MATIC_ADAPTER = + "VERIFY_LIDO_STAKE_MATIC_ADAPTER"; +export const DEPLOY_STADER_STAKE_ETH_ADAPTER = + "DEPLOY_STADER_STAKE_ETH_ADAPTER"; +export const VERIFY_STADER_STAKE_ETH_ADAPTER = + "VERIFY_STADER_STAKE_ETH_ADAPTER"; +export const DEPLOY_STADER_STAKE_MATIC_ADAPTER = + "DEPLOY_STADER_STAKE_MATIC_ADAPTER"; +export const VERIFY_STADER_STAKE_MATIC_ADAPTER = + "VERIFY_STADER_STAKE_MATIC_ADAPTER"; +export const DEPLOY_STADER_STAKE_POLYGON_ADAPTER = + "DEPLOY_STADER_STAKE_POLYGON_ADAPTER"; +export const VERIFY_STADER_STAKE_POLYGON_ADAPTER = + "VERIFY_STADER_STAKE_POLYGON_ADAPTER"; +export const DEPLOY_STADER_STAKE_BNB_ADAPTER = + "DEPLOY_STADER_STAKE_BNB_ADAPTER"; +export const VERIFY_STADER_STAKE_BNB_ADAPTER = + "VERIFY_STADER_STAKE_BNB_ADAPTER"; +export const DEPLOY_STADER_STAKE_FTM_ADAPTER = + "DEPLOY_STADER_STAKE_FTM_ADAPTER"; +export const VERIFY_STADER_STAKE_FTM_ADAPTER = + "VERIFY_STADER_STAKE_FTM_ADAPTER"; +export const DEPLOY_ROCKET_POOL_STAKE_ETH_ADAPTER = + "DEPLOY_ROCKET_POOL_STAKE_ETH_ADAPTER"; +export const VERIFY_ROCKET_POOL_STAKE_ETH_ADAPTER = + "VERIFY_ROCKET_POOL_STAKE_ETH_ADAPTER"; +export const DEPLOY_FRAX_STAKE_ETH_ADAPTER = "DEPLOY_FRAX_STAKE_ETH_ADAPTER"; +export const VERIFY_FRAX_STAKE_ETH_ADAPTER = "VERIFY_FRAX_STAKE_ETH_ADAPTER"; +export const DEPLOY_ANKR_STAKE_ETH_ADAPTER = "DEPLOY_ANKR_STAKE_ETH_ADAPTER"; +export const VERIFY_ANKR_STAKE_ETH_ADAPTER = "VERIFY_ANKR_STAKE_ETH_ADAPTER"; +export const DEPLOY_ANKR_STAKE_AVAX_ADAPTER = "DEPLOY_ANKR_STAKE_AVAX_ADAPTER"; +export const VERIFY_ANKR_STAKE_AVAX_ADAPTER = "VERIFY_ANKR_STAKE_AVAX_ADAPTER"; +export const DEPLOY_ANKR_STAKE_BSC_ADAPTER = "DEPLOY_ANKR_STAKE_BSC_ADAPTER"; +export const VERIFY_ANKR_STAKE_BSC_ADAPTER = "VERIFY_ANKR_STAKE_BSC_ADAPTER"; +export const DEPLOY_ANKR_STAKE_FANTOM_ADAPTER = + "DEPLOY_ANKR_STAKE_FANTOM_ADAPTER"; +export const VERIFY_ANKR_STAKE_FANTOM_ADAPTER = + "VERIFY_ANKR_STAKE_FANTOM_ADAPTER"; +export const DEPLOY_ANKR_STAKE_POLYGON_ADAPTER = + "DEPLOY_ANKR_STAKE_POLYGON_ADAPTER"; +export const VERIFY_ANKR_STAKE_POLYGON_ADAPTER = + "VERIFY_ANKR_STAKE_POLYGON_ADAPTER"; +export const DEPLOY_ANKR_STAKE_MATIC_ADAPTER = + "DEPLOY_ANKR_STAKE_MATIC_ADAPTER"; +export const VERIFY_ANKR_STAKE_MATIC_ADAPTER = + "VERIFY_ANKR_STAKE_MATIC_ADAPTER"; +export const DEPLOY_ORIGIN_STAKE_ETH_ADAPTER = + "DEPLOY_ORIGIN_STAKE_ETH_ADAPTER"; +export const VERIFY_ORIGIN_STAKE_ETH_ADAPTER = + "VERIFY_ORIGIN_STAKE_ETH_ADAPTER"; +export const DEPLOY_BENQI_STAKE_AVAX_ADAPTER = + "DEPLOY_BENQI_STAKE_AVAX_ADAPTER"; +export const VERIFY_BENQI_STAKE_AVAX_ADAPTER = + "VERIFY_BENQI_STAKE_AVAX_ADAPTER"; +export const DEPLOY_STAKEWISE_STAKE_ETH_ADAPTER = + "DEPLOY_STAKEWISE_STAKE_ETH_ADAPTER"; +export const VERIFY_STAKEWISE_STAKE_ETH_ADAPTER = + "VERIFY_STAKEWISE_STAKE_ETH_ADAPTER"; +export const DEPLOY_SWELL_STAKE_ETH_ADAPTER = "DEPLOY_SWELL_STAKE_ETH_ADAPTER"; +export const VERIFY_SWELL_STAKE_ETH_ADAPTER = "VERIFY_SWELL_STAKE_ETH_ADAPTER"; +export const DEPLOY_SYNCLUB_STAKE_BNB_ADAPTER = + "DEPLOY_SYNCLUB_STAKE_BNB_ADAPTER"; +export const VERIFY_SYNCLUB_STAKE_BNB_ADAPTER = + "VERIFY_SYNCLUB_STAKE_BNB_ADAPTER"; +export const DEPLOY_METAPOOL_STAKE_ETH_ADAPTER = + "DEPLOY_METAPOOL_STAKE_ETH_ADAPTER"; +export const VERIFY_METAPOOL_STAKE_ETH_ADAPTER = + "VERIFY_METAPOOL_STAKE_ETH_ADAPTER"; +export const DEPLOY_AAVE_V3_SUPPLY_ADAPTER = "DEPLOY_AAVE_V3_SUPPLY_ADAPTER"; +export const VERIFY_AAVE_V3_SUPPLY_ADAPTER = "VERIFY_AAVE_V3_SUPPLY_ADAPTER"; +export const DEPLOY_AAVE_V3_BORROW_ADAPTER = "DEPLOY_AAVE_V3_BORROW_ADAPTER"; +export const VERIFY_AAVE_V3_BORROW_ADAPTER = "VERIFY_AAVE_V3_BORROW_ADAPTER"; +export const DEPLOY_AAVE_V3_PAYBACK_ADAPTER = "DEPLOY_AAVE_V3_PAYBACK_ADAPTER"; +export const VERIFY_AAVE_V3_PAYBACK_ADAPTER = "VERIFY_AAVE_V3_PAYBACK_ADAPTER"; +export const DEPLOY_DEXSPAN_ADAPTER = "DEPLOY_DEXSPAN_ADAPTER"; +export const VERIFY_DEXSPAN_ADAPTER = "VERIFY_DEXSPAN_ADAPTER"; +export const DEPLOY_ERC20_APPROVAL_ADAPTER = "DEPLOY_ERC20_APPROVAL_ADAPTER"; +export const VERIFY_ERC20_APPROVAL_ADAPTER = "VERIFY_ERC20_APPROVAL_ADAPTER"; +export const DEPLOY_ERC20_TRANSFER_ADAPTER = "DEPLOY_ERC20_TRANSFER_ADAPTER"; +export const VERIFY_ERC20_TRANSFER_ADAPTER = "VERIFY_ERC20_TRANSFER_ADAPTER"; +export const DEPLOY_UNISWAP_V3_MINT_ADAPTER = "DEPLOY_UNISWAP_V3_MINT_ADAPTER"; +export const VERIFY_UNISWAP_V3_MINT_ADAPTER = "VERIFY_UNISWAP_V3_MINT_ADAPTER"; +export const DEPLOY_SUSHISWAP_MINT_ADAPTER = "DEPLOY_SUSHISWAP_MINT_ADAPTER"; +export const VERIFY_SUSHISWAP_MINT_ADAPTER = "VERIFY_SUSHISWAP_MINT_ADAPTER"; +export const DEPLOY_PANCAKESWAP_MINT_ADAPTER = "DEPLOY_PANCAKESWAP_MINT_ADAPTER"; +export const VERIFY_PANCAKESWAP_MINT_ADAPTER = "VERIFY_PANCAKESWAP_MINT_ADAPTER"; +export const DEPLOY_QUICKSWAP_MINT_ADAPTER = "DEPLOY_QUICKSWAP_MINT_ADAPTER"; +export const VERIFY_QUICKSWAP_MINT_ADAPTER = "VERIFY_QUICKSWAP_MINT_ADAPTER"; +export const DEPLOY_COMPOUND_SUPPLY_ADAPTER = "DEPLOY_COMPOUND_SUPPLY_ADAPTER"; +export const VERIFY_COMPOUND_SUPPLY_ADAPTER = "VERIFY_COMPOUND_SUPPLY_ADAPTER"; +export const DEPLOY_COMPOUND_BORROW_ADAPTER = "DEPLOY_COMPOUND_BORROW_ADAPTER"; +export const VERIFY_COMPOUND_BORROW_ADAPTER = "VERIFY_COMPOUND_BORROW_ADAPTER"; + +export const ASSET_FORWARDER: { + [network: string]: { [chainId: string]: string }; +} = { + testnet: { + "5": "0x1d16CEd330f9C44A7c0DD181265FF7eA695c6967", + "80001": "0xDFF6fe81B199a2EAd3F2FD8a22895BcD0E46BFCB", + "43113": "0x1c59a5a2acb846b82b65f651189f46ce18f3d8f2", + "1": "0x0000000000000000000000000000000000000000", + "137": "0x0000000000000000000000000000000000000000", + "56": "0x0000000000000000000000000000000000000000", + "43114": "0x0000000000000000000000000000000000000000", + "42161": "0x0000000000000000000000000000000000000000", + "10": "0x0000000000000000000000000000000000000000", + "250": "0x0000000000000000000000000000000000000000", + "8453": "0x0000000000000000000000000000000000000000", + "17000": "0x0000000000000000000000000000000000000000", + }, +}; + +export const DEXSPAN: { [network: string]: { [chainId: string]: string } } = { + testnet: { + "5": "0x199977B79292787a467594cc32A852434495979f", + "80001": "0x02BB8486c15e3732055d3225Cdc498c075e65397", + "43113": "0x02BB8486c15e3732055d3225Cdc498c075e65397", + "1": "0x0000000000000000000000000000000000000000", + "137": "0xA17Ad987ed5D0181b3CcaDF036Fc5427674d6265", + "56": "0x0000000000000000000000000000000000000000", + "43114": "0x0000000000000000000000000000000000000000", + "42161": "0x0000000000000000000000000000000000000000", + "10": "0x0000000000000000000000000000000000000000", + "250": "0x0000000000000000000000000000000000000000", + "8453": "0x0000000000000000000000000000000000000000", + "17000": "0x0000000000000000000000000000000000000000", + }, +}; + +export const WNATIVE: { [network: string]: { [chainId: string]: string } } = { + testnet: { + "1": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", + "56": "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c", + "10": "0x4200000000000000000000000000000000000006", + "137": "0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270", + "250": "0x21be370D5312f44cB42ce377BC9b8a0cEF1A4C83", + "43114": "0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7", + "42161": "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1", + "5": "0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6", + "80001": "0x9c3C9283D3e44854697Cd22D3Faa240Cfb032889", + "43113": "0xd00ae08403B9bbb9124bB305C09058E32C39A48c", + "17000": "0x94373a4919B3240D86eA41593D5eBa789FEF3848", + }, +}; + +export const CONTRACT_NAME: { [key: string]: string } = { + BatchTransaction: "BatchTransaction", + LidoStakeEth: "LidoStakeEth", + LidoStakeMatic: "LidoStakeMatic", + StaderStakePolygon: "StaderStakePolygon", + StaderStakeEth: "StaderStakeEth", + StaderStakeMatic: "StaderStakeMatic", + StaderStakeBnb: "StaderStakeBnb", + StaderStakeFtm: "StaderStakeFtm", + RPStakeEth: "RPStakeEth", + FraxStakeEth: "FraxStakeEth", + AnkrStakeEth: "AnkrStakeEth", + AnkrStakeAvax: "AnkrStakeAvax", + AnkrStakeBsc: "AnkrStakeBsc", + AnkrStakePolygon: "AnkrStakePolygon", + AnkrStakeFantom: "AnkrStakeFantom", + AnkrStakeMatic: "AnkrStakeMatic", + OriginStakeEth: "OriginStakeEth", + BenqiStakeAvax: "BenqiStakeAvax", + StakewiseStakeEth: "StakewiseStakeEth", + SwellStakeEth: "SwellStakeEth", + SynClubStakeBnb: "SynClubStakeBnb", + MetaPoolStakeEth: "MetaPoolStakeEth", + AaveV3Supply: "AaveV3Supply", + AaveV3Borrow: "AaveV3Borrow", + AaveV3Payback: "AaveV3Payback", + DexSpanAdapter: "DexSpanAdapter", + ERC20Approval: "ERC20Approval", + ERC20Transfer: "ERC20Transfer", + UniswapV3Mint: "UniswapV3Mint", + SushiswapMint: "SushiswapMint", + CompoundSupply: "CompoundSupply", + CompoundBorrow: "CompoundBorrow", + QuickswapMint: "QuickswapMint", + PancakeswapMint: "PancakeswapMint", +}; diff --git a/evm/tasks/dexspan/DexSpanAdapter.deploy.ts b/evm/tasks/dexspan/DexSpanAdapter.deploy.ts new file mode 100644 index 0000000..25de45d --- /dev/null +++ b/evm/tasks/dexspan/DexSpanAdapter.deploy.ts @@ -0,0 +1,101 @@ +import { HardhatRuntimeEnvironment, TaskArguments } from "hardhat/types"; +import { + ASSET_FORWARDER, + CONTRACT_NAME, + DEFAULT_ENV, + DEFAULT_OWNER, + DEFAULT_REFUND_ADDRESS, + DEPLOY_DEXSPAN_ADAPTER, + DEXSPAN, + NATIVE, + VERIFY_DEXSPAN_ADAPTER, + WNATIVE, +} from "../constants"; +import { task } from "hardhat/config"; +import { + IDeployment, + getDeployments, + recordAllDeployments, + saveDeployments, +} from "../utils"; + +const contractName: string = CONTRACT_NAME.DexSpanAdapter; + +task(DEPLOY_DEXSPAN_ADAPTER) + .addFlag("verify", "pass true to verify the contract") + .setAction(async function ( + _taskArguments: TaskArguments, + _hre: HardhatRuntimeEnvironment + ) { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + + let defaultRefundAddress = process.env.DEFAULT_REFUND_ADDRESS; + if (!defaultRefundAddress) defaultRefundAddress = DEFAULT_REFUND_ADDRESS; + + let owner = process.env.OWNER; + if (!owner) owner = DEFAULT_OWNER; + + const network = await _hre.getChainId(); + + console.log(`Deploying ${contractName} Contract on chainId ${network}....`); + const factory = await _hre.ethers.getContractFactory(contractName); + const instance = await factory.deploy( + NATIVE, + WNATIVE[env][network], + owner, + ASSET_FORWARDER[env][network], + DEXSPAN[env][network], + defaultRefundAddress + ); + await instance.deployed(); + + const deployment: IDeployment = await recordAllDeployments( + env, + network, + contractName, + instance.address + ); + + await saveDeployments(deployment); + + console.log(`${contractName} contract deployed at`, instance.address); + + if (_taskArguments.verify === true) { + await _hre.run(VERIFY_DEXSPAN_ADAPTER); + } + }); + +task(VERIFY_DEXSPAN_ADAPTER).setAction(async function ( + _taskArguments: TaskArguments, + _hre: HardhatRuntimeEnvironment +) { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + + let defaultRefundAddress = process.env.DEFAULT_REFUND_ADDRESS; + if (!defaultRefundAddress) defaultRefundAddress = DEFAULT_REFUND_ADDRESS; + + let owner = process.env.OWNER; + if (!owner) owner = DEFAULT_OWNER; + + const network = await _hre.getChainId(); + + const deployments: IDeployment = getDeployments(); + const address = deployments[env][network][contractName]; + + console.log(`Verifying ${contractName} Contract....`); + await _hre.run("verify:verify", { + address, + constructorArguments: [ + NATIVE, + WNATIVE[env][network], + owner, + ASSET_FORWARDER[env][network], + DEXSPAN[env][network], + defaultRefundAddress, + ], + }); + + console.log(`Verified ${contractName} contract address `, address); +}); diff --git a/evm/tasks/dexspan/index.ts b/evm/tasks/dexspan/index.ts new file mode 100644 index 0000000..d00f405 --- /dev/null +++ b/evm/tasks/dexspan/index.ts @@ -0,0 +1 @@ +import "./DexSpanAdapter.deploy"; diff --git a/evm/tasks/erc20/ERC20Approval.deploy.ts b/evm/tasks/erc20/ERC20Approval.deploy.ts new file mode 100644 index 0000000..e0467f3 --- /dev/null +++ b/evm/tasks/erc20/ERC20Approval.deploy.ts @@ -0,0 +1,101 @@ +import { HardhatRuntimeEnvironment, TaskArguments } from "hardhat/types"; +import { + ASSET_FORWARDER, + CONTRACT_NAME, + DEFAULT_ENV, + DEFAULT_OWNER, + DEFAULT_REFUND_ADDRESS, + DEPLOY_ERC20_APPROVAL_ADAPTER, + DEXSPAN, + NATIVE, + VERIFY_ERC20_APPROVAL_ADAPTER, + WNATIVE, +} from "../constants"; +import { task } from "hardhat/config"; +import { + IDeployment, + getDeployments, + recordAllDeployments, + saveDeployments, +} from "../utils"; + +const contractName: string = CONTRACT_NAME.ERC20Approval; + +task(DEPLOY_ERC20_APPROVAL_ADAPTER) + .addFlag("verify", "pass true to verify the contract") + .setAction(async function ( + _taskArguments: TaskArguments, + _hre: HardhatRuntimeEnvironment + ) { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + + let defaultRefundAddress = process.env.DEFAULT_REFUND_ADDRESS; + if (!defaultRefundAddress) defaultRefundAddress = DEFAULT_REFUND_ADDRESS; + + let owner = process.env.OWNER; + if (!owner) owner = DEFAULT_OWNER; + + const network = await _hre.getChainId(); + + console.log(`Deploying ${contractName} Contract on chainId ${network}....`); + const factory = await _hre.ethers.getContractFactory(contractName); + const instance = await factory.deploy( + NATIVE, + WNATIVE[env][network], + owner, + ASSET_FORWARDER[env][network], + DEXSPAN[env][network], + defaultRefundAddress + ); + await instance.deployed(); + + const deployment: IDeployment = await recordAllDeployments( + env, + network, + contractName, + instance.address + ); + + await saveDeployments(deployment); + + console.log(`${contractName} contract deployed at`, instance.address); + + if (_taskArguments.verify === true) { + await _hre.run(VERIFY_ERC20_APPROVAL_ADAPTER); + } + }); + +task(VERIFY_ERC20_APPROVAL_ADAPTER).setAction(async function ( + _taskArguments: TaskArguments, + _hre: HardhatRuntimeEnvironment +) { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + + let defaultRefundAddress = process.env.DEFAULT_REFUND_ADDRESS; + if (!defaultRefundAddress) defaultRefundAddress = DEFAULT_REFUND_ADDRESS; + + let owner = process.env.OWNER; + if (!owner) owner = DEFAULT_OWNER; + + const network = await _hre.getChainId(); + + const deployments: IDeployment = getDeployments(); + const address = deployments[env][network][contractName]; + + console.log(`Verifying ${contractName} Contract....`); + await _hre.run("verify:verify", { + address, + constructorArguments: [ + NATIVE, + WNATIVE[env][network], + owner, + ASSET_FORWARDER[env][network], + DEXSPAN[env][network], + defaultRefundAddress, + ], + }); + + console.log(`Verified ${contractName} contract address `, address); +}); diff --git a/evm/tasks/erc20/ERC20Transfer.deploy.ts b/evm/tasks/erc20/ERC20Transfer.deploy.ts new file mode 100644 index 0000000..b7216e6 --- /dev/null +++ b/evm/tasks/erc20/ERC20Transfer.deploy.ts @@ -0,0 +1,101 @@ +import { HardhatRuntimeEnvironment, TaskArguments } from "hardhat/types"; +import { + ASSET_FORWARDER, + CONTRACT_NAME, + DEFAULT_ENV, + DEFAULT_OWNER, + DEFAULT_REFUND_ADDRESS, + DEPLOY_ERC20_TRANSFER_ADAPTER, + DEXSPAN, + NATIVE, + VERIFY_ERC20_TRANSFER_ADAPTER, + WNATIVE, +} from "../constants"; +import { task } from "hardhat/config"; +import { + IDeployment, + getDeployments, + recordAllDeployments, + saveDeployments, +} from "../utils"; + +const contractName: string = CONTRACT_NAME.ERC20Transfer; + +task(DEPLOY_ERC20_TRANSFER_ADAPTER) + .addFlag("verify", "pass true to verify the contract") + .setAction(async function ( + _taskArguments: TaskArguments, + _hre: HardhatRuntimeEnvironment + ) { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + + let defaultRefundAddress = process.env.DEFAULT_REFUND_ADDRESS; + if (!defaultRefundAddress) defaultRefundAddress = DEFAULT_REFUND_ADDRESS; + + let owner = process.env.OWNER; + if (!owner) owner = DEFAULT_OWNER; + + const network = await _hre.getChainId(); + + console.log(`Deploying ${contractName} Contract on chainId ${network}....`); + const factory = await _hre.ethers.getContractFactory(contractName); + const instance = await factory.deploy( + NATIVE, + WNATIVE[env][network], + owner, + ASSET_FORWARDER[env][network], + DEXSPAN[env][network], + defaultRefundAddress + ); + await instance.deployed(); + + const deployment: IDeployment = await recordAllDeployments( + env, + network, + contractName, + instance.address + ); + + await saveDeployments(deployment); + + console.log(`${contractName} contract deployed at`, instance.address); + + if (_taskArguments.verify === true) { + await _hre.run(VERIFY_ERC20_TRANSFER_ADAPTER); + } + }); + +task(VERIFY_ERC20_TRANSFER_ADAPTER).setAction(async function ( + _taskArguments: TaskArguments, + _hre: HardhatRuntimeEnvironment +) { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + + let defaultRefundAddress = process.env.DEFAULT_REFUND_ADDRESS; + if (!defaultRefundAddress) defaultRefundAddress = DEFAULT_REFUND_ADDRESS; + + let owner = process.env.OWNER; + if (!owner) owner = DEFAULT_OWNER; + + const network = await _hre.getChainId(); + + const deployments: IDeployment = getDeployments(); + const address = deployments[env][network][contractName]; + + console.log(`Verifying ${contractName} Contract....`); + await _hre.run("verify:verify", { + address, + constructorArguments: [ + NATIVE, + WNATIVE[env][network], + owner, + ASSET_FORWARDER[env][network], + DEXSPAN[env][network], + defaultRefundAddress, + ], + }); + + console.log(`Verified ${contractName} contract address `, address); +}); diff --git a/evm/tasks/erc20/index.ts b/evm/tasks/erc20/index.ts new file mode 100644 index 0000000..5928998 --- /dev/null +++ b/evm/tasks/erc20/index.ts @@ -0,0 +1 @@ +import "./ERC20Approval.deploy"; diff --git a/evm/tasks/frax/FraxStakeEth.deploy.ts b/evm/tasks/frax/FraxStakeEth.deploy.ts new file mode 100644 index 0000000..a71a302 --- /dev/null +++ b/evm/tasks/frax/FraxStakeEth.deploy.ts @@ -0,0 +1,106 @@ +import { HardhatRuntimeEnvironment, TaskArguments } from "hardhat/types"; +import { + ASSET_FORWARDER, + CONTRACT_NAME, + DEFAULT_ENV, + DEFAULT_OWNER, + DEFAULT_REFUND_ADDRESS, + DEPLOY_FRAX_STAKE_ETH_ADAPTER, + DEXSPAN, + NATIVE, + VERIFY_FRAX_STAKE_ETH_ADAPTER, + WNATIVE, +} from "../constants"; +import { task } from "hardhat/config"; +import { + IDeployment, + getDeployments, + recordAllDeployments, + saveDeployments, +} from "../utils"; +import { FRX_ETH, FRX_ETH_MINTER, S_FRX_ETH } from "./constants"; + +const contractName: string = CONTRACT_NAME.FraxStakeEth; + +task(DEPLOY_FRAX_STAKE_ETH_ADAPTER) + .addFlag("verify", "pass true to verify the contract") + .setAction(async function ( + _taskArguments: TaskArguments, + _hre: HardhatRuntimeEnvironment + ) { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + + let defaultRefundAddress = process.env.DEFAULT_REFUND_ADDRESS; + if (!defaultRefundAddress) defaultRefundAddress = DEFAULT_REFUND_ADDRESS; + + let owner = process.env.OWNER; + if (!owner) owner = DEFAULT_OWNER; + + const network = await _hre.getChainId(); + + console.log(`Deploying ${contractName} Contract on chainId ${network}....`); + const factory = await _hre.ethers.getContractFactory(contractName); + const instance = await factory.deploy( + NATIVE, + WNATIVE[env][network], + owner, + ASSET_FORWARDER[env][network], + DEXSPAN[env][network], + FRX_ETH[network], + S_FRX_ETH[network], + FRX_ETH_MINTER[network] + ); + await instance.deployed(); + + const deployment: IDeployment = await recordAllDeployments( + env, + network, + contractName, + instance.address + ); + + await saveDeployments(deployment); + + console.log(`${contractName} contract deployed at`, instance.address); + + if (_taskArguments.verify === true) { + await _hre.run(VERIFY_FRAX_STAKE_ETH_ADAPTER); + } + }); + +task(VERIFY_FRAX_STAKE_ETH_ADAPTER).setAction(async function ( + _taskArguments: TaskArguments, + _hre: HardhatRuntimeEnvironment +) { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + + let defaultRefundAddress = process.env.DEFAULT_REFUND_ADDRESS; + if (!defaultRefundAddress) defaultRefundAddress = DEFAULT_REFUND_ADDRESS; + + let owner = process.env.OWNER; + if (!owner) owner = DEFAULT_OWNER; + + const network = await _hre.getChainId(); + + const deployments: IDeployment = getDeployments(); + const address = deployments[env][network][contractName]; + + console.log(`Verifying ${contractName} Contract....`); + await _hre.run("verify:verify", { + address, + constructorArguments: [ + NATIVE, + WNATIVE[env][network], + owner, + ASSET_FORWARDER[env][network], + DEXSPAN[env][network], + FRX_ETH[network], + S_FRX_ETH[network], + FRX_ETH_MINTER[network] + ], + }); + + console.log(`Verified ${contractName} contract address `, address); +}); diff --git a/evm/tasks/frax/constants.ts b/evm/tasks/frax/constants.ts new file mode 100644 index 0000000..cb9d662 --- /dev/null +++ b/evm/tasks/frax/constants.ts @@ -0,0 +1,11 @@ +export const FRX_ETH_MINTER: { [chainId: string]: string } = { + "1": "0xbAFA44EFE7901E04E39Dad13167D089C559c1138", + }; + + export const FRX_ETH: { [chainId: string]: string } = { + "1": "0x5E8422345238F34275888049021821E8E08CAa1f", + }; + + export const S_FRX_ETH: { [chainId: string]: string } = { + "1": "0xac3E018457B222d93114458476f3E3416Abbe38F", + }; \ No newline at end of file diff --git a/evm/tasks/frax/index.ts b/evm/tasks/frax/index.ts new file mode 100644 index 0000000..b84b976 --- /dev/null +++ b/evm/tasks/frax/index.ts @@ -0,0 +1 @@ +import "./FraxStakeEth.deploy"; \ No newline at end of file diff --git a/evm/tasks/index.ts b/evm/tasks/index.ts new file mode 100644 index 0000000..1415d61 --- /dev/null +++ b/evm/tasks/index.ts @@ -0,0 +1,19 @@ +import "./stader"; +import "./lido"; +import "./ankr"; +import "./origin"; +import "./benqi"; +import "./rocketPool"; +import "./swell"; +import "./synClub"; +import "./metaPool"; +import "./frax"; +import "./dexspan"; +import "./erc20"; +import "./uniswapV3"; +import "./sushiswap"; +import "./aaveV3"; +import "./compound"; +import "./pancakeswap"; +import "./quickswap"; +import "./BatchTransaction.deploy"; diff --git a/evm/tasks/lido/LidoStakeEth.deploy.ts b/evm/tasks/lido/LidoStakeEth.deploy.ts new file mode 100644 index 0000000..c637416 --- /dev/null +++ b/evm/tasks/lido/LidoStakeEth.deploy.ts @@ -0,0 +1,104 @@ +import { HardhatRuntimeEnvironment, TaskArguments } from "hardhat/types"; +import { + ASSET_FORWARDER, + CONTRACT_NAME, + DEFAULT_ENV, + DEFAULT_OWNER, + DEFAULT_REFUND_ADDRESS, + DEPLOY_LIDO_STAKE_ETH_ADAPTER, + DEXSPAN, + NATIVE, + VERIFY_LIDO_STAKE_ETH_ADAPTER, + WNATIVE, +} from "../constants"; +import { task } from "hardhat/config"; +import { + IDeployment, + getDeployments, + recordAllDeployments, + saveDeployments, +} from "../utils"; +import { LIDO_ST_ETH, LIDO_REFERRAL_ADDRESS } from "./constants"; + +const contractName: string = CONTRACT_NAME.LidoStakeEth; + +task(DEPLOY_LIDO_STAKE_ETH_ADAPTER) + .addFlag("verify", "pass true to verify the contract") + .setAction(async function ( + _taskArguments: TaskArguments, + _hre: HardhatRuntimeEnvironment + ) { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + + let defaultRefundAddress = process.env.DEFAULT_REFUND_ADDRESS; + if (!defaultRefundAddress) defaultRefundAddress = DEFAULT_REFUND_ADDRESS; + + let owner = process.env.OWNER; + if (!owner) owner = DEFAULT_OWNER; + + const network = await _hre.getChainId(); + + console.log(`Deploying ${contractName} Contract on chainId ${network}....`); + const factory = await _hre.ethers.getContractFactory(contractName); + const instance = await factory.deploy( + NATIVE, + WNATIVE[env][network], + owner, + ASSET_FORWARDER[env][network], + DEXSPAN[env][network], + LIDO_ST_ETH[network], + LIDO_REFERRAL_ADDRESS + ); + await instance.deployed(); + + const deployment: IDeployment = await recordAllDeployments( + env, + network, + contractName, + instance.address + ); + + await saveDeployments(deployment); + + console.log(`${contractName} contract deployed at`, instance.address); + + if (_taskArguments.verify === true) { + await _hre.run(VERIFY_LIDO_STAKE_ETH_ADAPTER); + } + }); + +task(VERIFY_LIDO_STAKE_ETH_ADAPTER).setAction(async function ( + _taskArguments: TaskArguments, + _hre: HardhatRuntimeEnvironment +) { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + + let defaultRefundAddress = process.env.DEFAULT_REFUND_ADDRESS; + if (!defaultRefundAddress) defaultRefundAddress = DEFAULT_REFUND_ADDRESS; + + let owner = process.env.OWNER; + if (!owner) owner = DEFAULT_OWNER; + + const network = await _hre.getChainId(); + + const deployments: IDeployment = getDeployments(); + const address = deployments[env][network][contractName]; + + console.log(`Verifying ${contractName} Contract....`); + await _hre.run("verify:verify", { + address, + constructorArguments: [ + NATIVE, + WNATIVE[env][network], + owner, + ASSET_FORWARDER[env][network], + DEXSPAN[env][network], + LIDO_ST_ETH[network], + LIDO_REFERRAL_ADDRESS, + ], + }); + + console.log(`Verified ${contractName} contract address `, address); +}); diff --git a/evm/tasks/lido/LidoStakeMatic.deploy.ts b/evm/tasks/lido/LidoStakeMatic.deploy.ts new file mode 100644 index 0000000..1e91f49 --- /dev/null +++ b/evm/tasks/lido/LidoStakeMatic.deploy.ts @@ -0,0 +1,99 @@ +import { HardhatRuntimeEnvironment, TaskArguments } from "hardhat/types"; +import { + ASSET_FORWARDER, + CONTRACT_NAME, + DEFAULT_ENV, + DEFAULT_OWNER, + DEPLOY_LIDO_STAKE_MATIC_ADAPTER, + DEXSPAN, + NATIVE, + VERIFY_LIDO_STAKE_MATIC_ADAPTER, + WNATIVE, +} from "../constants"; +import { task } from "hardhat/config"; +import { + IDeployment, + getDeployments, + recordAllDeployments, + saveDeployments, +} from "../utils"; +import { LIDO_ST_MATIC, MATIC, LIDO_REFERRAL_ADDRESS } from "./constants"; + +const contractName: string = CONTRACT_NAME.LidoStakeMatic; + +task(DEPLOY_LIDO_STAKE_MATIC_ADAPTER) + .addFlag("verify", "pass true to verify the contract") + .setAction(async function ( + _taskArguments: TaskArguments, + _hre: HardhatRuntimeEnvironment + ) { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + + let owner = process.env.OWNER; + if (!owner) owner = DEFAULT_OWNER; + + const network = await _hre.getChainId(); + + console.log(`Deploying ${contractName} Contract on chainId ${network}....`); + const factory = await _hre.ethers.getContractFactory(contractName); + const instance = await factory.deploy( + NATIVE, + WNATIVE[env][network], + owner, + ASSET_FORWARDER[env][network], + DEXSPAN[env][network], + LIDO_ST_MATIC[network], + MATIC[network], + LIDO_REFERRAL_ADDRESS + ); + await instance.deployed(); + + const deployment: IDeployment = await recordAllDeployments( + env, + network, + contractName, + instance.address + ); + + await saveDeployments(deployment); + + console.log(`${contractName} contract deployed at`, instance.address); + + if (_taskArguments.verify === true) { + await _hre.run(VERIFY_LIDO_STAKE_MATIC_ADAPTER); + } + }); + +task(VERIFY_LIDO_STAKE_MATIC_ADAPTER).setAction(async function ( + _taskArguments: TaskArguments, + _hre: HardhatRuntimeEnvironment +) { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + + let owner = process.env.OWNER; + if (!owner) owner = DEFAULT_OWNER; + + const network = await _hre.getChainId(); + + const deployments: IDeployment = getDeployments(); + const address = deployments[env][network][contractName]; + + console.log(`Verifying ${contractName} Contract....`); + await _hre.run("verify:verify", { + address, + constructorArguments: [ + NATIVE, + WNATIVE[env][network], + owner, + ASSET_FORWARDER[env][network], + DEXSPAN[env][network], + LIDO_ST_MATIC[network], + MATIC[network], + LIDO_REFERRAL_ADDRESS, + ], + }); + + console.log(`Verified ${contractName} contract address `, address); +}); diff --git a/evm/tasks/lido/constants.ts b/evm/tasks/lido/constants.ts new file mode 100644 index 0000000..749e6cd --- /dev/null +++ b/evm/tasks/lido/constants.ts @@ -0,0 +1,18 @@ +export const LIDO_ST_ETH: { [chainId: string]: string } = { + "1": "0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84", + "5": "0x1643E812aE58766192Cf7D2Cf9567dF2C37e9B7F", + }; + + export const LIDO_ST_MATIC: { [chainId: string]: string } = { + "1": "0x9ee91F9f426fA633d227f7a9b000E28b9dfd8599", + "5": "0x9A7c69A167160C507602ecB3Df4911e8E98e1279", + }; + + export const MATIC: { [chainId: string]: string } = { + "1": "0x7D1AfA7B718fb893dB30A3aBc0Cfc608AaCfeBB0", + "5": "0x499d11E0b6eAC7c0593d8Fb292DCBbF815Fb29Ae", + }; + + // TODO: get actual referral address from Lido. + export const LIDO_REFERRAL_ADDRESS = + "0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84"; \ No newline at end of file diff --git a/evm/tasks/lido/index.ts b/evm/tasks/lido/index.ts new file mode 100644 index 0000000..17d4306 --- /dev/null +++ b/evm/tasks/lido/index.ts @@ -0,0 +1,2 @@ +import "./LidoStakeEth.deploy"; +import "./LidoStakeMatic.deploy"; \ No newline at end of file diff --git a/evm/tasks/metaPool/MetaPoolStakeEth.deploy.ts b/evm/tasks/metaPool/MetaPoolStakeEth.deploy.ts new file mode 100644 index 0000000..fc5677d --- /dev/null +++ b/evm/tasks/metaPool/MetaPoolStakeEth.deploy.ts @@ -0,0 +1,104 @@ +import { HardhatRuntimeEnvironment, TaskArguments } from "hardhat/types"; +import { + ASSET_FORWARDER, + CONTRACT_NAME, + DEFAULT_ENV, + DEFAULT_OWNER, + DEFAULT_REFUND_ADDRESS, + DEPLOY_METAPOOL_STAKE_ETH_ADAPTER, + DEXSPAN, + NATIVE, + VERIFY_METAPOOL_STAKE_ETH_ADAPTER, + WNATIVE, +} from "../constants"; +import { task } from "hardhat/config"; +import { + IDeployment, + getDeployments, + recordAllDeployments, + saveDeployments, +} from "../utils"; +import { METAPOOL_POOL, MP_ETH } from "./constants"; + +const contractName: string = CONTRACT_NAME.MetaPoolStakeEth; + +task(DEPLOY_METAPOOL_STAKE_ETH_ADAPTER) + .addFlag("verify", "pass true to verify the contract") + .setAction(async function ( + _taskArguments: TaskArguments, + _hre: HardhatRuntimeEnvironment + ) { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + + let defaultRefundAddress = process.env.DEFAULT_REFUND_ADDRESS; + if (!defaultRefundAddress) defaultRefundAddress = DEFAULT_REFUND_ADDRESS; + + let owner = process.env.OWNER; + if (!owner) owner = DEFAULT_OWNER; + + const network = await _hre.getChainId(); + + console.log(`Deploying ${contractName} Contract on chainId ${network}....`); + const factory = await _hre.ethers.getContractFactory(contractName); + const instance = await factory.deploy( + NATIVE, + WNATIVE[env][network], + owner, + ASSET_FORWARDER[env][network], + DEXSPAN[env][network], + MP_ETH[network], + METAPOOL_POOL[network] + ); + await instance.deployed(); + + const deployment: IDeployment = await recordAllDeployments( + env, + network, + contractName, + instance.address + ); + + await saveDeployments(deployment); + + console.log(`${contractName} contract deployed at`, instance.address); + + if (_taskArguments.verify === true) { + await _hre.run(VERIFY_METAPOOL_STAKE_ETH_ADAPTER); + } + }); + +task(VERIFY_METAPOOL_STAKE_ETH_ADAPTER).setAction(async function ( + _taskArguments: TaskArguments, + _hre: HardhatRuntimeEnvironment +) { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + + let defaultRefundAddress = process.env.DEFAULT_REFUND_ADDRESS; + if (!defaultRefundAddress) defaultRefundAddress = DEFAULT_REFUND_ADDRESS; + + let owner = process.env.OWNER; + if (!owner) owner = DEFAULT_OWNER; + + const network = await _hre.getChainId(); + + const deployments: IDeployment = getDeployments(); + const address = deployments[env][network][contractName]; + + console.log(`Verifying ${contractName} Contract....`); + await _hre.run("verify:verify", { + address, + constructorArguments: [ + NATIVE, + WNATIVE[env][network], + owner, + ASSET_FORWARDER[env][network], + DEXSPAN[env][network], + MP_ETH[network], + METAPOOL_POOL[network], + ], + }); + + console.log(`Verified ${contractName} contract address `, address); +}); diff --git a/evm/tasks/metaPool/constants.ts b/evm/tasks/metaPool/constants.ts new file mode 100644 index 0000000..4a4a8dc --- /dev/null +++ b/evm/tasks/metaPool/constants.ts @@ -0,0 +1,9 @@ +export const METAPOOL_POOL: { [chainId: string]: string } = { + "1": "0x48AFbBd342F64EF8a9Ab1C143719b63C2AD81710", + "5": "0x748c905130CC15b92B97084Fd1eEBc2d2419146f", + }; + + export const MP_ETH: { [chainId: string]: string } = { + "1": "0x48AFbBd342F64EF8a9Ab1C143719b63C2AD81710", + "5": "0x748c905130CC15b92B97084Fd1eEBc2d2419146f", + }; \ No newline at end of file diff --git a/evm/tasks/metaPool/index.ts b/evm/tasks/metaPool/index.ts new file mode 100644 index 0000000..a7ffb5d --- /dev/null +++ b/evm/tasks/metaPool/index.ts @@ -0,0 +1 @@ +import "./MetaPoolStakeEth.deploy"; diff --git a/evm/tasks/origin/OriginStakeEth.deploy.ts b/evm/tasks/origin/OriginStakeEth.deploy.ts new file mode 100644 index 0000000..15da7ec --- /dev/null +++ b/evm/tasks/origin/OriginStakeEth.deploy.ts @@ -0,0 +1,104 @@ +import { HardhatRuntimeEnvironment, TaskArguments } from "hardhat/types"; +import { + ASSET_FORWARDER, + CONTRACT_NAME, + DEFAULT_ENV, + DEFAULT_OWNER, + DEFAULT_REFUND_ADDRESS, + DEPLOY_ORIGIN_STAKE_ETH_ADAPTER, + DEXSPAN, + NATIVE, + VERIFY_ORIGIN_STAKE_ETH_ADAPTER, + WNATIVE, +} from "../constants"; +import { task } from "hardhat/config"; +import { + IDeployment, + getDeployments, + recordAllDeployments, + saveDeployments, +} from "../utils"; +import { ORIGIN_POOL, O_ETH } from "./constants"; + +const contractName: string = CONTRACT_NAME.OriginStakeEth; + +task(DEPLOY_ORIGIN_STAKE_ETH_ADAPTER) + .addFlag("verify", "pass true to verify the contract") + .setAction(async function ( + _taskArguments: TaskArguments, + _hre: HardhatRuntimeEnvironment + ) { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + + let defaultRefundAddress = process.env.DEFAULT_REFUND_ADDRESS; + if (!defaultRefundAddress) defaultRefundAddress = DEFAULT_REFUND_ADDRESS; + + let owner = process.env.OWNER; + if (!owner) owner = DEFAULT_OWNER; + + const network = await _hre.getChainId(); + + console.log(`Deploying ${contractName} Contract on chainId ${network}....`); + const factory = await _hre.ethers.getContractFactory(contractName); + const instance = await factory.deploy( + NATIVE, + WNATIVE[env][network], + owner, + ASSET_FORWARDER[env][network], + DEXSPAN[env][network], + O_ETH[network], + ORIGIN_POOL[network] + ); + await instance.deployed(); + + const deployment: IDeployment = await recordAllDeployments( + env, + network, + contractName, + instance.address + ); + + await saveDeployments(deployment); + + console.log(`${contractName} contract deployed at`, instance.address); + + if (_taskArguments.verify === true) { + await _hre.run(VERIFY_ORIGIN_STAKE_ETH_ADAPTER); + } + }); + +task(VERIFY_ORIGIN_STAKE_ETH_ADAPTER).setAction(async function ( + _taskArguments: TaskArguments, + _hre: HardhatRuntimeEnvironment +) { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + + let defaultRefundAddress = process.env.DEFAULT_REFUND_ADDRESS; + if (!defaultRefundAddress) defaultRefundAddress = DEFAULT_REFUND_ADDRESS; + + let owner = process.env.OWNER; + if (!owner) owner = DEFAULT_OWNER; + + const network = await _hre.getChainId(); + + const deployments: IDeployment = getDeployments(); + const address = deployments[env][network][contractName]; + + console.log(`Verifying ${contractName} Contract....`); + await _hre.run("verify:verify", { + address, + constructorArguments: [ + NATIVE, + WNATIVE[env][network], + owner, + ASSET_FORWARDER[env][network], + DEXSPAN[env][network], + O_ETH[network], + ORIGIN_POOL[network] + ], + }); + + console.log(`Verified ${contractName} contract address `, address); +}); diff --git a/evm/tasks/origin/constants.ts b/evm/tasks/origin/constants.ts new file mode 100644 index 0000000..23b2369 --- /dev/null +++ b/evm/tasks/origin/constants.ts @@ -0,0 +1,7 @@ +export const ORIGIN_POOL: { [chainId: string]: string } = { + "1": "0x9858e47BCbBe6fBAC040519B02d7cd4B2C470C66", + }; + + export const O_ETH: { [chainId: string]: string } = { + "1": "0x856c4Efb76C1D1AE02e20CEB03A2A6a08b0b8dC3", + }; \ No newline at end of file diff --git a/evm/tasks/origin/index.ts b/evm/tasks/origin/index.ts new file mode 100644 index 0000000..9428027 --- /dev/null +++ b/evm/tasks/origin/index.ts @@ -0,0 +1 @@ +import "./OriginStakeEth.deploy"; diff --git a/evm/tasks/pancakeswap/PancakeswapMint.deploy.ts b/evm/tasks/pancakeswap/PancakeswapMint.deploy.ts new file mode 100644 index 0000000..208e71f --- /dev/null +++ b/evm/tasks/pancakeswap/PancakeswapMint.deploy.ts @@ -0,0 +1,104 @@ +import { HardhatRuntimeEnvironment, TaskArguments } from "hardhat/types"; +import { + ASSET_FORWARDER, + CONTRACT_NAME, + DEFAULT_ENV, + DEFAULT_OWNER, + DEFAULT_REFUND_ADDRESS, + DEPLOY_PANCAKESWAP_MINT_ADAPTER, + DEXSPAN, + NATIVE, + VERIFY_PANCAKESWAP_MINT_ADAPTER, + WNATIVE, +} from "../constants"; +import { task } from "hardhat/config"; +import { + IDeployment, + getDeployments, + recordAllDeployments, + saveDeployments, +} from "../utils"; +import { POSITION_MANAGER } from "./constants"; + +const contractName: string = CONTRACT_NAME.PancakeswapMint; + +task(DEPLOY_PANCAKESWAP_MINT_ADAPTER) + .addFlag("verify", "pass true to verify the contract") + .setAction(async function ( + _taskArguments: TaskArguments, + _hre: HardhatRuntimeEnvironment + ) { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + + let defaultRefundAddress = process.env.DEFAULT_REFUND_ADDRESS; + if (!defaultRefundAddress) defaultRefundAddress = DEFAULT_REFUND_ADDRESS; + + let owner = process.env.OWNER; + if (!owner) owner = DEFAULT_OWNER; + + const network = await _hre.getChainId(); + + console.log(`Deploying ${contractName} Contract on chainId ${network}....`); + const factory = await _hre.ethers.getContractFactory(contractName); + const instance = await factory.deploy( + NATIVE, + WNATIVE[env][network], + owner, + ASSET_FORWARDER[env][network], + DEXSPAN[env][network], + defaultRefundAddress, + POSITION_MANAGER[network] + ); + await instance.deployed(); + + const deployment: IDeployment = await recordAllDeployments( + env, + network, + contractName, + instance.address + ); + + await saveDeployments(deployment); + + console.log(`${contractName} contract deployed at`, instance.address); + + if (_taskArguments.verify === true) { + await _hre.run(VERIFY_PANCAKESWAP_MINT_ADAPTER); + } + }); + +task(VERIFY_PANCAKESWAP_MINT_ADAPTER).setAction(async function ( + _taskArguments: TaskArguments, + _hre: HardhatRuntimeEnvironment +) { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + + let defaultRefundAddress = process.env.DEFAULT_REFUND_ADDRESS; + if (!defaultRefundAddress) defaultRefundAddress = DEFAULT_REFUND_ADDRESS; + + let owner = process.env.OWNER; + if (!owner) owner = DEFAULT_OWNER; + + const network = await _hre.getChainId(); + + const deployments: IDeployment = getDeployments(); + const address = deployments[env][network][contractName]; + + console.log(`Verifying ${contractName} Contract....`); + await _hre.run("verify:verify", { + address, + constructorArguments: [ + NATIVE, + WNATIVE[env][network], + owner, + ASSET_FORWARDER[env][network], + DEXSPAN[env][network], + defaultRefundAddress, + POSITION_MANAGER[network], + ], + }); + + console.log(`Verified ${contractName} contract address `, address); +}); diff --git a/evm/tasks/pancakeswap/constants.ts b/evm/tasks/pancakeswap/constants.ts new file mode 100644 index 0000000..4e1f625 --- /dev/null +++ b/evm/tasks/pancakeswap/constants.ts @@ -0,0 +1,4 @@ +export const POSITION_MANAGER: { [chainId: string]: string } = { + "97": "0x427bF5b37357632377eCbEC9de3626C71A5396c1", + "5": "0x427bF5b37357632377eCbEC9de3626C71A5396c1", + }; \ No newline at end of file diff --git a/evm/tasks/pancakeswap/index.ts b/evm/tasks/pancakeswap/index.ts new file mode 100644 index 0000000..b7df7c4 --- /dev/null +++ b/evm/tasks/pancakeswap/index.ts @@ -0,0 +1 @@ +import "./PancakeswapMint.deploy"; \ No newline at end of file diff --git a/evm/tasks/quickswap/QuickswapMint.deploy.ts b/evm/tasks/quickswap/QuickswapMint.deploy.ts new file mode 100644 index 0000000..79e1546 --- /dev/null +++ b/evm/tasks/quickswap/QuickswapMint.deploy.ts @@ -0,0 +1,104 @@ +import { HardhatRuntimeEnvironment, TaskArguments } from "hardhat/types"; +import { + ASSET_FORWARDER, + CONTRACT_NAME, + DEFAULT_ENV, + DEFAULT_OWNER, + DEFAULT_REFUND_ADDRESS, + DEPLOY_QUICKSWAP_MINT_ADAPTER, + DEXSPAN, + NATIVE, + VERIFY_QUICKSWAP_MINT_ADAPTER, + WNATIVE, +} from "../constants"; +import { task } from "hardhat/config"; +import { + IDeployment, + getDeployments, + recordAllDeployments, + saveDeployments, +} from "../utils"; +import { POSITION_MANAGER } from "./constants"; + +const contractName: string = CONTRACT_NAME.QuickswapMint; + +task(DEPLOY_QUICKSWAP_MINT_ADAPTER) + .addFlag("verify", "pass true to verify the contract") + .setAction(async function ( + _taskArguments: TaskArguments, + _hre: HardhatRuntimeEnvironment + ) { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + + let defaultRefundAddress = process.env.DEFAULT_REFUND_ADDRESS; + if (!defaultRefundAddress) defaultRefundAddress = DEFAULT_REFUND_ADDRESS; + + let owner = process.env.OWNER; + if (!owner) owner = DEFAULT_OWNER; + + const network = await _hre.getChainId(); + + console.log(`Deploying ${contractName} Contract on chainId ${network}....`); + const factory = await _hre.ethers.getContractFactory(contractName); + const instance = await factory.deploy( + NATIVE, + WNATIVE[env][network], + owner, + ASSET_FORWARDER[env][network], + DEXSPAN[env][network], + defaultRefundAddress, + POSITION_MANAGER[network] + ); + await instance.deployed(); + + const deployment: IDeployment = await recordAllDeployments( + env, + network, + contractName, + instance.address + ); + + await saveDeployments(deployment); + + console.log(`${contractName} contract deployed at`, instance.address); + + if (_taskArguments.verify === true) { + await _hre.run(VERIFY_QUICKSWAP_MINT_ADAPTER); + } + }); + +task(VERIFY_QUICKSWAP_MINT_ADAPTER).setAction(async function ( + _taskArguments: TaskArguments, + _hre: HardhatRuntimeEnvironment +) { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + + let defaultRefundAddress = process.env.DEFAULT_REFUND_ADDRESS; + if (!defaultRefundAddress) defaultRefundAddress = DEFAULT_REFUND_ADDRESS; + + let owner = process.env.OWNER; + if (!owner) owner = DEFAULT_OWNER; + + const network = await _hre.getChainId(); + + const deployments: IDeployment = getDeployments(); + const address = deployments[env][network][contractName]; + + console.log(`Verifying ${contractName} Contract....`); + await _hre.run("verify:verify", { + address, + constructorArguments: [ + NATIVE, + WNATIVE[env][network], + owner, + ASSET_FORWARDER[env][network], + DEXSPAN[env][network], + defaultRefundAddress, + POSITION_MANAGER[network], + ], + }); + + console.log(`Verified ${contractName} contract address `, address); +}); diff --git a/evm/tasks/quickswap/constants.ts b/evm/tasks/quickswap/constants.ts new file mode 100644 index 0000000..8590a52 --- /dev/null +++ b/evm/tasks/quickswap/constants.ts @@ -0,0 +1,4 @@ +export const POSITION_MANAGER: { [chainId: string]: string } = { + "137": "0x8eF88E4c7CfbbaC1C163f7eddd4B578792201de6", + }; + \ No newline at end of file diff --git a/evm/tasks/quickswap/index.ts b/evm/tasks/quickswap/index.ts new file mode 100644 index 0000000..3b061d9 --- /dev/null +++ b/evm/tasks/quickswap/index.ts @@ -0,0 +1 @@ +import "./QuickswapMint.deploy"; \ No newline at end of file diff --git a/evm/tasks/rocketPool/RPStakeEth.deploy.ts b/evm/tasks/rocketPool/RPStakeEth.deploy.ts new file mode 100644 index 0000000..709b258 --- /dev/null +++ b/evm/tasks/rocketPool/RPStakeEth.deploy.ts @@ -0,0 +1,104 @@ +import { HardhatRuntimeEnvironment, TaskArguments } from "hardhat/types"; +import { + ASSET_FORWARDER, + CONTRACT_NAME, + DEFAULT_ENV, + DEFAULT_OWNER, + DEFAULT_REFUND_ADDRESS, + DEPLOY_ROCKET_POOL_STAKE_ETH_ADAPTER, + DEXSPAN, + NATIVE, + VERIFY_ROCKET_POOL_STAKE_ETH_ADAPTER, + WNATIVE, +} from "../constants"; +import { task } from "hardhat/config"; +import { + IDeployment, + getDeployments, + recordAllDeployments, + saveDeployments, +} from "../utils"; +import { R_ETH, ROCKET_DEPOSIT_POOL } from "./constants"; + +const contractName: string = CONTRACT_NAME.RPStakeEth; + +task(DEPLOY_ROCKET_POOL_STAKE_ETH_ADAPTER) + .addFlag("verify", "pass true to verify the contract") + .setAction(async function ( + _taskArguments: TaskArguments, + _hre: HardhatRuntimeEnvironment + ) { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + + let defaultRefundAddress = process.env.DEFAULT_REFUND_ADDRESS; + if (!defaultRefundAddress) defaultRefundAddress = DEFAULT_REFUND_ADDRESS; + + let owner = process.env.OWNER; + if (!owner) owner = DEFAULT_OWNER; + + const network = await _hre.getChainId(); + + console.log(`Deploying ${contractName} Contract on chainId ${network}....`); + const factory = await _hre.ethers.getContractFactory(contractName); + const instance = await factory.deploy( + NATIVE, + WNATIVE[env][network], + owner, + ASSET_FORWARDER[env][network], + DEXSPAN[env][network], + R_ETH[network], + ROCKET_DEPOSIT_POOL[network] + ); + await instance.deployed(); + + const deployment: IDeployment = await recordAllDeployments( + env, + network, + contractName, + instance.address + ); + + await saveDeployments(deployment); + + console.log(`${contractName} contract deployed at`, instance.address); + + if (_taskArguments.verify === true) { + await _hre.run(VERIFY_ROCKET_POOL_STAKE_ETH_ADAPTER); + } + }); + +task(VERIFY_ROCKET_POOL_STAKE_ETH_ADAPTER).setAction(async function ( + _taskArguments: TaskArguments, + _hre: HardhatRuntimeEnvironment +) { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + + let defaultRefundAddress = process.env.DEFAULT_REFUND_ADDRESS; + if (!defaultRefundAddress) defaultRefundAddress = DEFAULT_REFUND_ADDRESS; + + let owner = process.env.OWNER; + if (!owner) owner = DEFAULT_OWNER; + + const network = await _hre.getChainId(); + + const deployments: IDeployment = getDeployments(); + const address = deployments[env][network][contractName]; + + console.log(`Verifying ${contractName} Contract....`); + await _hre.run("verify:verify", { + address, + constructorArguments: [ + NATIVE, + WNATIVE[env][network], + owner, + ASSET_FORWARDER[env][network], + DEXSPAN[env][network], + R_ETH[network], + ROCKET_DEPOSIT_POOL[network], + ], + }); + + console.log(`Verified ${contractName} contract address `, address); +}); diff --git a/evm/tasks/rocketPool/constants.ts b/evm/tasks/rocketPool/constants.ts new file mode 100644 index 0000000..81257db --- /dev/null +++ b/evm/tasks/rocketPool/constants.ts @@ -0,0 +1,11 @@ +export const ROCKET_DEPOSIT_POOL: { [chainId: string]: string } = { + "1": "0xDD3f50F8A6CafbE9b31a427582963f465E745AF8", + "5": "0xa9A6A14A3643690D0286574976F45abBDAD8f505", + "17000": "0x320f3aAB9405e38b955178BBe75c477dECBA0C27", + }; + + export const R_ETH: { [chainId: string]: string } = { + "1": "0xae78736Cd615f374D3085123A210448E74Fc6393", + "5": "0x178E141a0E3b34152f73Ff610437A7bf9B83267A", + "17000": "0x7322c24752f79c05FFD1E2a6FCB97020C1C264F1", + }; \ No newline at end of file diff --git a/evm/tasks/rocketPool/index.ts b/evm/tasks/rocketPool/index.ts new file mode 100644 index 0000000..c0434c8 --- /dev/null +++ b/evm/tasks/rocketPool/index.ts @@ -0,0 +1 @@ +import "./RPStakeEth.deploy"; \ No newline at end of file diff --git a/evm/tasks/stader/StaderStakeBnb.deploy.ts b/evm/tasks/stader/StaderStakeBnb.deploy.ts new file mode 100644 index 0000000..4256c55 --- /dev/null +++ b/evm/tasks/stader/StaderStakeBnb.deploy.ts @@ -0,0 +1,104 @@ +import { HardhatRuntimeEnvironment, TaskArguments } from "hardhat/types"; +import { + ASSET_FORWARDER, + CONTRACT_NAME, + DEFAULT_ENV, + DEFAULT_OWNER, + DEFAULT_REFUND_ADDRESS, + DEPLOY_STADER_STAKE_BNB_ADAPTER, + DEXSPAN, + NATIVE, + VERIFY_STADER_STAKE_BNB_ADAPTER, + WNATIVE, +} from "../constants"; +import { task } from "hardhat/config"; +import { + IDeployment, + getDeployments, + recordAllDeployments, + saveDeployments, +} from "../utils"; +import { STADER_BNB_X_TOKEN, STADER_POOL } from "./constants"; + +const contractName: string = CONTRACT_NAME.StaderStakeBnb; + +task(DEPLOY_STADER_STAKE_BNB_ADAPTER) + .addFlag("verify", "pass true to verify the contract") + .setAction(async function ( + _taskArguments: TaskArguments, + _hre: HardhatRuntimeEnvironment + ) { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + + let defaultRefundAddress = process.env.DEFAULT_REFUND_ADDRESS; + if (!defaultRefundAddress) defaultRefundAddress = DEFAULT_REFUND_ADDRESS; + + let owner = process.env.OWNER; + if (!owner) owner = DEFAULT_OWNER; + + const network = await _hre.getChainId(); + + console.log(`Deploying ${contractName} Contract on chainId ${network}....`); + const factory = await _hre.ethers.getContractFactory(contractName); + const instance = await factory.deploy( + NATIVE, + WNATIVE[env][network], + owner, + ASSET_FORWARDER[env][network], + DEXSPAN[env][network], + STADER_BNB_X_TOKEN[network], + STADER_POOL[network] + ); + await instance.deployed(); + + const deployment: IDeployment = await recordAllDeployments( + env, + network, + contractName, + instance.address + ); + + await saveDeployments(deployment); + + console.log(`${contractName} contract deployed at`, instance.address); + + if (_taskArguments.verify === true) { + await _hre.run(VERIFY_STADER_STAKE_BNB_ADAPTER); + } + }); + +task(VERIFY_STADER_STAKE_BNB_ADAPTER).setAction(async function ( + _taskArguments: TaskArguments, + _hre: HardhatRuntimeEnvironment +) { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + + let defaultRefundAddress = process.env.DEFAULT_REFUND_ADDRESS; + if (!defaultRefundAddress) defaultRefundAddress = DEFAULT_REFUND_ADDRESS; + + let owner = process.env.OWNER; + if (!owner) owner = DEFAULT_OWNER; + + const network = await _hre.getChainId(); + + const deployments: IDeployment = getDeployments(); + const address = deployments[env][network][contractName]; + + console.log(`Verifying ${contractName} Contract....`); + await _hre.run("verify:verify", { + address, + constructorArguments: [ + NATIVE, + WNATIVE[env][network], + owner, + ASSET_FORWARDER[env][network], + DEXSPAN[env][network], + STADER_BNB_X_TOKEN[network], + STADER_POOL[network], + ], + }); + + console.log(`Verified ${contractName} contract address `, address); +}); diff --git a/evm/tasks/stader/StaderStakeEth.deploy.ts b/evm/tasks/stader/StaderStakeEth.deploy.ts new file mode 100644 index 0000000..72c27d6 --- /dev/null +++ b/evm/tasks/stader/StaderStakeEth.deploy.ts @@ -0,0 +1,104 @@ +import { HardhatRuntimeEnvironment, TaskArguments } from "hardhat/types"; +import { + ASSET_FORWARDER, + CONTRACT_NAME, + DEFAULT_ENV, + DEFAULT_OWNER, + DEFAULT_REFUND_ADDRESS, + DEPLOY_STADER_STAKE_ETH_ADAPTER, + DEXSPAN, + NATIVE, + VERIFY_STADER_STAKE_ETH_ADAPTER, + WNATIVE, +} from "../constants"; +import { task } from "hardhat/config"; +import { + IDeployment, + getDeployments, + recordAllDeployments, + saveDeployments, +} from "../utils"; +import { STADER_ETH_X_TOKEN, STADER_POOL } from "./constants"; + +const contractName: string = CONTRACT_NAME.StaderStakeEth; + +task(DEPLOY_STADER_STAKE_ETH_ADAPTER) + .addFlag("verify", "pass true to verify the contract") + .setAction(async function ( + _taskArguments: TaskArguments, + _hre: HardhatRuntimeEnvironment + ) { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + + let defaultRefundAddress = process.env.DEFAULT_REFUND_ADDRESS; + if (!defaultRefundAddress) defaultRefundAddress = DEFAULT_REFUND_ADDRESS; + + let owner = process.env.OWNER; + if (!owner) owner = DEFAULT_OWNER; + + const network = await _hre.getChainId(); + + console.log(`Deploying ${contractName} Contract on chainId ${network}....`); + const factory = await _hre.ethers.getContractFactory(contractName); + const instance = await factory.deploy( + NATIVE, + WNATIVE[env][network], + owner, + ASSET_FORWARDER[env][network], + DEXSPAN[env][network], + STADER_ETH_X_TOKEN[network], + STADER_POOL[network] + ); + await instance.deployed(); + + const deployment: IDeployment = await recordAllDeployments( + env, + network, + contractName, + instance.address + ); + + await saveDeployments(deployment); + + console.log(`${contractName} contract deployed at`, instance.address); + + if (_taskArguments.verify === true) { + await _hre.run(VERIFY_STADER_STAKE_ETH_ADAPTER); + } + }); + +task(VERIFY_STADER_STAKE_ETH_ADAPTER).setAction(async function ( + _taskArguments: TaskArguments, + _hre: HardhatRuntimeEnvironment +) { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + + let defaultRefundAddress = process.env.DEFAULT_REFUND_ADDRESS; + if (!defaultRefundAddress) defaultRefundAddress = DEFAULT_REFUND_ADDRESS; + + let owner = process.env.OWNER; + if (!owner) owner = DEFAULT_OWNER; + + const network = await _hre.getChainId(); + + const deployments: IDeployment = getDeployments(); + const address = deployments[env][network][contractName]; + + console.log(`Verifying ${contractName} Contract....`); + await _hre.run("verify:verify", { + address, + constructorArguments: [ + NATIVE, + WNATIVE[env][network], + owner, + ASSET_FORWARDER[env][network], + DEXSPAN[env][network], + STADER_ETH_X_TOKEN[network], + STADER_POOL[network], + ], + }); + + console.log(`Verified ${contractName} contract address `, address); +}); diff --git a/evm/tasks/stader/StaderStakeFtm.deploy.ts b/evm/tasks/stader/StaderStakeFtm.deploy.ts new file mode 100644 index 0000000..da5d6e2 --- /dev/null +++ b/evm/tasks/stader/StaderStakeFtm.deploy.ts @@ -0,0 +1,97 @@ +import { HardhatRuntimeEnvironment, TaskArguments } from "hardhat/types"; +import { + ASSET_FORWARDER, + CONTRACT_NAME, + DEFAULT_ENV, + DEFAULT_OWNER, + DEPLOY_STADER_STAKE_FTM_ADAPTER, + DEXSPAN, + NATIVE, + VERIFY_STADER_STAKE_FTM_ADAPTER, + WNATIVE, +} from "../constants"; +import { task } from "hardhat/config"; +import { + IDeployment, + getDeployments, + recordAllDeployments, + saveDeployments, +} from "../utils"; +import { STADER_SFTM_X_TOKEN, STADER_POOL } from "./constants"; + +const contractName: string = CONTRACT_NAME.StaderStakeFtm; + +task(DEPLOY_STADER_STAKE_FTM_ADAPTER) + .addFlag("verify", "pass true to verify the contract") + .setAction(async function ( + _taskArguments: TaskArguments, + _hre: HardhatRuntimeEnvironment + ) { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + + let owner = process.env.OWNER; + if (!owner) owner = DEFAULT_OWNER; + + const network = await _hre.getChainId(); + + console.log(`Deploying ${contractName} Contract on chainId ${network}....`); + const factory = await _hre.ethers.getContractFactory(contractName); + const instance = await factory.deploy( + NATIVE, + WNATIVE[env][network], + owner, + ASSET_FORWARDER[env][network], + DEXSPAN[env][network], + STADER_SFTM_X_TOKEN[network], + STADER_POOL[network] + ); + await instance.deployed(); + + const deployment: IDeployment = await recordAllDeployments( + env, + network, + contractName, + instance.address + ); + + await saveDeployments(deployment); + + console.log(`${contractName} contract deployed at`, instance.address); + + if (_taskArguments.verify === true) { + await _hre.run(VERIFY_STADER_STAKE_FTM_ADAPTER); + } + }); + +task(VERIFY_STADER_STAKE_FTM_ADAPTER).setAction(async function ( + _taskArguments: TaskArguments, + _hre: HardhatRuntimeEnvironment +) { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + + let owner = process.env.OWNER; + if (!owner) owner = DEFAULT_OWNER; + + const network = await _hre.getChainId(); + + const deployments: IDeployment = getDeployments(); + const address = deployments[env][network][contractName]; + + console.log(`Verifying ${contractName} Contract....`); + await _hre.run("verify:verify", { + address, + constructorArguments: [ + NATIVE, + WNATIVE[env][network], + owner, + ASSET_FORWARDER[env][network], + DEXSPAN[env][network], + STADER_SFTM_X_TOKEN[network], + STADER_POOL[network], + ], + }); + + console.log(`Verified ${contractName} contract address `, address); +}); diff --git a/evm/tasks/stader/StaderStakeMatic.deploy.ts b/evm/tasks/stader/StaderStakeMatic.deploy.ts new file mode 100644 index 0000000..8bad429 --- /dev/null +++ b/evm/tasks/stader/StaderStakeMatic.deploy.ts @@ -0,0 +1,97 @@ +import { HardhatRuntimeEnvironment, TaskArguments } from "hardhat/types"; +import { + ASSET_FORWARDER, + CONTRACT_NAME, + DEFAULT_ENV, + DEFAULT_OWNER, + DEPLOY_STADER_STAKE_MATIC_ADAPTER, + DEXSPAN, + NATIVE, + VERIFY_STADER_STAKE_MATIC_ADAPTER, + WNATIVE, +} from "../constants"; +import { task } from "hardhat/config"; +import { + IDeployment, + getDeployments, + recordAllDeployments, + saveDeployments, +} from "../utils"; +import { MATIC, STADER_MATIC_X_TOKEN } from "./constants"; + +const contractName = CONTRACT_NAME.StaderStakeMatic; + +task(DEPLOY_STADER_STAKE_MATIC_ADAPTER) + .addFlag("verify", "pass true to verify the contract") + .setAction(async function ( + _taskArguments: TaskArguments, + _hre: HardhatRuntimeEnvironment + ) { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + + let owner = process.env.OWNER; + if (!owner) owner = DEFAULT_OWNER; + + const network = await _hre.getChainId(); + + console.log(`Deploying ${contractName} Contract on chainId ${network}....`); + const factory = await _hre.ethers.getContractFactory(contractName); + const instance = await factory.deploy( + NATIVE, + WNATIVE[env][network], + owner, + ASSET_FORWARDER[env][network], + DEXSPAN[env][network], + STADER_MATIC_X_TOKEN[network], + MATIC[network] + ); + await instance.deployed(); + + const deployment: IDeployment = await recordAllDeployments( + env, + network, + contractName, + instance.address + ); + + await saveDeployments(deployment); + + console.log(`${contractName} contract deployed at`, instance.address); + + if (_taskArguments.verify === true) { + await _hre.run(VERIFY_STADER_STAKE_MATIC_ADAPTER); + } + }); + +task(VERIFY_STADER_STAKE_MATIC_ADAPTER).setAction(async function ( + _taskArguments: TaskArguments, + _hre: HardhatRuntimeEnvironment +) { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + + let owner = process.env.OWNER; + if (!owner) owner = DEFAULT_OWNER; + + const network = await _hre.getChainId(); + + const deployments: IDeployment = getDeployments(); + const address = deployments[env][network][contractName]; + + console.log(`Verifying ${contractName} Contract....`); + await _hre.run("verify:verify", { + address, + constructorArguments: [ + NATIVE, + WNATIVE[env][network], + owner, + ASSET_FORWARDER[env][network], + DEXSPAN[env][network], + STADER_MATIC_X_TOKEN[network], + MATIC[network], + ], + }); + + console.log(`Verified ${contractName} contract address `, address); +}); diff --git a/evm/tasks/stader/StaderStakePolygon.deploy.ts b/evm/tasks/stader/StaderStakePolygon.deploy.ts new file mode 100644 index 0000000..5668f23 --- /dev/null +++ b/evm/tasks/stader/StaderStakePolygon.deploy.ts @@ -0,0 +1,97 @@ +import { HardhatRuntimeEnvironment, TaskArguments } from "hardhat/types"; +import { + ASSET_FORWARDER, + CONTRACT_NAME, + DEFAULT_ENV, + DEFAULT_OWNER, + DEPLOY_STADER_STAKE_POLYGON_ADAPTER, + DEXSPAN, + NATIVE, + VERIFY_STADER_STAKE_POLYGON_ADAPTER, + WNATIVE, +} from "../constants"; +import { task } from "hardhat/config"; +import { + IDeployment, + getDeployments, + recordAllDeployments, + saveDeployments, +} from "../utils"; +import { STADER_MATIC_X_TOKEN, STADER_POOL } from "./constants"; + +const contractName = CONTRACT_NAME.StaderStakePolygon; + +task(DEPLOY_STADER_STAKE_POLYGON_ADAPTER) + .addFlag("verify", "pass true to verify the contract") + .setAction(async function ( + _taskArguments: TaskArguments, + _hre: HardhatRuntimeEnvironment + ) { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + + let owner = process.env.OWNER; + if (!owner) owner = DEFAULT_OWNER; + + const network = await _hre.getChainId(); + + console.log(`Deploying ${contractName} Contract on chainId ${network}....`); + const factory = await _hre.ethers.getContractFactory(contractName); + const instance = await factory.deploy( + NATIVE, + WNATIVE[env][network], + owner, + ASSET_FORWARDER[env][network], + DEXSPAN[env][network], + STADER_MATIC_X_TOKEN[network], + STADER_POOL[network] + ); + await instance.deployed(); + + const deployment: IDeployment = await recordAllDeployments( + env, + network, + contractName, + instance.address + ); + + await saveDeployments(deployment); + + console.log(`${contractName} contract deployed at`, instance.address); + + if (_taskArguments.verify === true) { + await _hre.run(VERIFY_STADER_STAKE_POLYGON_ADAPTER); + } + }); + +task(VERIFY_STADER_STAKE_POLYGON_ADAPTER).setAction(async function ( + _taskArguments: TaskArguments, + _hre: HardhatRuntimeEnvironment +) { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + + let owner = process.env.OWNER; + if (!owner) owner = DEFAULT_OWNER; + + const network = await _hre.getChainId(); + + const deployments: IDeployment = getDeployments(); + const address = deployments[env][network][contractName]; + + console.log(`Verifying ${contractName} Contract....`); + await _hre.run("verify:verify", { + address, + constructorArguments: [ + NATIVE, + WNATIVE[env][network], + owner, + ASSET_FORWARDER[env][network], + DEXSPAN[env][network], + STADER_MATIC_X_TOKEN[network], + STADER_POOL[network], + ], + }); + + console.log(`Verified ${contractName} contract address `, address); +}); diff --git a/evm/tasks/stader/constants.ts b/evm/tasks/stader/constants.ts new file mode 100644 index 0000000..0486230 --- /dev/null +++ b/evm/tasks/stader/constants.ts @@ -0,0 +1,29 @@ +export const STADER_ETH_X_TOKEN: { [chainId: string]: string } = { + "1": "0xA35b1B31Ce002FBF2058D22F30f95D405200A15b", + "5": "0x3338eCd3ab3d3503c55c931d759fA6d78d287236", +}; + +export const STADER_MATIC_X_TOKEN: { [chainId: string]: string } = { + "1": "0xf03A7Eb46d01d9EcAA104558C732Cf82f6B6B645", + "137": "0xfa68FB4628DFF1028CFEc22b4162FCcd0d45efb6", +}; + +export const STADER_BNB_X_TOKEN: { [chainId: string]: string } = { + "56": "0x1bdd3Cf7F79cfB8EdbB955f20ad99211551BA275", +}; + +export const STADER_SFTM_X_TOKEN: { [chainId: string]: string } = { + "250": "0xd7028092c830b5C8FcE061Af2E593413EbbC1fc1", +}; + +export const MATIC: { [chainId: string]: string } = { + "1": "0x7D1AfA7B718fb893dB30A3aBc0Cfc608AaCfeBB0", +}; + +export const STADER_POOL: { [chainId: string]: string } = { + "1": "0xcf5EA1b38380f6aF39068375516Daf40Ed70D299", + "5": "0xd0e400Ec6Ed9C803A9D9D3a602494393E806F823", + "137": "0xfd225C9e6601C9d38d8F98d8731BF59eFcF8C0E3", + "56": "0x7276241a669489E4BBB76f63d2A43Bfe63080F2F", + "250": "0xB458BfC855ab504a8a327720FcEF98886065529b", +}; diff --git a/evm/tasks/stader/index.ts b/evm/tasks/stader/index.ts new file mode 100644 index 0000000..94eb043 --- /dev/null +++ b/evm/tasks/stader/index.ts @@ -0,0 +1,5 @@ +import "./StaderStakeEth.deploy"; +import "./StaderStakeMatic.deploy"; +import "./StaderStakePolygon.deploy"; +import "./StaderStakeBnb.deploy"; +import "./StaderStakeFtm.deploy"; diff --git a/evm/tasks/sushiswap/SushiswapMint.deploy.ts b/evm/tasks/sushiswap/SushiswapMint.deploy.ts new file mode 100644 index 0000000..db8ac44 --- /dev/null +++ b/evm/tasks/sushiswap/SushiswapMint.deploy.ts @@ -0,0 +1,104 @@ +import { HardhatRuntimeEnvironment, TaskArguments } from "hardhat/types"; +import { + ASSET_FORWARDER, + CONTRACT_NAME, + DEFAULT_ENV, + DEFAULT_OWNER, + DEFAULT_REFUND_ADDRESS, + DEPLOY_SUSHISWAP_MINT_ADAPTER, + DEXSPAN, + NATIVE, + VERIFY_SUSHISWAP_MINT_ADAPTER, + WNATIVE, +} from "../constants"; +import { task } from "hardhat/config"; +import { + IDeployment, + getDeployments, + recordAllDeployments, + saveDeployments, +} from "../utils"; +import { POSITION_MANAGER } from "./constants"; + +const contractName: string = CONTRACT_NAME.SushiswapMint; + +task(DEPLOY_SUSHISWAP_MINT_ADAPTER) + .addFlag("verify", "pass true to verify the contract") + .setAction(async function ( + _taskArguments: TaskArguments, + _hre: HardhatRuntimeEnvironment + ) { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + + let defaultRefundAddress = process.env.DEFAULT_REFUND_ADDRESS; + if (!defaultRefundAddress) defaultRefundAddress = DEFAULT_REFUND_ADDRESS; + + let owner = process.env.OWNER; + if (!owner) owner = DEFAULT_OWNER; + + const network = await _hre.getChainId(); + + console.log(`Deploying ${contractName} Contract on chainId ${network}....`); + const factory = await _hre.ethers.getContractFactory(contractName); + const instance = await factory.deploy( + NATIVE, + WNATIVE[env][network], + owner, + ASSET_FORWARDER[env][network], + DEXSPAN[env][network], + defaultRefundAddress, + POSITION_MANAGER[network] + ); + await instance.deployed(); + + const deployment: IDeployment = await recordAllDeployments( + env, + network, + contractName, + instance.address + ); + + await saveDeployments(deployment); + + console.log(`${contractName} contract deployed at`, instance.address); + + if (_taskArguments.verify === true) { + await _hre.run(VERIFY_SUSHISWAP_MINT_ADAPTER); + } + }); + +task(VERIFY_SUSHISWAP_MINT_ADAPTER).setAction(async function ( + _taskArguments: TaskArguments, + _hre: HardhatRuntimeEnvironment +) { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + + let defaultRefundAddress = process.env.DEFAULT_REFUND_ADDRESS; + if (!defaultRefundAddress) defaultRefundAddress = DEFAULT_REFUND_ADDRESS; + + let owner = process.env.OWNER; + if (!owner) owner = DEFAULT_OWNER; + + const network = await _hre.getChainId(); + + const deployments: IDeployment = getDeployments(); + const address = deployments[env][network][contractName]; + + console.log(`Verifying ${contractName} Contract....`); + await _hre.run("verify:verify", { + address, + constructorArguments: [ + NATIVE, + WNATIVE[env][network], + owner, + ASSET_FORWARDER[env][network], + DEXSPAN[env][network], + defaultRefundAddress, + POSITION_MANAGER[network], + ], + }); + + console.log(`Verified ${contractName} contract address `, address); +}); diff --git a/evm/tasks/sushiswap/constants.ts b/evm/tasks/sushiswap/constants.ts new file mode 100644 index 0000000..e512ba3 --- /dev/null +++ b/evm/tasks/sushiswap/constants.ts @@ -0,0 +1,8 @@ +export const POSITION_MANAGER: { [chainId: string]: string } = { + "137": "0xb7402ee99F0A008e461098AC3A27F4957Df89a40", + "43114": "0x18350b048AB366ed601fFDbC669110Ecb36016f3", + "42161": "0xF0cBce1942A68BEB3d1b73F0dd86C8DCc363eF49", + "10": "0x1af415a1EbA07a4986a52B6f2e7dE7003D82231e", + "56": "0xF70c086618dcf2b1A461311275e00D6B722ef914", + "250": "0x10c19390E1Ac2Fd6D0c3643a2320b0abA38E5bAA", + }; \ No newline at end of file diff --git a/evm/tasks/sushiswap/index.ts b/evm/tasks/sushiswap/index.ts new file mode 100644 index 0000000..14dadda --- /dev/null +++ b/evm/tasks/sushiswap/index.ts @@ -0,0 +1 @@ +import "./SushiswapMint.deploy"; \ No newline at end of file diff --git a/evm/tasks/swell/SwellStakeEth.deploy.ts b/evm/tasks/swell/SwellStakeEth.deploy.ts new file mode 100644 index 0000000..2b7f7b8 --- /dev/null +++ b/evm/tasks/swell/SwellStakeEth.deploy.ts @@ -0,0 +1,102 @@ +import { HardhatRuntimeEnvironment, TaskArguments } from "hardhat/types"; +import { + ASSET_FORWARDER, + CONTRACT_NAME, + DEFAULT_ENV, + DEFAULT_OWNER, + DEFAULT_REFUND_ADDRESS, + DEPLOY_SWELL_STAKE_ETH_ADAPTER, + DEXSPAN, + NATIVE, + VERIFY_SWELL_STAKE_ETH_ADAPTER, + WNATIVE, +} from "../constants"; +import { task } from "hardhat/config"; +import { + IDeployment, + getDeployments, + recordAllDeployments, + saveDeployments, +} from "../utils"; +import { SWELL_SW_ETH } from "./constants"; + +const contractName: string = CONTRACT_NAME.SwellStakeEth; + +task(DEPLOY_SWELL_STAKE_ETH_ADAPTER) + .addFlag("verify", "pass true to verify the contract") + .setAction(async function ( + _taskArguments: TaskArguments, + _hre: HardhatRuntimeEnvironment + ) { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + + let defaultRefundAddress = process.env.DEFAULT_REFUND_ADDRESS; + if (!defaultRefundAddress) defaultRefundAddress = DEFAULT_REFUND_ADDRESS; + + let owner = process.env.OWNER; + if (!owner) owner = DEFAULT_OWNER; + + const network = await _hre.getChainId(); + + console.log(`Deploying ${contractName} Contract on chainId ${network}....`); + const factory = await _hre.ethers.getContractFactory(contractName); + const instance = await factory.deploy( + NATIVE, + WNATIVE[env][network], + owner, + ASSET_FORWARDER[env][network], + DEXSPAN[env][network], + SWELL_SW_ETH[network], + ); + await instance.deployed(); + + const deployment: IDeployment = await recordAllDeployments( + env, + network, + contractName, + instance.address + ); + + await saveDeployments(deployment); + + console.log(`${contractName} contract deployed at`, instance.address); + + if (_taskArguments.verify === true) { + await _hre.run(VERIFY_SWELL_STAKE_ETH_ADAPTER); + } + }); + +task(VERIFY_SWELL_STAKE_ETH_ADAPTER).setAction(async function ( + _taskArguments: TaskArguments, + _hre: HardhatRuntimeEnvironment +) { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + + let defaultRefundAddress = process.env.DEFAULT_REFUND_ADDRESS; + if (!defaultRefundAddress) defaultRefundAddress = DEFAULT_REFUND_ADDRESS; + + let owner = process.env.OWNER; + if (!owner) owner = DEFAULT_OWNER; + + const network = await _hre.getChainId(); + + const deployments: IDeployment = getDeployments(); + const address = deployments[env][network][contractName]; + + console.log(`Verifying ${contractName} Contract....`); + await _hre.run("verify:verify", { + address, + constructorArguments: [ + NATIVE, + WNATIVE[env][network], + owner, + ASSET_FORWARDER[env][network], + DEXSPAN[env][network], + SWELL_SW_ETH[network], + ], + }); + + console.log(`Verified ${contractName} contract address `, address); +}); diff --git a/evm/tasks/swell/constants.ts b/evm/tasks/swell/constants.ts new file mode 100644 index 0000000..5be4a6e --- /dev/null +++ b/evm/tasks/swell/constants.ts @@ -0,0 +1,4 @@ +export const SWELL_SW_ETH: { [chainId: string]: string } = { + "1": "0xf951E335afb289353dc249e82926178EaC7DEd78", + "5": "0x8bb383A752Ff3c1d510625C6F536E3332327068F", + }; \ No newline at end of file diff --git a/evm/tasks/swell/index.ts b/evm/tasks/swell/index.ts new file mode 100644 index 0000000..0679558 --- /dev/null +++ b/evm/tasks/swell/index.ts @@ -0,0 +1 @@ +import "./SwellStakeEth.deploy"; diff --git a/evm/tasks/synClub/SynClubStakeBnb.deploy.ts b/evm/tasks/synClub/SynClubStakeBnb.deploy.ts new file mode 100644 index 0000000..3ff0ec7 --- /dev/null +++ b/evm/tasks/synClub/SynClubStakeBnb.deploy.ts @@ -0,0 +1,104 @@ +import { HardhatRuntimeEnvironment, TaskArguments } from "hardhat/types"; +import { + ASSET_FORWARDER, + CONTRACT_NAME, + DEFAULT_ENV, + DEFAULT_OWNER, + DEFAULT_REFUND_ADDRESS, + DEPLOY_SYNCLUB_STAKE_BNB_ADAPTER, + DEXSPAN, + NATIVE, + VERIFY_SYNCLUB_STAKE_BNB_ADAPTER, + WNATIVE, +} from "../constants"; +import { task } from "hardhat/config"; +import { + IDeployment, + getDeployments, + recordAllDeployments, + saveDeployments, +} from "../utils"; +import { SYNCLUB_POOL, SYNCLUB_SN_BNB } from "./constants"; + +const contractName: string = CONTRACT_NAME.SynClubStakeBnb; + +task(DEPLOY_SYNCLUB_STAKE_BNB_ADAPTER) + .addFlag("verify", "pass true to verify the contract") + .setAction(async function ( + _taskArguments: TaskArguments, + _hre: HardhatRuntimeEnvironment + ) { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + + let defaultRefundAddress = process.env.DEFAULT_REFUND_ADDRESS; + if (!defaultRefundAddress) defaultRefundAddress = DEFAULT_REFUND_ADDRESS; + + let owner = process.env.OWNER; + if (!owner) owner = DEFAULT_OWNER; + + const network = await _hre.getChainId(); + + console.log(`Deploying ${contractName} Contract on chainId ${network}....`); + const factory = await _hre.ethers.getContractFactory(contractName); + const instance = await factory.deploy( + NATIVE, + WNATIVE[env][network], + owner, + ASSET_FORWARDER[env][network], + DEXSPAN[env][network], + SYNCLUB_SN_BNB[network], + SYNCLUB_POOL[network] + ); + await instance.deployed(); + + const deployment: IDeployment = await recordAllDeployments( + env, + network, + contractName, + instance.address + ); + + await saveDeployments(deployment); + + console.log(`${contractName} contract deployed at`, instance.address); + + if (_taskArguments.verify === true) { + await _hre.run(VERIFY_SYNCLUB_STAKE_BNB_ADAPTER); + } + }); + +task(VERIFY_SYNCLUB_STAKE_BNB_ADAPTER).setAction(async function ( + _taskArguments: TaskArguments, + _hre: HardhatRuntimeEnvironment +) { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + + let defaultRefundAddress = process.env.DEFAULT_REFUND_ADDRESS; + if (!defaultRefundAddress) defaultRefundAddress = DEFAULT_REFUND_ADDRESS; + + let owner = process.env.OWNER; + if (!owner) owner = DEFAULT_OWNER; + + const network = await _hre.getChainId(); + + const deployments: IDeployment = getDeployments(); + const address = deployments[env][network][contractName]; + + console.log(`Verifying ${contractName} Contract....`); + await _hre.run("verify:verify", { + address, + constructorArguments: [ + NATIVE, + WNATIVE[env][network], + owner, + ASSET_FORWARDER[env][network], + DEXSPAN[env][network], + SYNCLUB_SN_BNB[network], + SYNCLUB_POOL[network], + ], + }); + + console.log(`Verified ${contractName} contract address `, address); +}); diff --git a/evm/tasks/synClub/constants.ts b/evm/tasks/synClub/constants.ts new file mode 100644 index 0000000..a7c8401 --- /dev/null +++ b/evm/tasks/synClub/constants.ts @@ -0,0 +1,7 @@ +export const SYNCLUB_SN_BNB: { [chainId: string]: string } = { + "56": "0xB0b84D294e0C75A6abe60171b70edEb2EFd14A1B", + }; + + export const SYNCLUB_POOL: { [chainId: string]: string } = { + "56": "0x1adB950d8bB3dA4bE104211D5AB038628e477fE6", + }; \ No newline at end of file diff --git a/evm/tasks/synClub/index.ts b/evm/tasks/synClub/index.ts new file mode 100644 index 0000000..42dcd6f --- /dev/null +++ b/evm/tasks/synClub/index.ts @@ -0,0 +1 @@ +import "./SynClubStakeBnb.deploy"; diff --git a/evm/tasks/uniswapV3/UniswapV3MintPosition.deploy.ts b/evm/tasks/uniswapV3/UniswapV3MintPosition.deploy.ts new file mode 100644 index 0000000..e565d51 --- /dev/null +++ b/evm/tasks/uniswapV3/UniswapV3MintPosition.deploy.ts @@ -0,0 +1,104 @@ +import { HardhatRuntimeEnvironment, TaskArguments } from "hardhat/types"; +import { + ASSET_FORWARDER, + CONTRACT_NAME, + DEFAULT_ENV, + DEFAULT_OWNER, + DEFAULT_REFUND_ADDRESS, + DEPLOY_UNISWAP_V3_MINT_ADAPTER, + DEXSPAN, + NATIVE, + VERIFY_UNISWAP_V3_MINT_ADAPTER, + WNATIVE, +} from "../constants"; +import { task } from "hardhat/config"; +import { + IDeployment, + getDeployments, + recordAllDeployments, + saveDeployments, +} from "../utils"; +import { NON_FUNGIBLE_POSITION_MANAGER } from "./constants"; + +const contractName: string = CONTRACT_NAME.UniswapV3Mint; + +task(DEPLOY_UNISWAP_V3_MINT_ADAPTER) + .addFlag("verify", "pass true to verify the contract") + .setAction(async function ( + _taskArguments: TaskArguments, + _hre: HardhatRuntimeEnvironment + ) { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + + let defaultRefundAddress = process.env.DEFAULT_REFUND_ADDRESS; + if (!defaultRefundAddress) defaultRefundAddress = DEFAULT_REFUND_ADDRESS; + + let owner = process.env.OWNER; + if (!owner) owner = DEFAULT_OWNER; + + const network = await _hre.getChainId(); + + console.log(`Deploying ${contractName} Contract on chainId ${network}....`); + const factory = await _hre.ethers.getContractFactory(contractName); + const instance = await factory.deploy( + NATIVE, + WNATIVE[env][network], + owner, + ASSET_FORWARDER[env][network], + DEXSPAN[env][network], + defaultRefundAddress, + NON_FUNGIBLE_POSITION_MANAGER[network] + ); + await instance.deployed(); + + const deployment: IDeployment = await recordAllDeployments( + env, + network, + contractName, + instance.address + ); + + await saveDeployments(deployment); + + console.log(`${contractName} contract deployed at`, instance.address); + + if (_taskArguments.verify === true) { + await _hre.run(VERIFY_UNISWAP_V3_MINT_ADAPTER); + } + }); + +task(VERIFY_UNISWAP_V3_MINT_ADAPTER).setAction(async function ( + _taskArguments: TaskArguments, + _hre: HardhatRuntimeEnvironment +) { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + + let defaultRefundAddress = process.env.DEFAULT_REFUND_ADDRESS; + if (!defaultRefundAddress) defaultRefundAddress = DEFAULT_REFUND_ADDRESS; + + let owner = process.env.OWNER; + if (!owner) owner = DEFAULT_OWNER; + + const network = await _hre.getChainId(); + + const deployments: IDeployment = getDeployments(); + const address = deployments[env][network][contractName]; + + console.log(`Verifying ${contractName} Contract....`); + await _hre.run("verify:verify", { + address, + constructorArguments: [ + NATIVE, + WNATIVE[env][network], + owner, + ASSET_FORWARDER[env][network], + DEXSPAN[env][network], + defaultRefundAddress, + NON_FUNGIBLE_POSITION_MANAGER[network], + ], + }); + + console.log(`Verified ${contractName} contract address `, address); +}); diff --git a/evm/tasks/uniswapV3/constants.ts b/evm/tasks/uniswapV3/constants.ts new file mode 100644 index 0000000..b43931f --- /dev/null +++ b/evm/tasks/uniswapV3/constants.ts @@ -0,0 +1,4 @@ +export const NON_FUNGIBLE_POSITION_MANAGER: { [chainId: string]: string } = { + "1": "0xC36442b4a4522E871399CD717aBDD847Ab11FE88", + "5": "0xC36442b4a4522E871399CD717aBDD847Ab11FE88", +}; diff --git a/evm/tasks/uniswapV3/index.ts b/evm/tasks/uniswapV3/index.ts new file mode 100644 index 0000000..e9dbb98 --- /dev/null +++ b/evm/tasks/uniswapV3/index.ts @@ -0,0 +1 @@ +import "./UniswapV3MintPosition.deploy"; diff --git a/evm/tasks/utils.ts b/evm/tasks/utils.ts new file mode 100644 index 0000000..4a34224 --- /dev/null +++ b/evm/tasks/utils.ts @@ -0,0 +1,46 @@ +import fs from "fs"; + +export interface IDeployment { + [key: string]: { + [key: string]: { + [key: string]: string; + }; + }; +} + +export async function recordAllDeployments( + env: string, + network: string, + contractName: string, + address: string +) { + const deployment = JSON.parse( + fs.readFileSync("deployment/deployments.json", "utf-8") + ); + const deployments: IDeployment = deployment; + + if (!deployments[env]) { + deployments[env] = {}; + } + + if (!deployments[env][network]) { + deployments[env][network] = {}; + } + + deployments[env][network][contractName] = address; + + return deployments; +} + +export async function saveDeployments(deployment: IDeployment) { + fs.writeFileSync("deployment/deployments.json", JSON.stringify(deployment)); +} + +export function getDeployments() { + const deployment = JSON.parse( + fs.readFileSync("deployment/deployments.json", "utf-8") + ); + const deployments: IDeployment = deployment; + + return deployments; +} diff --git a/evm/test/AaveV3/AaveV3Borrow.specs.ts b/evm/test/AaveV3/AaveV3Borrow.specs.ts new file mode 100644 index 0000000..60d27d0 --- /dev/null +++ b/evm/test/AaveV3/AaveV3Borrow.specs.ts @@ -0,0 +1,241 @@ +import hardhat, { ethers, waffle } from "hardhat"; +import { expect } from "chai"; +import { RPC } from "../constants"; +import { + DEXSPAN, + DEFAULT_ENV, + DEFAULT_REFUND_ADDRESS, +} from "../../tasks/constants"; +import { TokenInterface__factory } from "../../typechain/factories/TokenInterface__factory"; +import { MockAssetForwarder__factory } from "../../typechain/factories/MockAssetForwarder__factory"; +import { BatchTransaction__factory } from "../../typechain/factories/BatchTransaction__factory"; +import { AaveV3Borrow__factory } from "../../typechain/factories/AaveV3Borrow__factory"; +import { IPoolV3__factory } from "../../typechain/factories/IPoolV3__factory"; +import { defaultAbiCoder } from "ethers/lib/utils"; +import { AaveV3Supply__factory } from "../../typechain/factories/AaveV3Supply__factory"; + +const CHAIN_ID = "80001"; +const AAVE_V3_POOL = "0xcC6114B983E4Ed2737E9BD3961c9924e6216c704"; +const AAVE_V3_WRAPPED_TOKEN_GATEWAY = + "0x8dA9412AbB78db20d0B496573D9066C474eA21B8"; +const AAVE_V3_REFERRAL_CODE = 0; +const NATIVE_TOKEN = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"; +const WMATIC = "0xaD3C5a67275dE4b5554CdD1d961e957f408eF75a"; +const A_WMATIC_ADDRESS = "0xaCA5e6a7117F54B34B476aB95Bf3034c304e7a81"; +const USDC_STABLE_DEBT_TOKEN = "0x0b03Ad2929926505EDE0958EF6454f291808c4c9"; +const USDC = "0x52D800ca262522580CeBAD275395ca6e7598C014"; + +const AAVE_DEBT_TOKEN_ABI = [ + "function approveDelegation(address delegatee, uint256 amount) external", + "function transfer(address _receiver, uint256 _value) public returns (bool success)", + "function transferFrom(address, address, uint256) public returns (bool)", + "function approve(address _spender, uint256 _value) public returns (bool success)", + "function allowance(address _owner, address _spender) public view returns (uint256 remaining)", + "function balanceOf(address _owner) public view returns (uint256 balance)", + "event Approval(address indexed _owner, address indexed _spender, uint256 _value)", +]; + +describe("AaveV3Borrow Adapter: ", async () => { + const [deployer] = waffle.provider.getWallets(); + + const setupTests = async () => { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + const MockAssetForwarder = await ethers.getContractFactory( + "MockAssetForwarder" + ); + const mockAssetForwarder = await MockAssetForwarder.deploy(); + + const AaveV3SupplyAdapter = await ethers.getContractFactory("AaveV3Supply"); + + const aaveV3SupplyAdapter = await AaveV3SupplyAdapter.deploy( + NATIVE_TOKEN, + WMATIC, + deployer.address, + mockAssetForwarder.address, + DEXSPAN[env][CHAIN_ID], + AAVE_V3_POOL, + AAVE_V3_WRAPPED_TOKEN_GATEWAY, + AAVE_V3_REFERRAL_CODE + ); + + const AaveV3BorrowAdapter = await ethers.getContractFactory("AaveV3Borrow"); + + const aaveV3BorrowAdapter = await AaveV3BorrowAdapter.deploy( + NATIVE_TOKEN, + WMATIC, + deployer.address, + mockAssetForwarder.address, + DEXSPAN[env][CHAIN_ID], + DEFAULT_REFUND_ADDRESS, + AAVE_V3_POOL, + AAVE_V3_WRAPPED_TOKEN_GATEWAY, + AAVE_V3_REFERRAL_CODE + ); + + const BatchTransaction = await ethers.getContractFactory( + "BatchTransaction" + ); + + const batchTransaction = await BatchTransaction.deploy( + NATIVE_TOKEN, + WMATIC, + mockAssetForwarder.address, + DEXSPAN[env][CHAIN_ID] + ); + + const wmatic = TokenInterface__factory.connect(WMATIC, deployer); + const aWmatic = TokenInterface__factory.connect(A_WMATIC_ADDRESS, deployer); + const usdc = TokenInterface__factory.connect(USDC, deployer); + const aaveV3Pool = IPoolV3__factory.connect(AAVE_V3_POOL, deployer); + const usdcStableDebtToken = await ethers.getContractAt( + AAVE_DEBT_TOKEN_ABI, + USDC_STABLE_DEBT_TOKEN, + deployer + ); + + const MockToken = await ethers.getContractFactory("MockToken"); + const mockToken = await MockToken.deploy(); + await mockToken.mint(deployer.address, ethers.utils.parseEther("10000")); + + return { + aaveV3SupplyAdapter: AaveV3Supply__factory.connect( + aaveV3SupplyAdapter.address, + deployer + ), + aaveV3BorrowAdapter: AaveV3Borrow__factory.connect( + aaveV3BorrowAdapter.address, + deployer + ), + batchTransaction: BatchTransaction__factory.connect( + batchTransaction.address, + deployer + ), + wmatic, + aWmatic, + usdc, + aaveV3Pool, + usdcStableDebtToken, + mockAssetForwarder: MockAssetForwarder__factory.connect( + mockAssetForwarder.address, + deployer + ), + mockToken: TokenInterface__factory.connect(mockToken.address, deployer), + }; + }; + + beforeEach(async function () { + await hardhat.network.provider.request({ + method: "hardhat_reset", + params: [ + { + forking: { + jsonRpcUrl: RPC[CHAIN_ID], + }, + }, + ], + }); + }); + + it("Can borrow funds on user's behalf", async () => { + const { + aWmatic, + usdc, + usdcStableDebtToken, + batchTransaction, + aaveV3BorrowAdapter, + aaveV3SupplyAdapter, + } = await setupTests(); + + const supplyAsset = NATIVE_TOKEN; + const supplyAmount = ethers.utils.parseEther("10"); + const supplyOnBehalfOf = deployer.address; + + const aaveV3SupplyData = defaultAbiCoder.encode( + ["address", "address", "uint256"], + [supplyAsset, supplyOnBehalfOf, supplyAmount] + ); + + const borrowAmount = "10000"; + const borrowRateMode = 1; // stable rate + const borrowAsset = usdc.address; + const borrowOnBehalfOf = deployer.address; + const borrowRecipient = deployer.address; + + const aaveV3BorrowData = defaultAbiCoder.encode( + ["uint256", "uint256", "address", "address", "address"], + [ + borrowAmount, + borrowRateMode, + borrowAsset, + borrowOnBehalfOf, + borrowRecipient, + ] + ); + + const tokens = [supplyAsset]; + const amounts = [supplyAmount]; + const targets = [aaveV3SupplyAdapter.address, aaveV3BorrowAdapter.address]; + const data = [aaveV3SupplyData, aaveV3BorrowData]; + const value = [0, 0]; + const callType = [2, 2]; + + await usdcStableDebtToken.approveDelegation( + batchTransaction.address, + borrowAmount + ); + + const userBalBefore = await aWmatic.balanceOf(deployer.address); + const usdcBalBefore = await usdc.balanceOf(deployer.address); + await batchTransaction.executeBatchCallsSameChain( + tokens, + amounts, + targets, + value, + callType, + data, + { value: supplyAmount } + ); + + const userBalAfter = await aWmatic.balanceOf(deployer.address); + const usdcBalAfter = await usdc.balanceOf(deployer.address); + + expect(userBalBefore).eq(0); + expect(userBalAfter).gt(0); + expect(usdcBalBefore).eq(0); + expect(usdcBalAfter).eq(borrowAmount); + }); + + it("Cannot borrow funds cross-chain when handleMessage is called directly on adapter", async () => { + const { usdc, mockAssetForwarder, aaveV3BorrowAdapter } = + await setupTests(); + + const amount = ethers.utils.parseEther("1"); + const borrowAmount = "10000"; + const borrowRateMode = 1; // stable rate + const borrowAsset = usdc.address; + const borrowOnBehalfOf = deployer.address; + const borrowRecipient = deployer.address; + + const aaveV3BorrowData = defaultAbiCoder.encode( + ["uint256", "uint256", "address", "address", "address"], + [ + borrowAmount, + borrowRateMode, + borrowAsset, + borrowOnBehalfOf, + borrowRecipient, + ] + ); + + expect( + await mockAssetForwarder.handleMessage( + NATIVE_TOKEN, + amount, + aaveV3BorrowData, + aaveV3BorrowAdapter.address, + { value: amount } + ) + ).to.emit("UnsupportedOperation"); + }); +}); diff --git a/evm/test/AaveV3/AaveV3Supply.specs.ts b/evm/test/AaveV3/AaveV3Supply.specs.ts new file mode 100644 index 0000000..aca3694 --- /dev/null +++ b/evm/test/AaveV3/AaveV3Supply.specs.ts @@ -0,0 +1,471 @@ +import hardhat, { ethers, waffle } from "hardhat"; +import { expect } from "chai"; +import { RPC } from "../constants"; +import { DEXSPAN, DEFAULT_ENV } from "../../tasks/constants"; +import { TokenInterface__factory } from "../../typechain/factories/TokenInterface__factory"; +import { MockAssetForwarder__factory } from "../../typechain/factories/MockAssetForwarder__factory"; +import { BatchTransaction__factory } from "../../typechain/factories/BatchTransaction__factory"; +import { AaveV3Supply__factory } from "../../typechain/factories/AaveV3Supply__factory"; +import { defaultAbiCoder } from "ethers/lib/utils"; +import { zeroAddress } from "ethereumjs-util"; + +const CHAIN_ID = "80001"; +const AAVE_V3_POOL = "0xcC6114B983E4Ed2737E9BD3961c9924e6216c704"; +const AAVE_V3_WRAPPED_TOKEN_GATEWAY = + "0x8dA9412AbB78db20d0B496573D9066C474eA21B8"; +const AAVE_V3_REFERRAL_CODE = 0; +const NATIVE_TOKEN = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"; +const WMATIC = "0xaD3C5a67275dE4b5554CdD1d961e957f408eF75a"; +const A_WMATIC_ADDRESS = "0xaCA5e6a7117F54B34B476aB95Bf3034c304e7a81"; + +describe("AaveV3Supply Adapter: ", async () => { + const [deployer, alice] = waffle.provider.getWallets(); + + const setupTests = async () => { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + const MockAssetForwarder = await ethers.getContractFactory( + "MockAssetForwarder" + ); + const mockAssetForwarder = await MockAssetForwarder.deploy(); + + const AaveV3SupplyAdapter = await ethers.getContractFactory("AaveV3Supply"); + + const aaveV3SupplyAdapter = await AaveV3SupplyAdapter.deploy( + NATIVE_TOKEN, + WMATIC, + deployer.address, + mockAssetForwarder.address, + DEXSPAN[env][CHAIN_ID], + AAVE_V3_POOL, + AAVE_V3_WRAPPED_TOKEN_GATEWAY, + AAVE_V3_REFERRAL_CODE + ); + + const BatchTransaction = await ethers.getContractFactory( + "BatchTransaction" + ); + + const batchTransaction = await BatchTransaction.deploy( + NATIVE_TOKEN, + WMATIC, + mockAssetForwarder.address, + DEXSPAN[env][CHAIN_ID] + ); + + const wmatic = TokenInterface__factory.connect(WMATIC, deployer); + const aWmatic = TokenInterface__factory.connect(A_WMATIC_ADDRESS, deployer); + + const MockToken = await ethers.getContractFactory("MockToken"); + const mockToken = await MockToken.deploy(); + await mockToken.mint(deployer.address, ethers.utils.parseEther("10000")); + + return { + aaveV3SupplyAdapter: AaveV3Supply__factory.connect( + aaveV3SupplyAdapter.address, + deployer + ), + batchTransaction: BatchTransaction__factory.connect( + batchTransaction.address, + deployer + ), + wmatic, + aWmatic, + mockAssetForwarder: MockAssetForwarder__factory.connect( + mockAssetForwarder.address, + deployer + ), + mockToken: TokenInterface__factory.connect(mockToken.address, deployer), + }; + }; + + beforeEach(async function () { + await hardhat.network.provider.request({ + method: "hardhat_reset", + params: [ + { + forking: { + jsonRpcUrl: RPC[CHAIN_ID], + }, + }, + ], + }); + }); + + it("Can supply native tokens on AaveV3", async () => { + const { aaveV3SupplyAdapter, aWmatic } = await setupTests(); + + const amount = ethers.utils.parseEther("1"); + + const data = defaultAbiCoder.encode( + ["address", "address", "uint256"], + [NATIVE_TOKEN, deployer.address, amount] + ); + + const userBalBefore = await aWmatic.balanceOf(deployer.address); + await aaveV3SupplyAdapter.execute(zeroAddress(), zeroAddress(), data, { + gasLimit: 10000000, + value: amount, + }); + + const userBalAfter = await aWmatic.balanceOf(deployer.address); + + expect(userBalBefore).eq(0); + expect(userBalAfter).gt(0); + }); + + it("Can supply non-native tokens on AaveV3", async () => { + const { aaveV3SupplyAdapter, wmatic, aWmatic } = await setupTests(); + + const amount = ethers.utils.parseEther("1"); + await wmatic.deposit({ value: amount }); + expect(await wmatic.balanceOf(deployer.address)).eq(amount); + + await wmatic.approve(aaveV3SupplyAdapter.address, amount); + const data = defaultAbiCoder.encode( + ["address", "address", "uint256"], + [wmatic.address, deployer.address, amount] + ); + + const userBalBefore = await aWmatic.balanceOf(deployer.address); + await aaveV3SupplyAdapter.execute(zeroAddress(), zeroAddress(), data, { + gasLimit: 10000000, + }); + const userBalAfter = await aWmatic.balanceOf(deployer.address); + + expect(userBalBefore).eq(0); + expect(userBalAfter).gt(0); + }); + + it("Cannot supply unsupported tokens on AaveV3", async () => { + const { aaveV3SupplyAdapter, mockToken } = await setupTests(); + + const amount = ethers.utils.parseEther("1"); + await mockToken.approve(aaveV3SupplyAdapter.address, amount); + + const data = defaultAbiCoder.encode( + ["address", "address", "uint256"], + [mockToken.address, deployer.address, amount] + ); + + await expect( + aaveV3SupplyAdapter.execute(zeroAddress(), zeroAddress(), data, { + gasLimit: 10000000, + }) + ).to.be.reverted; + }); + + it("Can supply native tokens cross-chain on AaveV3 when handleMessage is called directly on adapter", async () => { + const { aaveV3SupplyAdapter, aWmatic, mockAssetForwarder } = + await setupTests(); + + const amount = ethers.utils.parseEther("1"); + + const instruction = defaultAbiCoder.encode(["address"], [deployer.address]); + + const userBalBefore = await aWmatic.balanceOf(deployer.address); + await mockAssetForwarder.handleMessage( + NATIVE_TOKEN, + amount, + instruction, + aaveV3SupplyAdapter.address, + { + gasLimit: 10000000, + value: amount, + } + ); + + const userBalAfter = await aWmatic.balanceOf(deployer.address); + + expect(userBalBefore).eq(0); + expect(userBalAfter).gt(0); + }); + + it("Can supply non-native tokens cross-chain on AaveV3 when handleMessage is called directly on adapter", async () => { + const { aaveV3SupplyAdapter, wmatic, aWmatic, mockAssetForwarder } = + await setupTests(); + + const amount = ethers.utils.parseEther("1"); + await wmatic.deposit({ value: amount }); + expect(await wmatic.balanceOf(deployer.address)).eq(amount); + + await wmatic.approve(mockAssetForwarder.address, amount); + + const instruction = defaultAbiCoder.encode(["address"], [deployer.address]); + + const userBalBefore = await aWmatic.balanceOf(deployer.address); + await mockAssetForwarder.handleMessage( + WMATIC, + amount, + instruction, + aaveV3SupplyAdapter.address + ); + + const userBalAfter = await aWmatic.balanceOf(deployer.address); + + expect(userBalBefore).eq(0); + expect(userBalAfter).gt(0); + }); + + it("Can get a refund if unsupported token is being supplied cross-chain on AaveV3 when handleMessage is called directly on adapter", async () => { + const { aaveV3SupplyAdapter, mockToken, mockAssetForwarder } = + await setupTests(); + + const amount = ethers.utils.parseEther("1"); + await mockToken.approve(mockAssetForwarder.address, amount); + + const instruction = defaultAbiCoder.encode(["address"], [alice.address]); + + const callerBalBefore = await mockToken.balanceOf(deployer.address); + const recipientBalBefore = await mockToken.balanceOf(alice.address); + + expect( + await mockAssetForwarder.handleMessage( + mockToken.address, + amount, + instruction, + aaveV3SupplyAdapter.address + ) + ).to.emit("OperationFailedRefundEvent"); + + const callerBalAfter = await mockToken.balanceOf(deployer.address); + const recipientBalAfter = await mockToken.balanceOf(alice.address); + + expect(callerBalAfter).lt(callerBalBefore); + expect(recipientBalAfter).gt(recipientBalBefore); + }); + + it("Can supply native tokens on AaveV3 using BatchTransaction flow", async () => { + const { aaveV3SupplyAdapter, aWmatic, batchTransaction } = + await setupTests(); + + const amount = ethers.utils.parseEther("1"); + + const aaveV3SupplyData = defaultAbiCoder.encode( + ["address", "address", "uint256"], + [NATIVE_TOKEN, alice.address, amount] + ); + + const tokens = [NATIVE_TOKEN]; + const amounts = [amount]; + const targets = [aaveV3SupplyAdapter.address]; + const data = [aaveV3SupplyData]; + const value = [0]; + const callType = [2]; + + const userBalBefore = await aWmatic.balanceOf(alice.address); + await batchTransaction.executeBatchCallsSameChain( + tokens, + amounts, + targets, + value, + callType, + data, + { value: amount } + ); + + const userBalAfter = await aWmatic.balanceOf(alice.address); + + expect(userBalBefore).eq(0); + expect(userBalAfter).gt(0); + }); + + it("Can supply non-native tokens on AaveV3 using BatchTransaction flow", async () => { + const { aaveV3SupplyAdapter, wmatic, aWmatic, batchTransaction } = + await setupTests(); + + const amount = ethers.utils.parseEther("1"); + await wmatic.deposit({ value: amount }); + expect(await wmatic.balanceOf(deployer.address)).eq(amount); + + await wmatic.approve(batchTransaction.address, amount); + + const aaveV3SupplyData = defaultAbiCoder.encode( + ["address", "address", "uint256"], + [WMATIC, alice.address, amount] + ); + + const tokens = [WMATIC]; + const amounts = [amount]; + const targets = [aaveV3SupplyAdapter.address]; + const data = [aaveV3SupplyData]; + const value = [0]; + const callType = [2]; + + const userBalBefore = await aWmatic.balanceOf(alice.address); + await batchTransaction.executeBatchCallsSameChain( + tokens, + amounts, + targets, + value, + callType, + data + ); + + const userBalAfter = await aWmatic.balanceOf(alice.address); + + expect(userBalBefore).eq(0); + expect(userBalAfter).gt(0); + }); + + it("Cannot supply unsupported tokens on AaveV3 using BatchTransaction flow", async () => { + const { aaveV3SupplyAdapter, mockToken, batchTransaction } = + await setupTests(); + + const amount = ethers.utils.parseEther("1"); + await mockToken.approve(batchTransaction.address, amount); + + const aaveV3SupplyData = defaultAbiCoder.encode( + ["address", "address", "uint256"], + [mockToken.address, alice.address, amount] + ); + + const tokens = [mockToken.address]; + const amounts = [amount]; + const targets = [aaveV3SupplyAdapter.address]; + const data = [aaveV3SupplyData]; + const value = [0]; + const callType = [2]; + + await expect( + batchTransaction.executeBatchCallsSameChain( + tokens, + amounts, + targets, + value, + callType, + data + ) + ).to.be.reverted; + }); + + it("Can supply native tokens cross-chain on AaveV3 using BatchTransaction flow", async () => { + const { + aaveV3SupplyAdapter, + mockAssetForwarder, + aWmatic, + batchTransaction, + } = await setupTests(); + + const amount = ethers.utils.parseEther("1"); + + const aaveV3SupplyData = defaultAbiCoder.encode( + ["address", "address", "uint256"], + [NATIVE_TOKEN, alice.address, amount] + ); + + const targets = [aaveV3SupplyAdapter.address]; + const data = [aaveV3SupplyData]; + const value = [0]; + const callType = [2]; + + const assetForwarderData = defaultAbiCoder.encode( + ["address", "address[]", "uint256[]", "uint256[]", "bytes[]"], + [deployer.address, targets, value, callType, data] + ); + + const userBalBefore = await aWmatic.balanceOf(alice.address); + await mockAssetForwarder.handleMessage( + NATIVE_TOKEN, + amount, + assetForwarderData, + batchTransaction.address, + { value: amount, gasLimit: 10000000 } + ); + const userBalAfter = await aWmatic.balanceOf(alice.address); + + expect(userBalBefore).eq(0); + expect(userBalAfter).gt(0); + }); + + it("Can supply non-native tokens cross-chain on AaveV3 using BatchTransaction flow", async () => { + const { + aaveV3SupplyAdapter, + mockAssetForwarder, + wmatic, + aWmatic, + batchTransaction, + } = await setupTests(); + + const amount = ethers.utils.parseEther("1"); + await wmatic.deposit({ value: amount }); + expect(await wmatic.balanceOf(deployer.address)).eq(amount); + + await wmatic.approve(mockAssetForwarder.address, amount); + + const aaveV3SupplyData = defaultAbiCoder.encode( + ["address", "address", "uint256"], + [wmatic.address, alice.address, amount] + ); + + const targets = [aaveV3SupplyAdapter.address]; + const data = [aaveV3SupplyData]; + const value = [0]; + const callType = [2]; + + const assetForwarderData = defaultAbiCoder.encode( + ["address", "address[]", "uint256[]", "uint256[]", "bytes[]"], + [deployer.address, targets, value, callType, data] + ); + + const userBalBefore = await aWmatic.balanceOf(alice.address); + await mockAssetForwarder.handleMessage( + wmatic.address, + amount, + assetForwarderData, + batchTransaction.address, + { value: amount, gasLimit: 10000000 } + ); + const userBalAfter = await aWmatic.balanceOf(alice.address); + + expect(userBalBefore).eq(0); + expect(userBalAfter).gt(0); + }); + + it("Can get a refund if supply unsupported tokens cross-chain on AaveV3 using BatchTransaction flow", async () => { + const { + aaveV3SupplyAdapter, + mockAssetForwarder, + mockToken, + aWmatic, + batchTransaction, + } = await setupTests(); + + const amount = ethers.utils.parseEther("1"); + await mockToken.approve(mockAssetForwarder.address, amount); + + const aaveV3SupplyData = defaultAbiCoder.encode( + ["address", "address", "uint256"], + [mockToken.address, alice.address, amount] + ); + + const targets = [aaveV3SupplyAdapter.address]; + const data = [aaveV3SupplyData]; + const value = [0]; + const callType = [2]; + + const assetForwarderData = defaultAbiCoder.encode( + ["address", "address[]", "uint256[]", "uint256[]", "bytes[]"], + [deployer.address, targets, value, callType, data] + ); + + const recipientBalBefore = await aWmatic.balanceOf(alice.address); + const userMockTokenBalBefore = await mockToken.balanceOf(deployer.address); + + expect( + await mockAssetForwarder.handleMessage( + mockToken.address, + amount, + assetForwarderData, + batchTransaction.address, + { value: amount, gasLimit: 10000000 } + ) + ).to.emit("OperationFailedRefundEvent"); + + const recipientBalAfter = await aWmatic.balanceOf(alice.address); + const userMockTokenBalAfter = await mockToken.balanceOf(deployer.address); + + expect(recipientBalAfter).eq(recipientBalBefore); + expect(userMockTokenBalAfter).eq(userMockTokenBalBefore); + }); +}); diff --git a/evm/test/Ankr/AnkrStakeAvax.specs.ts b/evm/test/Ankr/AnkrStakeAvax.specs.ts new file mode 100644 index 0000000..cbeb00e --- /dev/null +++ b/evm/test/Ankr/AnkrStakeAvax.specs.ts @@ -0,0 +1,236 @@ +import hardhat, { ethers, waffle } from "hardhat"; +import { expect } from "chai"; +import { RPC } from "../constants"; +import { + DEXSPAN, + DEFAULT_ENV, + NATIVE, + WNATIVE, + DEFAULT_REFUND_ADDRESS, +} from "../../tasks/constants"; +import { AnkrStakeAvax__factory } from "../../typechain/factories/AnkrStakeAvax__factory"; +import { TokenInterface__factory } from "../../typechain/factories/TokenInterface__factory"; +import { MockAssetForwarder__factory } from "../../typechain/factories/MockAssetForwarder__factory"; +import { BatchTransaction__factory } from "../../typechain/factories/BatchTransaction__factory"; +import { BigNumber, Contract, Wallet } from "ethers"; +import { getPathfinderData } from "../utils"; +import { defaultAbiCoder } from "ethers/lib/utils"; +import { DexSpanAdapter__factory } from "../../typechain/factories/DexSpanAdapter__factory"; + +const CHAIN_ID = "43114"; +const ANKR_TOKEN = "0xc3344870d52688874b06d844E0C36cc39FC727F6"; +const ANKR_POOL = "0x7BAa1E3bFe49db8361680785182B80BB420A836D"; +const NATIVE_TOKEN = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"; +const USDT = "0x9702230a8ea53601f5cd2dc00fdbc13d4df4a8c7"; + +describe("AnkrStakeAvax Adapter: ", async () => { + const [deployer] = waffle.provider.getWallets(); + + const setupTests = async () => { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + const MockAssetForwarder = await ethers.getContractFactory( + "MockAssetForwarder" + ); + const mockAssetForwarder = await MockAssetForwarder.deploy(); + + const BatchTransaction = await ethers.getContractFactory( + "BatchTransaction" + ); + + const batchTransaction = await BatchTransaction.deploy( + NATIVE, + WNATIVE[env][CHAIN_ID], + mockAssetForwarder.address, + DEXSPAN[env][CHAIN_ID] + ); + + const DexSpanAdapter = await ethers.getContractFactory("DexSpanAdapter"); + const dexSpanAdapter = await DexSpanAdapter.deploy( + NATIVE, + WNATIVE[env][CHAIN_ID], + deployer.address, + mockAssetForwarder.address, + DEXSPAN[env][CHAIN_ID], + DEFAULT_REFUND_ADDRESS + ); + + const AnkrStakeAvax = await ethers.getContractFactory("AnkrStakeAvax"); + const ankrStakeAvaxAdapter = await AnkrStakeAvax.deploy( + NATIVE, + WNATIVE[env][CHAIN_ID], + deployer.address, + mockAssetForwarder.address, + DEXSPAN[env][CHAIN_ID], + ANKR_TOKEN, + ANKR_POOL + ); + + return { + batchTransaction: BatchTransaction__factory.connect( + batchTransaction.address, + deployer + ), + ankrStakeAvaxAdapter: AnkrStakeAvax__factory.connect( + ankrStakeAvaxAdapter.address, + deployer + ), + dexSpanAdapter: DexSpanAdapter__factory.connect( + dexSpanAdapter.address, + deployer + ), + mockAssetForwarder: MockAssetForwarder__factory.connect( + mockAssetForwarder.address, + deployer + ), + usdt: TokenInterface__factory.connect(USDT, deployer), + ankrEth: TokenInterface__factory.connect(ANKR_TOKEN, deployer), + }; + }; + + beforeEach(async function () { + await hardhat.network.provider.request({ + method: "hardhat_reset", + params: [ + { + forking: { + jsonRpcUrl: RPC[CHAIN_ID], + }, + }, + ], + }); + }); + + const toBytes32 = (bn: BigNumber) => { + return ethers.utils.hexlify(ethers.utils.zeroPad(bn.toHexString(), 32)); + }; + + // This works for token when it has balance mapping at slot 0. + const setUserTokenBalance = async ( + contract: Contract, + user: Wallet, + balance: BigNumber + ) => { + const index = ethers.utils.solidityKeccak256( + ["uint256", "uint256"], + [user.address, 0] // key, slot + ); + + await hardhat.network.provider.request({ + method: "hardhat_setStorageAt", + params: [contract.address, index, toBytes32(balance).toString()], + }); + + await hardhat.network.provider.request({ + method: "evm_mine", + params: [], + }); + }; + + it("Can stake on ankr on same chain", async () => { + const { batchTransaction, ankrStakeAvaxAdapter, ankrEth } = + await setupTests(); + + const amount = ethers.utils.parseEther("1"); + + const ankrData = defaultAbiCoder.encode( + ["address", "uint256"], + [deployer.address, amount] + ); + + const tokens = [NATIVE_TOKEN]; + const amounts = [amount]; + const targets = [ankrStakeAvaxAdapter.address]; + const data = [ankrData]; + const value = [0]; + const callType = [2]; + + const balBefore = await ethers.provider.getBalance(deployer.address); + const ankrEthBalBefore = await ankrEth.balanceOf(deployer.address); + + await batchTransaction.executeBatchCallsSameChain( + tokens, + amounts, + targets, + value, + callType, + data, + { value: amount } + ); + + const balAfter = await ethers.provider.getBalance(deployer.address); + const ankrEthBalAfter = await ankrEth.balanceOf(deployer.address); + + expect(balBefore).gt(balAfter); + expect(ankrEthBalAfter).gt(ankrEthBalBefore); + }); + + it("Can stake AVAX on Ankr on dest chain when instruction is received from BatchTransaction contract", async () => { + const { + batchTransaction, + ankrStakeAvaxAdapter, + ankrEth, + mockAssetForwarder, + } = await setupTests(); + + const amount = ethers.utils.parseEther("1"); + + const targets = [ankrStakeAvaxAdapter.address]; + const data = [ + defaultAbiCoder.encode( + ["address", "uint256"], + [deployer.address, amount] + ), + ]; + const value = [0]; + const callType = [2]; + + const assetForwarderData = defaultAbiCoder.encode( + ["address", "address[]", "uint256[]", "uint256[]", "bytes[]"], + [deployer.address, targets, value, callType, data] + ); + + const balBefore = await ethers.provider.getBalance(deployer.address); + const ankrEthBalBefore = await ankrEth.balanceOf(deployer.address); + + await mockAssetForwarder.handleMessage( + NATIVE_TOKEN, + amount, + assetForwarderData, + batchTransaction.address, + { value: amount } + ); + + const balAfter = await ethers.provider.getBalance(deployer.address); + const ankrEthBalAfter = await ankrEth.balanceOf(deployer.address); + + expect(balAfter).lt(balBefore); + expect(ankrEthBalAfter).gt(ankrEthBalBefore); + }); + + it("Can stake AVAX on Ankr on dest chain when instruction is received directly on AnkrStakeAvax adapter", async () => { + const { ankrStakeAvaxAdapter, ankrEth, mockAssetForwarder } = + await setupTests(); + + const amount = ethers.utils.parseEther("1"); + + const data = defaultAbiCoder.encode(["address"], [deployer.address]); + + const balBefore = await ethers.provider.getBalance(deployer.address); + const ankrEthBalBefore = await ankrEth.balanceOf(deployer.address); + + await mockAssetForwarder.handleMessage( + NATIVE_TOKEN, + amount, + data, + ankrStakeAvaxAdapter.address, + { value: amount } + ); + + const balAfter = await ethers.provider.getBalance(deployer.address); + const ankrEthBalAfter = await ankrEth.balanceOf(deployer.address); + + expect(balAfter).lt(balBefore); + expect(ankrEthBalAfter).gt(ankrEthBalBefore); + }); +}); diff --git a/evm/test/Ankr/AnkrStakeBsc.specs.ts b/evm/test/Ankr/AnkrStakeBsc.specs.ts new file mode 100644 index 0000000..ade70c5 --- /dev/null +++ b/evm/test/Ankr/AnkrStakeBsc.specs.ts @@ -0,0 +1,236 @@ +import hardhat, { ethers, waffle } from "hardhat"; +import { expect } from "chai"; +import { RPC } from "../constants"; +import { + DEXSPAN, + DEFAULT_ENV, + NATIVE, + WNATIVE, + DEFAULT_REFUND_ADDRESS, +} from "../../tasks/constants"; +import { AnkrStakeBsc__factory } from "../../typechain/factories/AnkrStakeBsc__factory"; +import { TokenInterface__factory } from "../../typechain/factories/TokenInterface__factory"; +import { MockAssetForwarder__factory } from "../../typechain/factories/MockAssetForwarder__factory"; +import { BatchTransaction__factory } from "../../typechain/factories/BatchTransaction__factory"; +import { BigNumber, Contract, Wallet } from "ethers"; +import { getPathfinderData } from "../utils"; +import { defaultAbiCoder } from "ethers/lib/utils"; +import { DexSpanAdapter__factory } from "../../typechain/factories/DexSpanAdapter__factory"; + +const CHAIN_ID = "56"; +const ANKR_TOKEN = "0x52F24a5e03aee338Da5fd9Df68D2b6FAe1178827"; +const ANKR_POOL = "0x9e347Af362059bf2E55839002c699F7A5BaFE86E"; +const NATIVE_TOKEN = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"; +const USDT = "0x55d398326f99059ff775485246999027b3197955"; + +describe("AnkrStakeBsc Adapter: ", async () => { + const [deployer] = waffle.provider.getWallets(); + + const setupTests = async () => { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + const MockAssetForwarder = await ethers.getContractFactory( + "MockAssetForwarder" + ); + const mockAssetForwarder = await MockAssetForwarder.deploy(); + + const BatchTransaction = await ethers.getContractFactory( + "BatchTransaction" + ); + + const batchTransaction = await BatchTransaction.deploy( + NATIVE, + WNATIVE[env][CHAIN_ID], + mockAssetForwarder.address, + DEXSPAN[env][CHAIN_ID] + ); + + const DexSpanAdapter = await ethers.getContractFactory("DexSpanAdapter"); + const dexSpanAdapter = await DexSpanAdapter.deploy( + NATIVE, + WNATIVE[env][CHAIN_ID], + deployer.address, + mockAssetForwarder.address, + DEXSPAN[env][CHAIN_ID], + DEFAULT_REFUND_ADDRESS + ); + + const AnkrStakeBsc = await ethers.getContractFactory("AnkrStakeBsc"); + const ankrStakeBscAdapter = await AnkrStakeBsc.deploy( + NATIVE, + WNATIVE[env][CHAIN_ID], + deployer.address, + mockAssetForwarder.address, + DEXSPAN[env][CHAIN_ID], + ANKR_TOKEN, + ANKR_POOL + ); + + return { + batchTransaction: BatchTransaction__factory.connect( + batchTransaction.address, + deployer + ), + ankrStakeBscAdapter: AnkrStakeBsc__factory.connect( + ankrStakeBscAdapter.address, + deployer + ), + dexSpanAdapter: DexSpanAdapter__factory.connect( + dexSpanAdapter.address, + deployer + ), + mockAssetForwarder: MockAssetForwarder__factory.connect( + mockAssetForwarder.address, + deployer + ), + usdt: TokenInterface__factory.connect(USDT, deployer), + ankrEth: TokenInterface__factory.connect(ANKR_TOKEN, deployer), + }; + }; + + beforeEach(async function () { + await hardhat.network.provider.request({ + method: "hardhat_reset", + params: [ + { + forking: { + jsonRpcUrl: RPC[CHAIN_ID], + }, + }, + ], + }); + }); + + const toBytes32 = (bn: BigNumber) => { + return ethers.utils.hexlify(ethers.utils.zeroPad(bn.toHexString(), 32)); + }; + + // This works for token when it has balance mapping at slot 0. + const setUserTokenBalance = async ( + contract: Contract, + user: Wallet, + balance: BigNumber + ) => { + const index = ethers.utils.solidityKeccak256( + ["uint256", "uint256"], + [user.address, 0] // key, slot + ); + + await hardhat.network.provider.request({ + method: "hardhat_setStorageAt", + params: [contract.address, index, toBytes32(balance).toString()], + }); + + await hardhat.network.provider.request({ + method: "evm_mine", + params: [], + }); + }; + + it("Can stake on ankr on same chain", async () => { + const { batchTransaction, ankrStakeBscAdapter, ankrEth } = + await setupTests(); + + const amount = ethers.utils.parseEther("1"); + + const ankrData = defaultAbiCoder.encode( + ["address", "uint256"], + [deployer.address, amount] + ); + + const tokens = [NATIVE_TOKEN]; + const amounts = [amount]; + const targets = [ankrStakeBscAdapter.address]; + const data = [ankrData]; + const value = [0]; + const callType = [2]; + + const balBefore = await ethers.provider.getBalance(deployer.address); + const ankrEthBalBefore = await ankrEth.balanceOf(deployer.address); + + await batchTransaction.executeBatchCallsSameChain( + tokens, + amounts, + targets, + value, + callType, + data, + { value: amount } + ); + + const balAfter = await ethers.provider.getBalance(deployer.address); + const ankrEthBalAfter = await ankrEth.balanceOf(deployer.address); + + expect(balBefore).gt(balAfter); + expect(ankrEthBalAfter).gt(ankrEthBalBefore); + }); + + it("Can stake BSC on Ankr on dest chain when instruction is received from BatchTransaction contract", async () => { + const { + batchTransaction, + ankrStakeBscAdapter, + ankrEth, + mockAssetForwarder, + } = await setupTests(); + + const amount = "100000000000000000"; + + const targets = [ankrStakeBscAdapter.address]; + const data = [ + defaultAbiCoder.encode( + ["address", "uint256"], + [deployer.address, amount] + ), + ]; + const value = [0]; + const callType = [2]; + + const assetForwarderData = defaultAbiCoder.encode( + ["address", "address[]", "uint256[]", "uint256[]", "bytes[]"], + [deployer.address, targets, value, callType, data] + ); + + const balBefore = await ethers.provider.getBalance(deployer.address); + const ankrEthBalBefore = await ankrEth.balanceOf(deployer.address); + + await mockAssetForwarder.handleMessage( + NATIVE_TOKEN, + amount, + assetForwarderData, + batchTransaction.address, + { value: amount } + ); + + const balAfter = await ethers.provider.getBalance(deployer.address); + const ankrEthBalAfter = await ankrEth.balanceOf(deployer.address); + + expect(balAfter).lt(balBefore); + expect(ankrEthBalAfter).gt(ankrEthBalBefore); + }); + + it("Can stake BSC on Ankr on dest chain when instruction is received directly on AnkrStakeBsc adapter", async () => { + const { ankrStakeBscAdapter, ankrEth, mockAssetForwarder } = + await setupTests(); + + const amount = "100000000000000000"; + + const data = defaultAbiCoder.encode(["address"], [deployer.address]); + + const balBefore = await ethers.provider.getBalance(deployer.address); + const ankrEthBalBefore = await ankrEth.balanceOf(deployer.address); + + await mockAssetForwarder.handleMessage( + NATIVE_TOKEN, + amount, + data, + ankrStakeBscAdapter.address, + { value: amount } + ); + + const balAfter = await ethers.provider.getBalance(deployer.address); + const ankrEthBalAfter = await ankrEth.balanceOf(deployer.address); + + expect(balAfter).lt(balBefore); + expect(ankrEthBalAfter).gt(ankrEthBalBefore); + }); +}); diff --git a/evm/test/Ankr/AnkrStakeEth.specs.ts b/evm/test/Ankr/AnkrStakeEth.specs.ts new file mode 100644 index 0000000..7936e4d --- /dev/null +++ b/evm/test/Ankr/AnkrStakeEth.specs.ts @@ -0,0 +1,236 @@ +import hardhat, { ethers, waffle } from "hardhat"; +import { expect } from "chai"; +import { RPC } from "../constants"; +import { + DEXSPAN, + DEFAULT_ENV, + NATIVE, + WNATIVE, + DEFAULT_REFUND_ADDRESS, +} from "../../tasks/constants"; +import { AnkrStakeEth__factory } from "../../typechain/factories/AnkrStakeEth__factory"; +import { TokenInterface__factory } from "../../typechain/factories/TokenInterface__factory"; +import { MockAssetForwarder__factory } from "../../typechain/factories/MockAssetForwarder__factory"; +import { BatchTransaction__factory } from "../../typechain/factories/BatchTransaction__factory"; +import { BigNumber, Contract, Wallet } from "ethers"; +import { getPathfinderData } from "../utils"; +import { defaultAbiCoder } from "ethers/lib/utils"; +import { DexSpanAdapter__factory } from "../../typechain/factories/DexSpanAdapter__factory"; + +const CHAIN_ID = "1"; +const ANKR_TOKEN = "0xE95A203B1a91a908F9B9CE46459d101078c2c3cb"; +const ANKR_POOL = "0x84db6eE82b7Cf3b47E8F19270abdE5718B936670"; +const NATIVE_TOKEN = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"; +const USDT = "0xdac17f958d2ee523a2206206994597c13d831ec7"; + +describe("AnkrStakeEth Adapter: ", async () => { + const [deployer] = waffle.provider.getWallets(); + + const setupTests = async () => { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + const MockAssetForwarder = await ethers.getContractFactory( + "MockAssetForwarder" + ); + const mockAssetForwarder = await MockAssetForwarder.deploy(); + + const BatchTransaction = await ethers.getContractFactory( + "BatchTransaction" + ); + + const batchTransaction = await BatchTransaction.deploy( + NATIVE, + WNATIVE[env][CHAIN_ID], + mockAssetForwarder.address, + DEXSPAN[env][CHAIN_ID] + ); + + const DexSpanAdapter = await ethers.getContractFactory("DexSpanAdapter"); + const dexSpanAdapter = await DexSpanAdapter.deploy( + NATIVE, + WNATIVE[env][CHAIN_ID], + deployer.address, + mockAssetForwarder.address, + DEXSPAN[env][CHAIN_ID], + DEFAULT_REFUND_ADDRESS + ); + + const AnkrStakeEth = await ethers.getContractFactory("AnkrStakeEth"); + const ankrStakeEthAdapter = await AnkrStakeEth.deploy( + NATIVE, + WNATIVE[env][CHAIN_ID], + deployer.address, + mockAssetForwarder.address, + DEXSPAN[env][CHAIN_ID], + ANKR_TOKEN, + ANKR_POOL + ); + + return { + batchTransaction: BatchTransaction__factory.connect( + batchTransaction.address, + deployer + ), + ankrStakeEthAdapter: AnkrStakeEth__factory.connect( + ankrStakeEthAdapter.address, + deployer + ), + dexSpanAdapter: DexSpanAdapter__factory.connect( + dexSpanAdapter.address, + deployer + ), + mockAssetForwarder: MockAssetForwarder__factory.connect( + mockAssetForwarder.address, + deployer + ), + usdt: TokenInterface__factory.connect(USDT, deployer), + ankrEth: TokenInterface__factory.connect(ANKR_TOKEN, deployer), + }; + }; + + beforeEach(async function () { + await hardhat.network.provider.request({ + method: "hardhat_reset", + params: [ + { + forking: { + jsonRpcUrl: RPC[CHAIN_ID], + }, + }, + ], + }); + }); + + const toBytes32 = (bn: BigNumber) => { + return ethers.utils.hexlify(ethers.utils.zeroPad(bn.toHexString(), 32)); + }; + + // This works for token when it has balance mapping at slot 0. + const setUserTokenBalance = async ( + contract: Contract, + user: Wallet, + balance: BigNumber + ) => { + const index = ethers.utils.solidityKeccak256( + ["uint256", "uint256"], + [user.address, 0] // key, slot + ); + + await hardhat.network.provider.request({ + method: "hardhat_setStorageAt", + params: [contract.address, index, toBytes32(balance).toString()], + }); + + await hardhat.network.provider.request({ + method: "evm_mine", + params: [], + }); + }; + + it("Can stake on ankr on same chain", async () => { + const { batchTransaction, ankrStakeEthAdapter, ankrEth } = + await setupTests(); + + const amount = ethers.utils.parseEther("1"); + + const ankrData = defaultAbiCoder.encode( + ["address", "uint256"], + [deployer.address, amount] + ); + + const tokens = [NATIVE_TOKEN]; + const amounts = [amount]; + const targets = [ankrStakeEthAdapter.address]; + const data = [ankrData]; + const value = [0]; + const callType = [2]; + + const balBefore = await ethers.provider.getBalance(deployer.address); + const ankrEthBalBefore = await ankrEth.balanceOf(deployer.address); + + await batchTransaction.executeBatchCallsSameChain( + tokens, + amounts, + targets, + value, + callType, + data, + { value: amount } + ); + + const balAfter = await ethers.provider.getBalance(deployer.address); + const ankrEthBalAfter = await ankrEth.balanceOf(deployer.address); + + expect(balBefore).gt(balAfter); + expect(ankrEthBalAfter).gt(ankrEthBalBefore); + }); + + it("Can stake ETH on Ankr on dest chain when instruction is received from BatchTransaction contract", async () => { + const { + batchTransaction, + ankrStakeEthAdapter, + ankrEth, + mockAssetForwarder, + } = await setupTests(); + + const amount = "100000000000000000"; + + const targets = [ankrStakeEthAdapter.address]; + const data = [ + defaultAbiCoder.encode( + ["address", "uint256"], + [deployer.address, amount] + ), + ]; + const value = [0]; + const callType = [2]; + + const assetForwarderData = defaultAbiCoder.encode( + ["address", "address[]", "uint256[]", "uint256[]", "bytes[]"], + [deployer.address, targets, value, callType, data] + ); + + const balBefore = await ethers.provider.getBalance(deployer.address); + const ankrEthBalBefore = await ankrEth.balanceOf(deployer.address); + + await mockAssetForwarder.handleMessage( + NATIVE_TOKEN, + amount, + assetForwarderData, + batchTransaction.address, + { value: amount } + ); + + const balAfter = await ethers.provider.getBalance(deployer.address); + const ankrEthBalAfter = await ankrEth.balanceOf(deployer.address); + + expect(balAfter).lt(balBefore); + expect(ankrEthBalAfter).gt(ankrEthBalBefore); + }); + + it("Can stake ETH on Ankr on dest chain when instruction is received directly on AnkrStakeEth adapter", async () => { + const { ankrStakeEthAdapter, ankrEth, mockAssetForwarder } = + await setupTests(); + + const amount = "100000000000000000"; + + const data = defaultAbiCoder.encode(["address"], [deployer.address]); + + const balBefore = await ethers.provider.getBalance(deployer.address); + const ankrEthBalBefore = await ankrEth.balanceOf(deployer.address); + + await mockAssetForwarder.handleMessage( + NATIVE_TOKEN, + amount, + data, + ankrStakeEthAdapter.address, + { value: amount } + ); + + const balAfter = await ethers.provider.getBalance(deployer.address); + const ankrEthBalAfter = await ankrEth.balanceOf(deployer.address); + + expect(balAfter).lt(balBefore); + expect(ankrEthBalAfter).gt(ankrEthBalBefore); + }); +}); diff --git a/evm/test/Ankr/AnkrStakeFantom.specs.ts b/evm/test/Ankr/AnkrStakeFantom.specs.ts new file mode 100644 index 0000000..bc7b4e8 --- /dev/null +++ b/evm/test/Ankr/AnkrStakeFantom.specs.ts @@ -0,0 +1,236 @@ +import hardhat, { ethers, waffle } from "hardhat"; +import { expect } from "chai"; +import { RPC } from "../constants"; +import { + DEXSPAN, + DEFAULT_ENV, + NATIVE, + WNATIVE, + DEFAULT_REFUND_ADDRESS, +} from "../../tasks/constants"; +import { AnkrStakeFantom__factory } from "../../typechain/factories/AnkrStakeFantom__factory"; +import { TokenInterface__factory } from "../../typechain/factories/TokenInterface__factory"; +import { MockAssetForwarder__factory } from "../../typechain/factories/MockAssetForwarder__factory"; +import { BatchTransaction__factory } from "../../typechain/factories/BatchTransaction__factory"; +import { BigNumber, Contract, Wallet } from "ethers"; +import { getPathfinderData } from "../utils"; +import { defaultAbiCoder } from "ethers/lib/utils"; +import { DexSpanAdapter__factory } from "../../typechain/factories/DexSpanAdapter__factory"; + +const CHAIN_ID = "250"; +const ANKR_TOKEN = "0xCfC785741Dc0e98ad4c9F6394Bb9d43Cd1eF5179"; +const ANKR_POOL = "0x84db6eE82b7Cf3b47E8F19270abdE5718B936670"; +const NATIVE_TOKEN = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"; +const USDT = "0x049d68029688eabf473097a2fc38ef61633a3c7a"; + +describe("AnkrStakeFantom Adapter: ", async () => { + const [deployer] = waffle.provider.getWallets(); + + const setupTests = async () => { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + const MockAssetForwarder = await ethers.getContractFactory( + "MockAssetForwarder" + ); + const mockAssetForwarder = await MockAssetForwarder.deploy(); + + const BatchTransaction = await ethers.getContractFactory( + "BatchTransaction" + ); + + const batchTransaction = await BatchTransaction.deploy( + NATIVE, + WNATIVE[env][CHAIN_ID], + mockAssetForwarder.address, + DEXSPAN[env][CHAIN_ID] + ); + + const DexSpanAdapter = await ethers.getContractFactory("DexSpanAdapter"); + const dexSpanAdapter = await DexSpanAdapter.deploy( + NATIVE, + WNATIVE[env][CHAIN_ID], + deployer.address, + mockAssetForwarder.address, + DEXSPAN[env][CHAIN_ID], + DEFAULT_REFUND_ADDRESS + ); + + const AnkrStakeFantom = await ethers.getContractFactory("AnkrStakeFantom"); + const ankrStakeFantomAdapter = await AnkrStakeFantom.deploy( + NATIVE, + WNATIVE[env][CHAIN_ID], + deployer.address, + mockAssetForwarder.address, + DEXSPAN[env][CHAIN_ID], + ANKR_TOKEN, + ANKR_POOL + ); + + return { + batchTransaction: BatchTransaction__factory.connect( + batchTransaction.address, + deployer + ), + ankrStakeFantomAdapter: AnkrStakeFantom__factory.connect( + ankrStakeFantomAdapter.address, + deployer + ), + dexSpanAdapter: DexSpanAdapter__factory.connect( + dexSpanAdapter.address, + deployer + ), + mockAssetForwarder: MockAssetForwarder__factory.connect( + mockAssetForwarder.address, + deployer + ), + usdt: TokenInterface__factory.connect(USDT, deployer), + ankrEth: TokenInterface__factory.connect(ANKR_TOKEN, deployer), + }; + }; + + beforeEach(async function () { + await hardhat.network.provider.request({ + method: "hardhat_reset", + params: [ + { + forking: { + jsonRpcUrl: RPC[CHAIN_ID], + }, + }, + ], + }); + }); + + const toBytes32 = (bn: BigNumber) => { + return ethers.utils.hexlify(ethers.utils.zeroPad(bn.toHexString(), 32)); + }; + + // This works for token when it has balance mapping at slot 0. + const setUserTokenBalance = async ( + contract: Contract, + user: Wallet, + balance: BigNumber + ) => { + const index = ethers.utils.solidityKeccak256( + ["uint256", "uint256"], + [user.address, 0] // key, slot + ); + + await hardhat.network.provider.request({ + method: "hardhat_setStorageAt", + params: [contract.address, index, toBytes32(balance).toString()], + }); + + await hardhat.network.provider.request({ + method: "evm_mine", + params: [], + }); + }; + + it("Can stake on ankr on same chain", async () => { + const { batchTransaction, ankrStakeFantomAdapter, ankrEth } = + await setupTests(); + + const amount = ethers.utils.parseEther("1"); + + const ankrData = defaultAbiCoder.encode( + ["address", "uint256"], + [deployer.address, amount] + ); + + const tokens = [NATIVE_TOKEN]; + const amounts = [amount]; + const targets = [ankrStakeFantomAdapter.address]; + const data = [ankrData]; + const value = [0]; + const callType = [2]; + + const balBefore = await ethers.provider.getBalance(deployer.address); + const ankrEthBalBefore = await ankrEth.balanceOf(deployer.address); + + await batchTransaction.executeBatchCallsSameChain( + tokens, + amounts, + targets, + value, + callType, + data, + { value: amount } + ); + + const balAfter = await ethers.provider.getBalance(deployer.address); + const ankrEthBalAfter = await ankrEth.balanceOf(deployer.address); + + expect(balBefore).gt(balAfter); + expect(ankrEthBalAfter).gt(ankrEthBalBefore); + }); + + it("Can stake FTM on Ankr on dest chain when instruction is received from BatchTransaction contract", async () => { + const { + batchTransaction, + ankrStakeFantomAdapter, + ankrEth, + mockAssetForwarder, + } = await setupTests(); + + const amount = ethers.utils.parseEther("1"); + + const targets = [ankrStakeFantomAdapter.address]; + const data = [ + defaultAbiCoder.encode( + ["address", "uint256"], + [deployer.address, amount] + ), + ]; + const value = [0]; + const callType = [2]; + + const assetForwarderData = defaultAbiCoder.encode( + ["address", "address[]", "uint256[]", "uint256[]", "bytes[]"], + [deployer.address, targets, value, callType, data] + ); + + const balBefore = await ethers.provider.getBalance(deployer.address); + const ankrEthBalBefore = await ankrEth.balanceOf(deployer.address); + + await mockAssetForwarder.handleMessage( + NATIVE_TOKEN, + amount, + assetForwarderData, + batchTransaction.address, + { value: amount } + ); + + const balAfter = await ethers.provider.getBalance(deployer.address); + const ankrEthBalAfter = await ankrEth.balanceOf(deployer.address); + + expect(balAfter).lt(balBefore); + expect(ankrEthBalAfter).gt(ankrEthBalBefore); + }); + + it("Can stake FTM on Ankr on dest chain when instruction is received directly on AnkrStakeFantom adapter", async () => { + const { ankrStakeFantomAdapter, ankrEth, mockAssetForwarder } = + await setupTests(); + + const amount = ethers.utils.parseEther("1"); + + const data = defaultAbiCoder.encode(["address"], [deployer.address]); + + const balBefore = await ethers.provider.getBalance(deployer.address); + const ankrEthBalBefore = await ankrEth.balanceOf(deployer.address); + + await mockAssetForwarder.handleMessage( + NATIVE_TOKEN, + amount, + data, + ankrStakeFantomAdapter.address, + { value: amount } + ); + + const balAfter = await ethers.provider.getBalance(deployer.address); + const ankrEthBalAfter = await ankrEth.balanceOf(deployer.address); + + expect(balAfter).lt(balBefore); + expect(ankrEthBalAfter).gt(ankrEthBalBefore); + }); +}); diff --git a/evm/test/Ankr/AnkrStakeMatic.specs.ts b/evm/test/Ankr/AnkrStakeMatic.specs.ts new file mode 100644 index 0000000..13bd812 --- /dev/null +++ b/evm/test/Ankr/AnkrStakeMatic.specs.ts @@ -0,0 +1,246 @@ +import hardhat, { ethers, waffle } from "hardhat"; +import { expect } from "chai"; +import { RPC } from "../constants"; +import { + DEXSPAN, + DEFAULT_ENV, + NATIVE, + WNATIVE, + DEFAULT_REFUND_ADDRESS, +} from "../../tasks/constants"; +import { AnkrStakeMatic__factory } from "../../typechain/factories/AnkrStakeMatic__factory"; +import { TokenInterface__factory } from "../../typechain/factories/TokenInterface__factory"; +import { MockAssetForwarder__factory } from "../../typechain/factories/MockAssetForwarder__factory"; +import { BatchTransaction__factory } from "../../typechain/factories/BatchTransaction__factory"; +import { BigNumber, Contract, Wallet } from "ethers"; +import { getPathfinderData } from "../utils"; +import { defaultAbiCoder } from "ethers/lib/utils"; +import { DexSpanAdapter__factory } from "../../typechain/factories/DexSpanAdapter__factory"; + +const CHAIN_ID = "1"; +const ANKR_TOKEN = "0x26dcFbFa8Bc267b250432c01C982Eaf81cC5480C"; +const ANKR_POOL = "0xCfD4B4Bc15C8bF0Fd820B0D4558c725727B3ce89"; +const USDT = "0xdac17f958d2ee523a2206206994597c13d831ec7"; +const MATIC_TOKEN = "0x7D1AfA7B718fb893dB30A3aBc0Cfc608AaCfeBB0"; + +describe("AnkrStakeMatic Adapter: ", async () => { + const [deployer] = waffle.provider.getWallets(); + + const setupTests = async () => { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + const MockAssetForwarder = await ethers.getContractFactory( + "MockAssetForwarder" + ); + const mockAssetForwarder = await MockAssetForwarder.deploy(); + + const BatchTransaction = await ethers.getContractFactory( + "BatchTransaction" + ); + + const batchTransaction = await BatchTransaction.deploy( + NATIVE, + WNATIVE[env][CHAIN_ID], + mockAssetForwarder.address, + DEXSPAN[env][CHAIN_ID] + ); + + const DexSpanAdapter = await ethers.getContractFactory("DexSpanAdapter"); + const dexSpanAdapter = await DexSpanAdapter.deploy( + NATIVE, + WNATIVE[env][CHAIN_ID], + deployer.address, + mockAssetForwarder.address, + DEXSPAN[env][CHAIN_ID], + DEFAULT_REFUND_ADDRESS + ); + + const AnkrStakeMatic = await ethers.getContractFactory("AnkrStakeMatic"); + const ankrStakeMaticAdapter = await AnkrStakeMatic.deploy( + NATIVE, + WNATIVE[env][CHAIN_ID], + deployer.address, + mockAssetForwarder.address, + DEXSPAN[env][CHAIN_ID], + ANKR_TOKEN, + MATIC_TOKEN, + ANKR_POOL + ); + + return { + batchTransaction: BatchTransaction__factory.connect( + batchTransaction.address, + deployer + ), + ankrStakeMaticAdapter: AnkrStakeMatic__factory.connect( + ankrStakeMaticAdapter.address, + deployer + ), + dexSpanAdapter: DexSpanAdapter__factory.connect( + dexSpanAdapter.address, + deployer + ), + mockAssetForwarder: MockAssetForwarder__factory.connect( + mockAssetForwarder.address, + deployer + ), + usdt: TokenInterface__factory.connect(USDT, deployer), + ankrMatic: TokenInterface__factory.connect(ANKR_TOKEN, deployer), + matic: TokenInterface__factory.connect(MATIC_TOKEN, deployer), + }; + }; + + beforeEach(async function () { + await hardhat.network.provider.request({ + method: "hardhat_reset", + params: [ + { + forking: { + jsonRpcUrl: RPC[CHAIN_ID], + }, + }, + ], + }); + }); + + const toBytes32 = (bn: BigNumber) => { + return ethers.utils.hexlify(ethers.utils.zeroPad(bn.toHexString(), 32)); + }; + + // This works for token when it has balance mapping at slot 0. + const setUserTokenBalance = async ( + contract: Contract, + user: Wallet, + balance: BigNumber + ) => { + const index = ethers.utils.solidityKeccak256( + ["uint256", "uint256"], + [user.address, 0] // key, slot + ); + + await hardhat.network.provider.request({ + method: "hardhat_setStorageAt", + params: [contract.address, index, toBytes32(balance).toString()], + }); + + await hardhat.network.provider.request({ + method: "evm_mine", + params: [], + }); + }; + + it("Can stake on ankr on same chain", async () => { + const { batchTransaction, ankrStakeMaticAdapter, ankrMatic, matic } = + await setupTests(); + + const amount = ethers.utils.parseEther("1"); + + const ankrData = defaultAbiCoder.encode( + ["address", "uint256"], + [deployer.address, amount] + ); + + const tokens = [MATIC_TOKEN]; + const amounts = [amount]; + const targets = [ankrStakeMaticAdapter.address]; + const data = [ankrData]; + const value = [0]; + const callType = [2]; + + await setUserTokenBalance(matic, deployer, amount); + await matic.approve(batchTransaction.address, amount); + + const balBefore = await ethers.provider.getBalance(deployer.address); + const ankrMaticBalBefore = await ankrMatic.balanceOf(deployer.address); + + await batchTransaction.executeBatchCallsSameChain( + tokens, + amounts, + targets, + value, + callType, + data, + ); + + const balAfter = await ethers.provider.getBalance(deployer.address); + const ankrMaticBalAfter = await ankrMatic.balanceOf(deployer.address); + + expect(balBefore).gt(balAfter); + expect(ankrMaticBalAfter).gt(ankrMaticBalBefore); + }); + + it("Can stake MATIC on Ankr on dest chain when instruction is received from BatchTransaction contract", async () => { + const { + batchTransaction, + ankrStakeMaticAdapter, + ankrMatic, + mockAssetForwarder, + matic + } = await setupTests(); + + const amount = ethers.utils.parseEther("1"); + + const targets = [ankrStakeMaticAdapter.address]; + const data = [ + defaultAbiCoder.encode( + ["address", "uint256"], + [deployer.address, amount] + ), + ]; + const value = [0]; + const callType = [2]; + + await setUserTokenBalance(matic, deployer, amount); + await matic.approve(mockAssetForwarder.address, amount); + + const assetForwarderData = defaultAbiCoder.encode( + ["address", "address[]", "uint256[]", "uint256[]", "bytes[]"], + [deployer.address, targets, value, callType, data] + ); + + const balBefore = await ethers.provider.getBalance(deployer.address); + const ankrMaticBalBefore = await ankrMatic.balanceOf(deployer.address); + + await mockAssetForwarder.handleMessage( + MATIC_TOKEN, + amount, + assetForwarderData, + batchTransaction.address, + ); + + const balAfter = await ethers.provider.getBalance(deployer.address); + const ankrMaticBalAfter = await ankrMatic.balanceOf(deployer.address); + + expect(balAfter).lt(balBefore); + expect(ankrMaticBalAfter).gt(ankrMaticBalBefore); + }); + + it("Can stake MATIC on Ankr on dest chain when instruction is received directly on AnkrStakeMatic adapter", async () => { + const { ankrStakeMaticAdapter, ankrMatic, mockAssetForwarder, matic } = + await setupTests(); + + const amount = ethers.utils.parseEther("1"); + + await setUserTokenBalance(matic, deployer, amount); + await matic.approve(mockAssetForwarder.address, amount); + + const data = defaultAbiCoder.encode(["address"], [deployer.address]); + + + const balBefore = await ethers.provider.getBalance(deployer.address); + const ankrMaticBalBefore = await ankrMatic.balanceOf(deployer.address); + + await mockAssetForwarder.handleMessage( + MATIC_TOKEN, + amount, + data, + ankrStakeMaticAdapter.address, + ); + + const balAfter = await ethers.provider.getBalance(deployer.address); + const ankrMaticBalAfter = await ankrMatic.balanceOf(deployer.address); + + expect(balAfter).lt(balBefore); + expect(ankrMaticBalAfter).gt(ankrMaticBalBefore); + }); +}); diff --git a/evm/test/Ankr/AnkrStakePolygon.specs.ts b/evm/test/Ankr/AnkrStakePolygon.specs.ts new file mode 100644 index 0000000..6497ecd --- /dev/null +++ b/evm/test/Ankr/AnkrStakePolygon.specs.ts @@ -0,0 +1,236 @@ +import hardhat, { ethers, waffle } from "hardhat"; +import { expect } from "chai"; +import { RPC } from "../constants"; +import { + DEXSPAN, + DEFAULT_ENV, + NATIVE, + WNATIVE, + DEFAULT_REFUND_ADDRESS, +} from "../../tasks/constants"; +import { AnkrStakePolygon__factory } from "../../typechain/factories/AnkrStakePolygon__factory"; +import { TokenInterface__factory } from "../../typechain/factories/TokenInterface__factory"; +import { MockAssetForwarder__factory } from "../../typechain/factories/MockAssetForwarder__factory"; +import { BatchTransaction__factory } from "../../typechain/factories/BatchTransaction__factory"; +import { BigNumber, Contract, Wallet } from "ethers"; +import { getPathfinderData } from "../utils"; +import { defaultAbiCoder } from "ethers/lib/utils"; +import { DexSpanAdapter__factory } from "../../typechain/factories/DexSpanAdapter__factory"; + +const CHAIN_ID = "137"; +const ANKR_TOKEN = "0x0E9b89007eEE9c958c0EDA24eF70723C2C93dD58"; +const ANKR_POOL = "0x62A509BA95c75Cabc7190469025E5aBeE4eDdb2a"; +const NATIVE_TOKEN = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"; +const USDT = "0xc2132d05d31c914a87c6611c10748aeb04b58e8f"; + +describe("AnkrStakePolygon Adapter: ", async () => { + const [deployer] = waffle.provider.getWallets(); + + const setupTests = async () => { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + const MockAssetForwarder = await ethers.getContractFactory( + "MockAssetForwarder" + ); + const mockAssetForwarder = await MockAssetForwarder.deploy(); + + const BatchTransaction = await ethers.getContractFactory( + "BatchTransaction" + ); + + const batchTransaction = await BatchTransaction.deploy( + NATIVE, + WNATIVE[env][CHAIN_ID], + mockAssetForwarder.address, + DEXSPAN[env][CHAIN_ID] + ); + + const DexSpanAdapter = await ethers.getContractFactory("DexSpanAdapter"); + const dexSpanAdapter = await DexSpanAdapter.deploy( + NATIVE, + WNATIVE[env][CHAIN_ID], + deployer.address, + mockAssetForwarder.address, + DEXSPAN[env][CHAIN_ID], + DEFAULT_REFUND_ADDRESS + ); + + const AnkrStakePolygon = await ethers.getContractFactory("AnkrStakePolygon"); + const ankrStakePolygonAdapter = await AnkrStakePolygon.deploy( + NATIVE, + WNATIVE[env][CHAIN_ID], + deployer.address, + mockAssetForwarder.address, + DEXSPAN[env][CHAIN_ID], + ANKR_TOKEN, + ANKR_POOL + ); + + return { + batchTransaction: BatchTransaction__factory.connect( + batchTransaction.address, + deployer + ), + ankrStakePolygonAdapter: AnkrStakePolygon__factory.connect( + ankrStakePolygonAdapter.address, + deployer + ), + dexSpanAdapter: DexSpanAdapter__factory.connect( + dexSpanAdapter.address, + deployer + ), + mockAssetForwarder: MockAssetForwarder__factory.connect( + mockAssetForwarder.address, + deployer + ), + usdt: TokenInterface__factory.connect(USDT, deployer), + ankrEth: TokenInterface__factory.connect(ANKR_TOKEN, deployer), + }; + }; + + beforeEach(async function () { + await hardhat.network.provider.request({ + method: "hardhat_reset", + params: [ + { + forking: { + jsonRpcUrl: RPC[CHAIN_ID], + }, + }, + ], + }); + }); + + const toBytes32 = (bn: BigNumber) => { + return ethers.utils.hexlify(ethers.utils.zeroPad(bn.toHexString(), 32)); + }; + + // This works for token when it has balance mapping at slot 0. + const setUserTokenBalance = async ( + contract: Contract, + user: Wallet, + balance: BigNumber + ) => { + const index = ethers.utils.solidityKeccak256( + ["uint256", "uint256"], + [user.address, 0] // key, slot + ); + + await hardhat.network.provider.request({ + method: "hardhat_setStorageAt", + params: [contract.address, index, toBytes32(balance).toString()], + }); + + await hardhat.network.provider.request({ + method: "evm_mine", + params: [], + }); + }; + + it("Can stake on ankr on same chain", async () => { + const { batchTransaction, ankrStakePolygonAdapter, ankrEth } = + await setupTests(); + + const amount = ethers.utils.parseEther("1"); + + const ankrData = defaultAbiCoder.encode( + ["address", "uint256"], + [deployer.address, amount] + ); + + const tokens = [NATIVE_TOKEN]; + const amounts = [amount]; + const targets = [ankrStakePolygonAdapter.address]; + const data = [ankrData]; + const value = [0]; + const callType = [2]; + + const balBefore = await ethers.provider.getBalance(deployer.address); + const ankrEthBalBefore = await ankrEth.balanceOf(deployer.address); + + await batchTransaction.executeBatchCallsSameChain( + tokens, + amounts, + targets, + value, + callType, + data, + { value: amount } + ); + + const balAfter = await ethers.provider.getBalance(deployer.address); + const ankrEthBalAfter = await ankrEth.balanceOf(deployer.address); + + expect(balBefore).gt(balAfter); + expect(ankrEthBalAfter).gt(ankrEthBalBefore); + }); + + it("Can stake MATIC on Ankr on dest chain when instruction is received from BatchTransaction contract", async () => { + const { + batchTransaction, + ankrStakePolygonAdapter, + ankrEth, + mockAssetForwarder, + } = await setupTests(); + + const amount = "100000000000000000"; + + const targets = [ankrStakePolygonAdapter.address]; + const data = [ + defaultAbiCoder.encode( + ["address", "uint256"], + [deployer.address, amount] + ), + ]; + const value = [0]; + const callType = [2]; + + const assetForwarderData = defaultAbiCoder.encode( + ["address", "address[]", "uint256[]", "uint256[]", "bytes[]"], + [deployer.address, targets, value, callType, data] + ); + + const balBefore = await ethers.provider.getBalance(deployer.address); + const ankrEthBalBefore = await ankrEth.balanceOf(deployer.address); + + await mockAssetForwarder.handleMessage( + NATIVE_TOKEN, + amount, + assetForwarderData, + batchTransaction.address, + { value: amount } + ); + + const balAfter = await ethers.provider.getBalance(deployer.address); + const ankrEthBalAfter = await ankrEth.balanceOf(deployer.address); + + expect(balAfter).lt(balBefore); + expect(ankrEthBalAfter).gt(ankrEthBalBefore); + }); + + it("Can stake MATIC on Ankr on dest chain when instruction is received directly on AnkrStakePolygon adapter", async () => { + const { ankrStakePolygonAdapter, ankrEth, mockAssetForwarder } = + await setupTests(); + + const amount = "100000000000000000"; + + const data = defaultAbiCoder.encode(["address"], [deployer.address]); + + const balBefore = await ethers.provider.getBalance(deployer.address); + const ankrEthBalBefore = await ankrEth.balanceOf(deployer.address); + + await mockAssetForwarder.handleMessage( + NATIVE_TOKEN, + amount, + data, + ankrStakePolygonAdapter.address, + { value: amount } + ); + + const balAfter = await ethers.provider.getBalance(deployer.address); + const ankrEthBalAfter = await ankrEth.balanceOf(deployer.address); + + expect(balAfter).lt(balBefore); + expect(ankrEthBalAfter).gt(ankrEthBalBefore); + }); +}); diff --git a/evm/test/Benqi/BenqiStakeAvax.specs.ts b/evm/test/Benqi/BenqiStakeAvax.specs.ts new file mode 100644 index 0000000..31186d3 --- /dev/null +++ b/evm/test/Benqi/BenqiStakeAvax.specs.ts @@ -0,0 +1,234 @@ +import hardhat, { ethers, waffle } from "hardhat"; +import { expect } from "chai"; +import { RPC } from "../constants"; +import { + DEXSPAN, + DEFAULT_ENV, + NATIVE, + WNATIVE, + DEFAULT_REFUND_ADDRESS, +} from "../../tasks/constants"; +import { BenqiStakeAvax__factory } from "../../typechain/factories/BenqiStakeAvax__factory"; +import { TokenInterface__factory } from "../../typechain/factories/TokenInterface__factory"; +import { MockAssetForwarder__factory } from "../../typechain/factories/MockAssetForwarder__factory"; +import { BatchTransaction__factory } from "../../typechain/factories/BatchTransaction__factory"; +import { BigNumber, Contract, Wallet } from "ethers"; +import { getPathfinderData } from "../utils"; +import { defaultAbiCoder } from "ethers/lib/utils"; +import { DexSpanAdapter__factory } from "../../typechain/factories/DexSpanAdapter__factory"; + +const CHAIN_ID = "43114"; +const BENQI_TOKEN = "0x2b2C81e08f1Af8835a78Bb2A90AE924ACE0eA4bE"; +const NATIVE_TOKEN = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"; +const USDT = "0x9702230a8ea53601f5cd2dc00fdbc13d4df4a8c7"; + +describe("BenqiStakeAvax Adapter: ", async () => { + const [deployer] = waffle.provider.getWallets(); + + const setupTests = async () => { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + const MockAssetForwarder = await ethers.getContractFactory( + "MockAssetForwarder" + ); + const mockAssetForwarder = await MockAssetForwarder.deploy(); + + const BatchTransaction = await ethers.getContractFactory( + "BatchTransaction" + ); + + const batchTransaction = await BatchTransaction.deploy( + NATIVE, + WNATIVE[env][CHAIN_ID], + mockAssetForwarder.address, + DEXSPAN[env][CHAIN_ID] + ); + + const DexSpanAdapter = await ethers.getContractFactory("DexSpanAdapter"); + const dexSpanAdapter = await DexSpanAdapter.deploy( + NATIVE, + WNATIVE[env][CHAIN_ID], + deployer.address, + mockAssetForwarder.address, + DEXSPAN[env][CHAIN_ID], + DEFAULT_REFUND_ADDRESS + ); + + const BenqiStakeAvax = await ethers.getContractFactory("BenqiStakeAvax"); + const benqiStakeAvaxAdapter = await BenqiStakeAvax.deploy( + NATIVE, + WNATIVE[env][CHAIN_ID], + deployer.address, + mockAssetForwarder.address, + DEXSPAN[env][CHAIN_ID], + BENQI_TOKEN, + ); + + return { + batchTransaction: BatchTransaction__factory.connect( + batchTransaction.address, + deployer + ), + benqiStakeAvaxAdapter: BenqiStakeAvax__factory.connect( + benqiStakeAvaxAdapter.address, + deployer + ), + dexSpanAdapter: DexSpanAdapter__factory.connect( + dexSpanAdapter.address, + deployer + ), + mockAssetForwarder: MockAssetForwarder__factory.connect( + mockAssetForwarder.address, + deployer + ), + usdt: TokenInterface__factory.connect(USDT, deployer), + benqiSAvax: TokenInterface__factory.connect(BENQI_TOKEN, deployer), + }; + }; + + beforeEach(async function () { + await hardhat.network.provider.request({ + method: "hardhat_reset", + params: [ + { + forking: { + jsonRpcUrl: RPC[CHAIN_ID], + }, + }, + ], + }); + }); + + const toBytes32 = (bn: BigNumber) => { + return ethers.utils.hexlify(ethers.utils.zeroPad(bn.toHexString(), 32)); + }; + + // This works for token when it has balance mapping at slot 0. + const setUserTokenBalance = async ( + contract: Contract, + user: Wallet, + balance: BigNumber + ) => { + const index = ethers.utils.solidityKeccak256( + ["uint256", "uint256"], + [user.address, 0] // key, slot + ); + + await hardhat.network.provider.request({ + method: "hardhat_setStorageAt", + params: [contract.address, index, toBytes32(balance).toString()], + }); + + await hardhat.network.provider.request({ + method: "evm_mine", + params: [], + }); + }; + + it("Can stake on benqi on same chain", async () => { + const { batchTransaction, benqiStakeAvaxAdapter, benqiSAvax } = + await setupTests(); + + const amount = ethers.utils.parseEther("1"); + + const benqiData = defaultAbiCoder.encode( + ["address", "uint256"], + [deployer.address, amount] + ); + + const tokens = [NATIVE_TOKEN]; + const amounts = [amount]; + const targets = [benqiStakeAvaxAdapter.address]; + const data = [benqiData]; + const value = [0]; + const callType = [2]; + + const balBefore = await ethers.provider.getBalance(deployer.address); + const benqiSAvaxBalBefore = await benqiSAvax.balanceOf(deployer.address); + + await batchTransaction.executeBatchCallsSameChain( + tokens, + amounts, + targets, + value, + callType, + data, + { value: amount } + ); + + const balAfter = await ethers.provider.getBalance(deployer.address); + const benqiSAvaxBalAfter = await benqiSAvax.balanceOf(deployer.address); + + expect(balBefore).gt(balAfter); + expect(benqiSAvaxBalAfter).gt(benqiSAvaxBalBefore); + }); + + it("Can stake AVAX on Benqi on dest chain when instruction is received from BatchTransaction contract", async () => { + const { + batchTransaction, + benqiStakeAvaxAdapter, + benqiSAvax, + mockAssetForwarder, + } = await setupTests(); + + const amount = ethers.utils.parseEther("1"); + + const targets = [benqiStakeAvaxAdapter.address]; + const data = [ + defaultAbiCoder.encode( + ["address", "uint256"], + [deployer.address, amount] + ), + ]; + const value = [0]; + const callType = [2]; + + const assetForwarderData = defaultAbiCoder.encode( + ["address", "address[]", "uint256[]", "uint256[]", "bytes[]"], + [deployer.address, targets, value, callType, data] + ); + + const balBefore = await ethers.provider.getBalance(deployer.address); + const benqiSAvaxBalBefore = await benqiSAvax.balanceOf(deployer.address); + + await mockAssetForwarder.handleMessage( + NATIVE_TOKEN, + amount, + assetForwarderData, + batchTransaction.address, + { value: amount } + ); + + const balAfter = await ethers.provider.getBalance(deployer.address); + const benqiSAvaxBalAfter = await benqiSAvax.balanceOf(deployer.address); + + expect(balAfter).lt(balBefore); + expect(benqiSAvaxBalAfter).gt(benqiSAvaxBalBefore); + }); + + it("Can stake AVAX on Benqi on dest chain when instruction is received directly on BenqiStakeAvax adapter", async () => { + const { benqiStakeAvaxAdapter, benqiSAvax, mockAssetForwarder } = + await setupTests(); + + const amount = ethers.utils.parseEther("1"); + + const data = defaultAbiCoder.encode(["address"], [deployer.address]); + + const balBefore = await ethers.provider.getBalance(deployer.address); + const benqiSAvaxBalBefore = await benqiSAvax.balanceOf(deployer.address); + + await mockAssetForwarder.handleMessage( + NATIVE_TOKEN, + amount, + data, + benqiStakeAvaxAdapter.address, + { value: amount } + ); + + const balAfter = await ethers.provider.getBalance(deployer.address); + const benqiSAvaxBalAfter = await benqiSAvax.balanceOf(deployer.address); + + expect(balAfter).lt(balBefore); + expect(benqiSAvaxBalAfter).gt(benqiSAvaxBalBefore); + }); +}); diff --git a/evm/test/Compound/CompoundBorrow.specs.ts b/evm/test/Compound/CompoundBorrow.specs.ts new file mode 100644 index 0000000..776cdbc --- /dev/null +++ b/evm/test/Compound/CompoundBorrow.specs.ts @@ -0,0 +1,303 @@ +import hardhat, { ethers, waffle } from "hardhat"; +import { expect } from "chai"; +import { RPC } from "../constants"; +import { + DEXSPAN, + DEFAULT_ENV, + DEFAULT_REFUND_ADDRESS, +} from "../../tasks/constants"; +import { TokenInterface__factory } from "../../typechain/factories/TokenInterface__factory"; +import { MockAssetForwarder__factory } from "../../typechain/factories/MockAssetForwarder__factory"; +import { BatchTransaction__factory } from "../../typechain/factories/BatchTransaction__factory"; +import { CompoundBorrow__factory } from "../../typechain/factories/CompoundBorrow__factory"; +import { IPoolV3__factory } from "../../typechain/factories/IPoolV3__factory"; +import { defaultAbiCoder } from "ethers/lib/utils"; +import { CompoundSupply__factory } from "../../typechain/factories/CompoundSupply__factory"; +import { IComet__factory } from "../../typechain/factories/IComet__factory"; + +const CHAIN_ID = "5"; +const COMPOUND_USDC_POOL = "0x3EE77595A8459e93C2888b13aDB354017B198188"; +const COMPOUND_WETH_POOL = "0x9A539EEc489AAA03D588212a164d0abdB5F08F5F"; +const NATIVE_TOKEN = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"; +const WETH = "0x42a71137C09AE83D8d05974960fd607d40033499"; +const C_WETH_ADDRESS = "0x9A539EEc489AAA03D588212a164d0abdB5F08F5F"; +const C_USDC_ADDRESS = "0x3EE77595A8459e93C2888b13aDB354017B198188"; +const USDC = "0x07865c6E87B9F70255377e024ace6630C1Eaa37F"; + +const AAVE_DEBT_TOKEN_ABI = [ + "function approveDelegation(address delegatee, uint256 amount) external", + "function transfer(address _receiver, uint256 _value) public returns (bool success)", + "function transferFrom(address, address, uint256) public returns (bool)", + "function approve(address _spender, uint256 _value) public returns (bool success)", + "function allowance(address _owner, address _spender) public view returns (uint256 remaining)", + "function balanceOf(address _owner) public view returns (uint256 balance)", + "event Approval(address indexed _owner, address indexed _spender, uint256 _value)", +]; + +describe("CompoundBorrow Adapter: ", async () => { + const [deployer] = waffle.provider.getWallets(); + + const setupTests = async () => { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + const MockAssetForwarder = await ethers.getContractFactory( + "MockAssetForwarder" + ); + const mockAssetForwarder = await MockAssetForwarder.deploy(); + + const CompoundSupplyAdapter = await ethers.getContractFactory("CompoundSupply"); + + const compoundSupplyAdapter = await CompoundSupplyAdapter.deploy( + NATIVE_TOKEN, + WETH, + deployer.address, + mockAssetForwarder.address, + DEXSPAN[env][CHAIN_ID], + USDC, + COMPOUND_USDC_POOL, + COMPOUND_WETH_POOL + ); + + const CompoundBorrowAdapter = await ethers.getContractFactory("CompoundBorrow"); + + const compoundBorrowAdapter = await CompoundBorrowAdapter.deploy( + NATIVE_TOKEN, + WETH, + deployer.address, + mockAssetForwarder.address, + DEXSPAN[env][CHAIN_ID], + DEFAULT_REFUND_ADDRESS, + USDC, + COMPOUND_USDC_POOL, + COMPOUND_WETH_POOL + ); + + const BatchTransaction = await ethers.getContractFactory( + "BatchTransaction" + ); + + const batchTransaction = await BatchTransaction.deploy( + NATIVE_TOKEN, + WETH, + mockAssetForwarder.address, + DEXSPAN[env][CHAIN_ID] + ); + + const weth = TokenInterface__factory.connect(WETH, deployer); + const cWeth = TokenInterface__factory.connect(C_WETH_ADDRESS, deployer); + const cUSDC = TokenInterface__factory.connect(C_USDC_ADDRESS, deployer); + const usdc = TokenInterface__factory.connect(USDC, deployer); + const compoundUSDCPool = IComet__factory.connect(COMPOUND_USDC_POOL, deployer); + const compoundWETHPool = IComet__factory.connect(COMPOUND_WETH_POOL, deployer); + + const MockToken = await ethers.getContractFactory("MockToken"); + const mockToken = await MockToken.deploy(); + await mockToken.mint(deployer.address, ethers.utils.parseEther("10000")); + + return { + compoundSupplyAdapter: CompoundSupply__factory.connect( + compoundSupplyAdapter.address, + deployer + ), + compoundBorrowAdapter: CompoundBorrow__factory.connect( + compoundBorrowAdapter.address, + deployer + ), + batchTransaction: BatchTransaction__factory.connect( + batchTransaction.address, + deployer + ), + weth, + cWeth, + usdc, + cUSDC, + compoundUSDCPool, + compoundWETHPool, + mockAssetForwarder: MockAssetForwarder__factory.connect( + mockAssetForwarder.address, + deployer + ), + mockToken: TokenInterface__factory.connect(mockToken.address, deployer), + }; + }; + + beforeEach(async function () { + await hardhat.network.provider.request({ + method: "hardhat_reset", + params: [ + { + forking: { + jsonRpcUrl: RPC[CHAIN_ID], + }, + }, + ], + }); + }); + + it("Can borrow funds on user's behalf on weth market", async () => { + const { + weth, + cWeth, + usdc, + batchTransaction, + compoundBorrowAdapter, + compoundSupplyAdapter, + compoundWETHPool + } = await setupTests(); + + const supplyAsset = NATIVE_TOKEN; + const supplyAmount = ethers.utils.parseEther("10"); + const supplyOnBehalfOf = deployer.address; + + const compoundSupplyData = defaultAbiCoder.encode( + ["address", "address", "uint256","address"], + [supplyAsset, supplyOnBehalfOf, supplyAmount, WETH] + ); + + const borrowAmount = "10000"; + const borrowAsset = WETH; + const borrowOnBehalfOf = deployer.address; + const borrowRecipient = deployer.address; + + const compoundBorrowData = defaultAbiCoder.encode( + ["uint256", "address", "address", "address"], + [ + borrowAmount, + borrowAsset, + borrowOnBehalfOf, + borrowRecipient, + ] + ); + + const tokens = [supplyAsset]; + const amounts = [supplyAmount]; + const targets = [compoundSupplyAdapter.address, compoundBorrowAdapter.address]; + const data = [compoundSupplyData, compoundBorrowData]; + const value = [0, 0]; + const callType = [2, 2]; + + await compoundWETHPool.allow( + batchTransaction.address, + true + ); + + const userBalBefore = await cWeth.balanceOf(deployer.address); + const wethBalBefore = await weth.balanceOf(deployer.address); + await batchTransaction.executeBatchCallsSameChain( + tokens, + amounts, + targets, + value, + callType, + data, + { value: supplyAmount } + ); + + const userBalAfter = await cWeth.balanceOf(deployer.address); + const wethBalAfter = await weth.balanceOf(deployer.address); + + expect(userBalBefore).eq(0); + expect(userBalAfter).gt(0); + expect(wethBalBefore).eq(0); + expect(wethBalAfter).eq(borrowAmount); + }); + + it("Can borrow funds on user's behalf on usdc market", async () => { + const { + weth, + cWeth, + usdc, + batchTransaction, + compoundBorrowAdapter, + compoundSupplyAdapter, + compoundUSDCPool + } = await setupTests(); + + const supplyAsset = NATIVE_TOKEN; + const supplyAmount = ethers.utils.parseEther("10"); + const supplyOnBehalfOf = deployer.address; + + const compoundSupplyData = defaultAbiCoder.encode( + ["address", "address", "uint256","address"], + [supplyAsset, supplyOnBehalfOf, supplyAmount, USDC] + ); + + const borrowAmount = "10000"; + const borrowAsset = USDC; + const borrowOnBehalfOf = deployer.address; + const borrowRecipient = deployer.address; + + const compoundBorrowData = defaultAbiCoder.encode( + ["uint256", "address", "address", "address"], + [ + borrowAmount, + borrowAsset, + borrowOnBehalfOf, + borrowRecipient, + ] + ); + + const tokens = [supplyAsset]; + const amounts = [supplyAmount]; + const targets = [compoundSupplyAdapter.address, compoundBorrowAdapter.address]; + const data = [compoundSupplyData, compoundBorrowData]; + const value = [0, 0]; + const callType = [2, 2]; + + await compoundUSDCPool.allow( + batchTransaction.address, + true + ); + + const usdcBalBefore = await usdc.balanceOf(deployer.address); + await batchTransaction.executeBatchCallsSameChain( + tokens, + amounts, + targets, + value, + callType, + data, + { value: supplyAmount } + ); + + const usdcBalAfter = await usdc.balanceOf(deployer.address); + + const collateralBal = await compoundUSDCPool.collateralBalanceOf(deployer.address, WETH); + + expect(collateralBal).gt(0); + + expect(usdcBalAfter).eq(usdcBalBefore.add(borrowAmount)); + }); + + + it("Cannot borrow funds cross-chain when handleMessage is called directly on adapter", async () => { + const { usdc, mockAssetForwarder, compoundBorrowAdapter } = + await setupTests(); + + const amount = ethers.utils.parseEther("1"); + const borrowAmount = "10000"; + const borrowAsset = usdc.address; + const borrowOnBehalfOf = deployer.address; + const borrowRecipient = deployer.address; + + const compoundBorrowData = defaultAbiCoder.encode( + ["uint256", "address", "address", "address"], + [ + borrowAmount, + borrowAsset, + borrowOnBehalfOf, + borrowRecipient, + ] + ); + + expect( + await mockAssetForwarder.handleMessage( + NATIVE_TOKEN, + amount, + compoundBorrowData, + compoundBorrowAdapter.address, + { value: amount } + ) + ).to.emit("UnsupportedOperation"); + }); +}); diff --git a/evm/test/Compound/CompoundSupply.specs.ts b/evm/test/Compound/CompoundSupply.specs.ts new file mode 100644 index 0000000..137a79d --- /dev/null +++ b/evm/test/Compound/CompoundSupply.specs.ts @@ -0,0 +1,952 @@ +import hardhat, { ethers, waffle } from "hardhat"; +import { expect } from "chai"; +import { RPC } from "../constants"; +import { DEXSPAN, DEFAULT_ENV } from "../../tasks/constants"; +import { TokenInterface__factory } from "../../typechain/factories/TokenInterface__factory"; +import { MockAssetForwarder__factory } from "../../typechain/factories/MockAssetForwarder__factory"; +import { BatchTransaction__factory } from "../../typechain/factories/BatchTransaction__factory"; +import { CompoundSupply__factory } from "../../typechain/factories/CompoundSupply__factory"; +import { IComet__factory } from "../../typechain/factories/IComet__factory"; +import { defaultAbiCoder } from "ethers/lib/utils"; +import { zeroAddress } from "ethereumjs-util"; + +const CHAIN_ID = "5"; +const COMPOUND_USDC_POOL = "0x3EE77595A8459e93C2888b13aDB354017B198188"; +const COMPOUND_WETH_POOL = "0x9A539EEc489AAA03D588212a164d0abdB5F08F5F"; +const NATIVE_TOKEN = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"; +const WETH = "0x42a71137C09AE83D8d05974960fd607d40033499"; +const C_WETH_ADDRESS = "0x9A539EEc489AAA03D588212a164d0abdB5F08F5F"; +const C_USDC_ADDRESS = "0x3EE77595A8459e93C2888b13aDB354017B198188"; +const USDC = "0x07865c6E87B9F70255377e024ace6630C1Eaa37F"; + +describe("CompoundSupply Adapter: ", async () => { + const [deployer, alice] = waffle.provider.getWallets(); + + const setupTests = async () => { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + const MockAssetForwarder = await ethers.getContractFactory( + "MockAssetForwarder" + ); + const mockAssetForwarder = await MockAssetForwarder.deploy(); + + const CompoundSupplyAdapter = await ethers.getContractFactory("CompoundSupply"); + + const compoundSupplyAdapter = await CompoundSupplyAdapter.deploy( + NATIVE_TOKEN, + WETH, + deployer.address, + mockAssetForwarder.address, + DEXSPAN[env][CHAIN_ID], + USDC, + COMPOUND_USDC_POOL, + COMPOUND_WETH_POOL + ); + + const BatchTransaction = await ethers.getContractFactory( + "BatchTransaction" + ); + + const batchTransaction = await BatchTransaction.deploy( + NATIVE_TOKEN, + WETH, + mockAssetForwarder.address, + DEXSPAN[env][CHAIN_ID] + ); + + const weth = TokenInterface__factory.connect(WETH, deployer); + const cWeth = TokenInterface__factory.connect(C_WETH_ADDRESS, deployer); + const cUSDC = TokenInterface__factory.connect(C_USDC_ADDRESS, deployer); + const usdc = TokenInterface__factory.connect(USDC, deployer); + const compoundUSDCPool = IComet__factory.connect(COMPOUND_USDC_POOL, deployer); + const compoundWETHPool = IComet__factory.connect(COMPOUND_WETH_POOL, deployer); + + const MockToken = await ethers.getContractFactory("MockToken"); + const mockToken = await MockToken.deploy(); + await mockToken.mint(deployer.address, ethers.utils.parseEther("10000")); + + return { + compoundSupplyAdapter: CompoundSupply__factory.connect( + compoundSupplyAdapter.address, + deployer + ), + batchTransaction: BatchTransaction__factory.connect( + batchTransaction.address, + deployer + ), + weth, + cWeth, + usdc, + cUSDC, + compoundUSDCPool, + compoundWETHPool, + mockAssetForwarder: MockAssetForwarder__factory.connect( + mockAssetForwarder.address, + deployer + ), + mockToken: TokenInterface__factory.connect(mockToken.address, deployer), + }; + }; + + beforeEach(async function () { + await hardhat.network.provider.request({ + method: "hardhat_reset", + params: [ + { + forking: { + jsonRpcUrl: RPC[CHAIN_ID], + }, + }, + ], + }); + }); + + it("Can supply native tokens on Compound weth market", async () => { + const { compoundSupplyAdapter, cWeth } = await setupTests(); + + const amount = ethers.utils.parseEther("1"); + + const data = defaultAbiCoder.encode( + ["address", "address", "uint256","address"], + [NATIVE_TOKEN, deployer.address, amount,WETH] + ); + + const userBalBefore = await cWeth.balanceOf(deployer.address); + await compoundSupplyAdapter.execute(zeroAddress(), zeroAddress(), data, { + gasLimit: 10000000, + value: amount, + }); + + const userBalAfter = await cWeth.balanceOf(deployer.address); + + expect(userBalBefore).eq(0); + expect(userBalAfter).gt(0); + }); + + it("Can supply native tokens on Compound usdc market", async () => { + const { compoundSupplyAdapter, cWeth, compoundUSDCPool} = await setupTests(); + + const amount = ethers.utils.parseEther("1"); + + const data = defaultAbiCoder.encode( + ["address", "address", "uint256","address"], + [NATIVE_TOKEN, deployer.address, amount, USDC] + ); + + await compoundSupplyAdapter.execute(zeroAddress(), zeroAddress(), data, { + gasLimit: 10000000, + value: amount, + }); + + const collateralBal = await compoundUSDCPool.collateralBalanceOf(deployer.address, WETH); + + expect(collateralBal).gt(0); + }); + + it("Can supply non-native tokens on Compound weth market", async () => { + const { compoundSupplyAdapter, weth, cWeth } = await setupTests(); + + const amount = ethers.utils.parseEther("1"); + await weth.deposit({ value: amount }); + expect(await weth.balanceOf(deployer.address)).eq(amount); + + await weth.approve(compoundSupplyAdapter.address, amount); + const data = defaultAbiCoder.encode( + ["address", "address", "uint256", "address"], + [weth.address, deployer.address, amount, WETH] + ); + + const userBalBefore = await cWeth.balanceOf(deployer.address); + await compoundSupplyAdapter.execute(zeroAddress(), zeroAddress(), data, { + gasLimit: 10000000, + }); + const userBalAfter = await cWeth.balanceOf(deployer.address); + + expect(userBalBefore).eq(0); + expect(userBalAfter).gt(0); + }); + + it("Can supply non-native tokens on Compound usdc market", async () => { + const { compoundSupplyAdapter, weth, cWeth, compoundUSDCPool } = await setupTests(); + + const amount = ethers.utils.parseEther("1"); + await weth.deposit({ value: amount }); + expect(await weth.balanceOf(deployer.address)).eq(amount); + + await weth.approve(compoundSupplyAdapter.address, amount); + const data = defaultAbiCoder.encode( + ["address", "address", "uint256", "address"], + [weth.address, deployer.address, amount, USDC] + ); + + const userBalBefore = await cWeth.balanceOf(deployer.address); + await compoundSupplyAdapter.execute(zeroAddress(), zeroAddress(), data, { + gasLimit: 10000000, + }); + const collateralBal = await compoundUSDCPool.collateralBalanceOf(deployer.address, WETH); + + expect(collateralBal).gt(0); + }); + + it("Cannot supply unsupported tokens on Compound weth market", async () => { + const { compoundSupplyAdapter, mockToken } = await setupTests(); + + const amount = ethers.utils.parseEther("1"); + await mockToken.approve(compoundSupplyAdapter.address, amount); + + const data = defaultAbiCoder.encode( + ["address", "address", "uint256", "address"], + [mockToken.address, deployer.address, amount, WETH] + ); + + await expect( + compoundSupplyAdapter.execute(zeroAddress(), zeroAddress(), data, { + gasLimit: 10000000, + }) + ).to.be.reverted; + }); + + it("Cannot supply unsupported tokens on Compound usdc market", async () => { + const { compoundSupplyAdapter, mockToken } = await setupTests(); + + const amount = ethers.utils.parseEther("1"); + await mockToken.approve(compoundSupplyAdapter.address, amount); + + const data = defaultAbiCoder.encode( + ["address", "address", "uint256", "address"], + [mockToken.address, deployer.address, amount, USDC] + ); + + await expect( + compoundSupplyAdapter.execute(zeroAddress(), zeroAddress(), data, { + gasLimit: 10000000, + }) + ).to.be.reverted; + }); + + it("Cannot supply tokens on Compound- unsupported market", async () => { + const { compoundSupplyAdapter, mockToken } = await setupTests(); + + const amount = ethers.utils.parseEther("1"); + + const data = defaultAbiCoder.encode( + ["address", "address", "uint256", "address"], + [NATIVE_TOKEN, deployer.address, amount, NATIVE_TOKEN] + ); + + await expect( + compoundSupplyAdapter.execute(zeroAddress(), zeroAddress(), data, { + gasLimit: 10000000, + }) + ).to.be.reverted; + }); + + it("Can supply native tokens cross-chain on Compound weth market when handleMessage is called directly on adapter", async () => { + const { compoundSupplyAdapter, cWeth, mockAssetForwarder } = + await setupTests(); + + const amount = ethers.utils.parseEther("1"); + + const instruction = defaultAbiCoder.encode(["address","address"], [deployer.address, WETH]); + + const userBalBefore = await cWeth.balanceOf(deployer.address); + await mockAssetForwarder.handleMessage( + NATIVE_TOKEN, + amount, + instruction, + compoundSupplyAdapter.address, + { + gasLimit: 10000000, + value: amount, + } + ); + + const userBalAfter = await cWeth.balanceOf(deployer.address); + + expect(userBalBefore).eq(0); + expect(userBalAfter).gt(0); + }); + + it("Can supply native tokens cross-chain on Compound usdc market when handleMessage is called directly on adapter", async () => { + const { compoundSupplyAdapter, cWeth, mockAssetForwarder, compoundUSDCPool } = + await setupTests(); + + const amount = ethers.utils.parseEther("1"); + + const instruction = defaultAbiCoder.encode(["address","address"], [deployer.address, USDC]); + + await mockAssetForwarder.handleMessage( + NATIVE_TOKEN, + amount, + instruction, + compoundSupplyAdapter.address, + { + gasLimit: 10000000, + value: amount, + } + ); + + const collateralBal = await compoundUSDCPool.collateralBalanceOf(deployer.address, WETH); + + expect(collateralBal).gt(0); + }); + + it("Can supply non-native tokens cross-chain on Compound weth market when handleMessage is called directly on adapter", async () => { + const { compoundSupplyAdapter, weth, cWeth, mockAssetForwarder } = + await setupTests(); + + const amount = ethers.utils.parseEther("1"); + await weth.deposit({ value: amount }); + expect(await weth.balanceOf(deployer.address)).eq(amount); + + await weth.approve(mockAssetForwarder.address, amount); + + const instruction = defaultAbiCoder.encode(["address", "address"], [deployer.address, WETH]); + + const userBalBefore = await cWeth.balanceOf(deployer.address); + await mockAssetForwarder.handleMessage( + WETH, + amount, + instruction, + compoundSupplyAdapter.address + ); + + const userBalAfter = await cWeth.balanceOf(deployer.address); + + expect(userBalBefore).eq(0); + expect(userBalAfter).gt(0); + }); + + it("Can supply non-native tokens cross-chain on Compound usdc market when handleMessage is called directly on adapter", async () => { + const { compoundSupplyAdapter, weth, cWeth, mockAssetForwarder, compoundUSDCPool } = + await setupTests(); + + const amount = ethers.utils.parseEther("1"); + await weth.deposit({ value: amount }); + expect(await weth.balanceOf(deployer.address)).eq(amount); + + await weth.approve(mockAssetForwarder.address, amount); + + const instruction = defaultAbiCoder.encode(["address", "address"], [deployer.address, USDC]); + + await mockAssetForwarder.handleMessage( + WETH, + amount, + instruction, + compoundSupplyAdapter.address + ); + + const collateralBal = await compoundUSDCPool.collateralBalanceOf(deployer.address, WETH); + + expect(collateralBal).gt(0); + }); + + it("Can get a refund if unsupported token is being supplied cross-chain on Compound wethmarket when handleMessage is called directly on adapter", async () => { + const { compoundSupplyAdapter, mockToken, mockAssetForwarder } = + await setupTests(); + + const amount = ethers.utils.parseEther("1"); + await mockToken.approve(mockAssetForwarder.address, amount); + + const instruction = defaultAbiCoder.encode(["address", "address"], [alice.address, WETH]); + + const callerBalBefore = await mockToken.balanceOf(deployer.address); + const recipientBalBefore = await mockToken.balanceOf(alice.address); + + expect( + await mockAssetForwarder.handleMessage( + mockToken.address, + amount, + instruction, + compoundSupplyAdapter.address + ) + ).to.emit("OperationFailedRefundEvent"); + + const callerBalAfter = await mockToken.balanceOf(deployer.address); + const recipientBalAfter = await mockToken.balanceOf(alice.address); + + expect(callerBalAfter).lt(callerBalBefore); + expect(recipientBalAfter).gt(recipientBalBefore); + }); + + it("Can get a refund if unsupported token is being supplied cross-chain on Compound usdc market when handleMessage is called directly on adapter", async () => { + const { compoundSupplyAdapter, mockToken, mockAssetForwarder } = + await setupTests(); + + const amount = ethers.utils.parseEther("1"); + await mockToken.approve(mockAssetForwarder.address, amount); + + const instruction = defaultAbiCoder.encode(["address", "address"], [alice.address, USDC]); + + const callerBalBefore = await mockToken.balanceOf(deployer.address); + const recipientBalBefore = await mockToken.balanceOf(alice.address); + + expect( + await mockAssetForwarder.handleMessage( + mockToken.address, + amount, + instruction, + compoundSupplyAdapter.address + ) + ).to.emit("OperationFailedRefundEvent"); + + const callerBalAfter = await mockToken.balanceOf(deployer.address); + const recipientBalAfter = await mockToken.balanceOf(alice.address); + + expect(callerBalAfter).lt(callerBalBefore); + expect(recipientBalAfter).gt(recipientBalBefore); + }); + + it("Can get a refund if tried to supply on unsupported market on Compound when handleMessage is called directly on adapter", async () => { + const { compoundSupplyAdapter, mockToken, mockAssetForwarder } = + await setupTests(); + + const amount = ethers.utils.parseEther("1"); + + const instruction = defaultAbiCoder.encode(["address", "address"], [alice.address, NATIVE_TOKEN]); + + const callerBalBefore = await mockToken.balanceOf(deployer.address); + const recipientBalBefore = await mockToken.balanceOf(alice.address); + + await expect( + mockAssetForwarder.handleMessage( + NATIVE_TOKEN, + amount, + instruction, + compoundSupplyAdapter.address + ) + ).to.be.reverted; + }); + + it("Can supply native tokens on Compound weth market using BatchTransaction flow", async () => { + const { compoundSupplyAdapter, cWeth, batchTransaction } = + await setupTests(); + + const amount = ethers.utils.parseEther("1"); + + const compoundSupplyData = defaultAbiCoder.encode( + ["address", "address", "uint256", "address"], + [NATIVE_TOKEN, alice.address, amount, WETH] + ); + + const tokens = [NATIVE_TOKEN]; + const amounts = [amount]; + const targets = [compoundSupplyAdapter.address]; + const data = [compoundSupplyData]; + const value = [0]; + const callType = [2]; + + const userBalBefore = await cWeth.balanceOf(alice.address); + await batchTransaction.executeBatchCallsSameChain( + tokens, + amounts, + targets, + value, + callType, + data, + { value: amount } + ); + + const userBalAfter = await cWeth.balanceOf(alice.address); + + expect(userBalBefore).eq(0); + expect(userBalAfter).gt(0); + }); + + it("Can supply native tokens on Compound usdc market using BatchTransaction flow", async () => { + const { compoundSupplyAdapter, cWeth, batchTransaction , compoundUSDCPool} = + await setupTests(); + + const amount = ethers.utils.parseEther("1"); + + const compoundSupplyData = defaultAbiCoder.encode( + ["address", "address", "uint256", "address"], + [NATIVE_TOKEN, alice.address, amount, USDC] + ); + + const tokens = [NATIVE_TOKEN]; + const amounts = [amount]; + const targets = [compoundSupplyAdapter.address]; + const data = [compoundSupplyData]; + const value = [0]; + const callType = [2]; + + await batchTransaction.executeBatchCallsSameChain( + tokens, + amounts, + targets, + value, + callType, + data, + { value: amount } + ); + + const collateralBal = await compoundUSDCPool.collateralBalanceOf(alice.address, WETH); + + expect(collateralBal).gt(0); + }); + + it("Can supply non-native tokens on Compound weth market using BatchTransaction flow", async () => { + const { compoundSupplyAdapter, weth, cWeth, batchTransaction } = + await setupTests(); + + const amount = ethers.utils.parseEther("1"); + await weth.deposit({ value: amount }); + expect(await weth.balanceOf(deployer.address)).eq(amount); + + await weth.approve(batchTransaction.address, amount); + + const compoundSupplyData = defaultAbiCoder.encode( + ["address", "address", "uint256", "address"], + [WETH, alice.address, amount, WETH] + ); + + const tokens = [WETH]; + const amounts = [amount]; + const targets = [compoundSupplyAdapter.address]; + const data = [compoundSupplyData]; + const value = [0]; + const callType = [2]; + + const userBalBefore = await cWeth.balanceOf(alice.address); + await batchTransaction.executeBatchCallsSameChain( + tokens, + amounts, + targets, + value, + callType, + data + ); + + const userBalAfter = await cWeth.balanceOf(alice.address); + + expect(userBalBefore).eq(0); + expect(userBalAfter).gt(0); + }); + + it("Can supply non-native tokens on Compound usdc market using BatchTransaction flow", async () => { + const { compoundSupplyAdapter, weth, cWeth, batchTransaction, compoundUSDCPool } = + await setupTests(); + + const amount = ethers.utils.parseEther("1"); + await weth.deposit({ value: amount }); + expect(await weth.balanceOf(deployer.address)).eq(amount); + + await weth.approve(batchTransaction.address, amount); + + const compoundSupplyData = defaultAbiCoder.encode( + ["address", "address", "uint256", "address"], + [WETH, alice.address, amount, USDC] + ); + + const tokens = [WETH]; + const amounts = [amount]; + const targets = [compoundSupplyAdapter.address]; + const data = [compoundSupplyData]; + const value = [0]; + const callType = [2]; + + await batchTransaction.executeBatchCallsSameChain( + tokens, + amounts, + targets, + value, + callType, + data + ); + + const collateralBal = await compoundUSDCPool.collateralBalanceOf(alice.address, WETH); + + expect(collateralBal).gt(0); + }); + + it("Cannot supply unsupported tokens on Compound weth market using BatchTransaction flow", async () => { + const { compoundSupplyAdapter, mockToken, batchTransaction } = + await setupTests(); + + const amount = ethers.utils.parseEther("1"); + await mockToken.approve(batchTransaction.address, amount); + + const compoundSupplyData = defaultAbiCoder.encode( + ["address", "address", "uint256", "address"], + [mockToken.address, alice.address, amount , WETH] + ); + + const tokens = [mockToken.address]; + const amounts = [amount]; + const targets = [compoundSupplyAdapter.address]; + const data = [compoundSupplyData]; + const value = [0]; + const callType = [2]; + + await expect( + batchTransaction.executeBatchCallsSameChain( + tokens, + amounts, + targets, + value, + callType, + data + ) + ).to.be.reverted; + }); + + it("Cannot supply unsupported tokens on Compound usdc market using BatchTransaction flow", async () => { + const { compoundSupplyAdapter, mockToken, batchTransaction } = + await setupTests(); + + const amount = ethers.utils.parseEther("1"); + await mockToken.approve(batchTransaction.address, amount); + + const compoundSupplyData = defaultAbiCoder.encode( + ["address", "address", "uint256", "address"], + [mockToken.address, alice.address, amount , USDC] + ); + + const tokens = [mockToken.address]; + const amounts = [amount]; + const targets = [compoundSupplyAdapter.address]; + const data = [compoundSupplyData]; + const value = [0]; + const callType = [2]; + + await expect( + batchTransaction.executeBatchCallsSameChain( + tokens, + amounts, + targets, + value, + callType, + data + ) + ).to.be.reverted; + }); + + it("Cannot supply tokens on unsupported market on Compound using BatchTransaction flow", async () => { + const { compoundSupplyAdapter, cWeth, batchTransaction , compoundUSDCPool} = + await setupTests(); + + const amount = ethers.utils.parseEther("1"); + + const compoundSupplyData = defaultAbiCoder.encode( + ["address", "address", "uint256", "address"], + [NATIVE_TOKEN, alice.address, amount, NATIVE_TOKEN] + ); + + const tokens = [NATIVE_TOKEN]; + const amounts = [amount]; + const targets = [compoundSupplyAdapter.address]; + const data = [compoundSupplyData]; + const value = [0]; + const callType = [2]; + + await expect(batchTransaction.executeBatchCallsSameChain( + tokens, + amounts, + targets, + value, + callType, + data, + { value: amount } + )).to.be.reverted; + }); + + it("Can supply native tokens cross-chain on Compound weth market using BatchTransaction flow", async () => { + const { + compoundSupplyAdapter, + mockAssetForwarder, + cWeth, + batchTransaction, + } = await setupTests(); + + const amount = ethers.utils.parseEther("1"); + + const compoundSupplyData = defaultAbiCoder.encode( + ["address", "address", "uint256", "address"], + [NATIVE_TOKEN, alice.address, amount, WETH] + ); + + const targets = [compoundSupplyAdapter.address]; + const data = [compoundSupplyData]; + const value = [0]; + const callType = [2]; + + const assetForwarderData = defaultAbiCoder.encode( + ["address", "address[]", "uint256[]", "uint256[]", "bytes[]"], + [deployer.address, targets, value, callType, data] + ); + + const userBalBefore = await cWeth.balanceOf(alice.address); + await mockAssetForwarder.handleMessage( + NATIVE_TOKEN, + amount, + assetForwarderData, + batchTransaction.address, + { value: amount, gasLimit: 10000000 } + ); + const userBalAfter = await cWeth.balanceOf(alice.address); + + expect(userBalBefore).eq(0); + expect(userBalAfter).gt(0); + }); + + it("Can supply native tokens cross-chain on Compound usdc market using BatchTransaction flow", async () => { + const { + compoundSupplyAdapter, + mockAssetForwarder, + cWeth, + batchTransaction, + compoundUSDCPool + } = await setupTests(); + + const amount = ethers.utils.parseEther("1"); + + const compoundSupplyData = defaultAbiCoder.encode( + ["address", "address", "uint256", "address"], + [NATIVE_TOKEN, alice.address, amount, USDC] + ); + + const targets = [compoundSupplyAdapter.address]; + const data = [compoundSupplyData]; + const value = [0]; + const callType = [2]; + + const assetForwarderData = defaultAbiCoder.encode( + ["address", "address[]", "uint256[]", "uint256[]", "bytes[]"], + [deployer.address, targets, value, callType, data] + ); + await mockAssetForwarder.handleMessage( + NATIVE_TOKEN, + amount, + assetForwarderData, + batchTransaction.address, + { value: amount, gasLimit: 10000000 } + ); + + const collateralBal = await compoundUSDCPool.collateralBalanceOf(alice.address, WETH); + + expect(collateralBal).gt(0); + }); + + it("Can supply non-native tokens cross-chain on Compound weth market using BatchTransaction flow", async () => { + const { + compoundSupplyAdapter, + mockAssetForwarder, + weth, + cWeth, + batchTransaction, + } = await setupTests(); + + const amount = ethers.utils.parseEther("1"); + await weth.deposit({ value: amount }); + expect(await weth.balanceOf(deployer.address)).eq(amount); + + await weth.approve(mockAssetForwarder.address, amount); + + const compoundSupplyData = defaultAbiCoder.encode( + ["address", "address", "uint256", "address"], + [weth.address, alice.address, amount, WETH] + ); + + const targets = [compoundSupplyAdapter.address]; + const data = [compoundSupplyData]; + const value = [0]; + const callType = [2]; + + const assetForwarderData = defaultAbiCoder.encode( + ["address", "address[]", "uint256[]", "uint256[]", "bytes[]"], + [deployer.address, targets, value, callType, data] + ); + + const userBalBefore = await cWeth.balanceOf(alice.address); + await mockAssetForwarder.handleMessage( + weth.address, + amount, + assetForwarderData, + batchTransaction.address, + { value: amount, gasLimit: 10000000 } + ); + const userBalAfter = await cWeth.balanceOf(alice.address); + + expect(userBalBefore).eq(0); + expect(userBalAfter).gt(0); + }); + + it("Can supply non-native tokens cross-chain on Compound usdc market using BatchTransaction flow", async () => { + const { + compoundSupplyAdapter, + mockAssetForwarder, + weth, + cWeth, + batchTransaction, + compoundUSDCPool + } = await setupTests(); + + const amount = ethers.utils.parseEther("1"); + await weth.deposit({ value: amount }); + expect(await weth.balanceOf(deployer.address)).eq(amount); + + await weth.approve(mockAssetForwarder.address, amount); + + const compoundSupplyData = defaultAbiCoder.encode( + ["address", "address", "uint256", "address"], + [weth.address, alice.address, amount, USDC] + ); + + const targets = [compoundSupplyAdapter.address]; + const data = [compoundSupplyData]; + const value = [0]; + const callType = [2]; + + const assetForwarderData = defaultAbiCoder.encode( + ["address", "address[]", "uint256[]", "uint256[]", "bytes[]"], + [deployer.address, targets, value, callType, data] + ); + + await mockAssetForwarder.handleMessage( + weth.address, + amount, + assetForwarderData, + batchTransaction.address, + { value: amount, gasLimit: 10000000 } + ); + + const collateralBal = await compoundUSDCPool.collateralBalanceOf(alice.address, WETH); + + expect(collateralBal).gt(0); + }); + + it("Can get a refund if supply unsupported tokens cross-chain on Compound weth market using BatchTransaction flow", async () => { + const { + compoundSupplyAdapter, + mockAssetForwarder, + mockToken, + cWeth, + batchTransaction, + } = await setupTests(); + + const amount = ethers.utils.parseEther("1"); + await mockToken.approve(mockAssetForwarder.address, amount); + + const compoundSupplyData = defaultAbiCoder.encode( + ["address", "address", "uint256", "address"], + [mockToken.address, alice.address, amount, WETH] + ); + + const targets = [compoundSupplyAdapter.address]; + const data = [compoundSupplyData]; + const value = [0]; + const callType = [2]; + + const assetForwarderData = defaultAbiCoder.encode( + ["address", "address[]", "uint256[]", "uint256[]", "bytes[]"], + [deployer.address, targets, value, callType, data] + ); + + const recipientBalBefore = await cWeth.balanceOf(alice.address); + const userMockTokenBalBefore = await mockToken.balanceOf(deployer.address); + + expect( + await mockAssetForwarder.handleMessage( + mockToken.address, + amount, + assetForwarderData, + batchTransaction.address, + { value: amount, gasLimit: 10000000 } + ) + ).to.emit("OperationFailedRefundEvent"); + + const recipientBalAfter = await cWeth.balanceOf(alice.address); + const userMockTokenBalAfter = await mockToken.balanceOf(deployer.address); + + expect(recipientBalAfter).eq(recipientBalBefore); + expect(userMockTokenBalAfter).eq(userMockTokenBalBefore); + }); + + it("Can get a refund if supply unsupported tokens cross-chain on Compound usdc market using BatchTransaction flow", async () => { + const { + compoundSupplyAdapter, + mockAssetForwarder, + mockToken, + cWeth, + batchTransaction, + } = await setupTests(); + + const amount = ethers.utils.parseEther("1"); + await mockToken.approve(mockAssetForwarder.address, amount); + + const compoundSupplyData = defaultAbiCoder.encode( + ["address", "address", "uint256", "address"], + [mockToken.address, alice.address, amount, USDC] + ); + + const targets = [compoundSupplyAdapter.address]; + const data = [compoundSupplyData]; + const value = [0]; + const callType = [2]; + + const assetForwarderData = defaultAbiCoder.encode( + ["address", "address[]", "uint256[]", "uint256[]", "bytes[]"], + [deployer.address, targets, value, callType, data] + ); + + const recipientBalBefore = await cWeth.balanceOf(alice.address); + const userMockTokenBalBefore = await mockToken.balanceOf(deployer.address); + + expect( + await mockAssetForwarder.handleMessage( + mockToken.address, + amount, + assetForwarderData, + batchTransaction.address, + { value: amount, gasLimit: 10000000 } + ) + ).to.emit("OperationFailedRefundEvent"); + + const recipientBalAfter = await cWeth.balanceOf(alice.address); + const userMockTokenBalAfter = await mockToken.balanceOf(deployer.address); + + expect(recipientBalAfter).eq(recipientBalBefore); + expect(userMockTokenBalAfter).eq(userMockTokenBalBefore); + }); + + it("Cannot supply non-native tokens cross-chain on Compound unsupported market using BatchTransaction flow", async () => { + const { + compoundSupplyAdapter, + mockAssetForwarder, + weth, + cWeth, + batchTransaction, + } = await setupTests(); + + const amount = ethers.utils.parseEther("1"); + await weth.deposit({ value: amount }); + expect(await weth.balanceOf(deployer.address)).eq(amount); + + await weth.approve(mockAssetForwarder.address, amount); + + const compoundSupplyData = defaultAbiCoder.encode( + ["address", "address", "uint256", "address"], + [weth.address, alice.address, amount, NATIVE_TOKEN] + ); + + const targets = [compoundSupplyAdapter.address]; + const data = [compoundSupplyData]; + const value = [0]; + const callType = [2]; + + const assetForwarderData = defaultAbiCoder.encode( + ["address", "address[]", "uint256[]", "uint256[]", "bytes[]"], + [deployer.address, targets, value, callType, data] + ); + + expect( + await mockAssetForwarder.handleMessage( + weth.address, + amount, + assetForwarderData, + batchTransaction.address, + { value: amount, gasLimit: 10000000 } + )).to.emit("OperationFailedRefundEvent"); + }); +}); diff --git a/evm/test/DexSpanAdapter/DexSpanAdapter.specs.ts b/evm/test/DexSpanAdapter/DexSpanAdapter.specs.ts new file mode 100644 index 0000000..a50826b --- /dev/null +++ b/evm/test/DexSpanAdapter/DexSpanAdapter.specs.ts @@ -0,0 +1,226 @@ +import hardhat, { ethers, waffle } from "hardhat"; +import { expect } from "chai"; +import { RPC } from "../constants"; +import { + DEXSPAN, + DEFAULT_ENV, + NATIVE, + WNATIVE, + DEFAULT_REFUND_ADDRESS, +} from "../../tasks/constants"; +import { DexSpanAdapter__factory } from "../../typechain/factories/DexSpanAdapter__factory"; +import { TokenInterface__factory } from "../../typechain/factories/TokenInterface__factory"; +import { MockAssetForwarder__factory } from "../../typechain/factories/MockAssetForwarder__factory"; +import { BatchTransaction__factory } from "../../typechain/factories/BatchTransaction__factory"; +import { BigNumber, Contract, Wallet } from "ethers"; +import { decodeUnsupportedOperationEvent, getPathfinderData } from "../utils"; +import { defaultAbiCoder } from "ethers/lib/utils"; + +const CHAIN_ID = "80001"; +const NATIVE_TOKEN = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"; +const USDT = "0x22bAA8b6cdd31a0C5D1035d6e72043f4Ce6aF054"; + +describe("DexSpan Adapter: ", async () => { + const [deployer] = waffle.provider.getWallets(); + + const setupTests = async () => { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + const MockAssetForwarder = await ethers.getContractFactory( + "MockAssetForwarder" + ); + const mockAssetForwarder = await MockAssetForwarder.deploy(); + + const BatchTransaction = await ethers.getContractFactory( + "BatchTransaction" + ); + + const batchTransaction = await BatchTransaction.deploy( + NATIVE, + WNATIVE[env][CHAIN_ID], + mockAssetForwarder.address, + DEXSPAN[env][CHAIN_ID] + ); + + const DexSpanAdapter = await ethers.getContractFactory("DexSpanAdapter"); + const dexSpanAdapter = await DexSpanAdapter.deploy( + NATIVE, + WNATIVE[env][CHAIN_ID], + deployer.address, + mockAssetForwarder.address, + DEXSPAN[env][CHAIN_ID], + DEFAULT_REFUND_ADDRESS + ); + + return { + batchTransaction: BatchTransaction__factory.connect( + batchTransaction.address, + deployer + ), + dexSpanAdapter: DexSpanAdapter__factory.connect( + dexSpanAdapter.address, + deployer + ), + mockAssetForwarder: MockAssetForwarder__factory.connect( + mockAssetForwarder.address, + deployer + ), + usdt: TokenInterface__factory.connect(USDT, deployer), + }; + }; + + beforeEach(async function () { + await hardhat.network.provider.request({ + method: "hardhat_reset", + params: [ + { + forking: { + jsonRpcUrl: RPC[CHAIN_ID], + }, + }, + ], + }); + }); + + const toBytes32 = (bn: BigNumber) => { + return ethers.utils.hexlify(ethers.utils.zeroPad(bn.toHexString(), 32)); + }; + + // This works for token when it has balance mapping at slot 0. + const setUserTokenBalance = async ( + contract: Contract, + user: Wallet, + balance: BigNumber + ) => { + const index = ethers.utils.solidityKeccak256( + ["uint256", "uint256"], + [user.address, 0] // key, slot + ); + + await hardhat.network.provider.request({ + method: "hardhat_setStorageAt", + params: [contract.address, index, toBytes32(balance).toString()], + }); + + await hardhat.network.provider.request({ + method: "evm_mine", + params: [], + }); + }; + + it("Can swap using dexspan on same chain", async () => { + const { batchTransaction, dexSpanAdapter, usdt } = await setupTests(); + + await setUserTokenBalance(usdt, deployer, ethers.utils.parseEther("1")); + + const amount = "10000000000000"; + await usdt.approve(batchTransaction.address, amount); + + const { data: swapData } = await getPathfinderData( + usdt.address, + NATIVE_TOKEN, + amount, + CHAIN_ID, + CHAIN_ID, + deployer.address + ); + + const tokens = [usdt.address]; + const amounts = [amount]; + const targets = [dexSpanAdapter.address]; + const data = [swapData]; + const value = [0]; + const callType = [2]; + + const balBefore = await ethers.provider.getBalance(deployer.address); + + await batchTransaction.executeBatchCallsSameChain( + tokens, + amounts, + targets, + value, + callType, + data + ); + + const balAfter = await ethers.provider.getBalance(deployer.address); + + expect(balAfter).gt(balBefore); + }); + + it("Can swap using dexspan on dest chain when instruction is received from BatchTransaction contract", async () => { + const { batchTransaction, dexSpanAdapter, usdt, mockAssetForwarder } = + await setupTests(); + + await setUserTokenBalance(usdt, deployer, ethers.utils.parseEther("1")); + + const amount = "10000000000000"; + await usdt.approve(mockAssetForwarder.address, amount); + + const { data: swapData } = await getPathfinderData( + usdt.address, + NATIVE_TOKEN, + amount, + CHAIN_ID, + CHAIN_ID, + deployer.address + ); + + const targets = [dexSpanAdapter.address]; + const data = [swapData]; + const value = [0]; + const callType = [2]; + + const assetForwarderData = defaultAbiCoder.encode( + ["address", "address[]", "uint256[]", "uint256[]", "bytes[]"], + [deployer.address, targets, value, callType, data] + ); + + const balBefore = await ethers.provider.getBalance(deployer.address); + + await mockAssetForwarder.handleMessage( + usdt.address, + amount, + assetForwarderData, + batchTransaction.address + ); + + const balAfter = await ethers.provider.getBalance(deployer.address); + + expect(balAfter).gt(balBefore); + }); + + it("Cannot swap using dexspan on dest chain when instruction is received directly on dexspan adapter", async () => { + const { dexSpanAdapter, usdt, mockAssetForwarder } = await setupTests(); + + await setUserTokenBalance(usdt, deployer, ethers.utils.parseEther("1")); + + const amount = "10000000000000"; + await usdt.approve(mockAssetForwarder.address, amount); + + const { data: swapData } = await getPathfinderData( + usdt.address, + NATIVE_TOKEN, + amount, + CHAIN_ID, + CHAIN_ID, + deployer.address + ); + + const tx = await mockAssetForwarder.handleMessage( + usdt.address, + amount, + swapData, + dexSpanAdapter.address + ); + + const txReceipt = await tx.wait(); + + const { token, refundAddress, refundAmount } = + decodeUnsupportedOperationEvent(txReceipt); + + expect(token).eq(usdt.address); + expect(refundAddress).eq(DEFAULT_REFUND_ADDRESS); + expect(refundAmount).eq(amount); + }); +}); diff --git a/evm/test/Frax/FraxStakeEth.specs.ts b/evm/test/Frax/FraxStakeEth.specs.ts new file mode 100644 index 0000000..315b4f2 --- /dev/null +++ b/evm/test/Frax/FraxStakeEth.specs.ts @@ -0,0 +1,382 @@ +import hardhat, { ethers, waffle } from "hardhat"; +import { expect } from "chai"; +import { RPC } from "../constants"; +import { + DEXSPAN, + DEFAULT_ENV, + NATIVE, + WNATIVE, + DEFAULT_REFUND_ADDRESS, +} from "../../tasks/constants"; +import { FraxStakeEth__factory } from "../../typechain/factories/FraxStakeEth__factory"; +import { TokenInterface__factory } from "../../typechain/factories/TokenInterface__factory"; +import { MockAssetForwarder__factory } from "../../typechain/factories/MockAssetForwarder__factory"; +import { BatchTransaction__factory } from "../../typechain/factories/BatchTransaction__factory"; +import { BigNumber, Contract, Wallet } from "ethers"; +import { getPathfinderData } from "../utils"; +import { defaultAbiCoder } from "ethers/lib/utils"; +import { DexSpanAdapter__factory } from "../../typechain/factories/DexSpanAdapter__factory"; + +const CHAIN_ID = "1"; +const FRAX_ETH_TOKEN = "0x5E8422345238F34275888049021821E8E08CAa1f"; +const S_FRAX_ETH_TOKEN = "0xac3E018457B222d93114458476f3E3416Abbe38F"; +const FRAX_POOL = "0xbAFA44EFE7901E04E39Dad13167D089C559c1138"; +const NATIVE_TOKEN = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"; +const USDT = "0xdac17f958d2ee523a2206206994597c13d831ec7"; + +describe("FraxStakeEth Adapter: ", async () => { + const [deployer] = waffle.provider.getWallets(); + + const setupTests = async () => { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + const MockAssetForwarder = await ethers.getContractFactory( + "MockAssetForwarder" + ); + const mockAssetForwarder = await MockAssetForwarder.deploy(); + + const BatchTransaction = await ethers.getContractFactory( + "BatchTransaction" + ); + + const batchTransaction = await BatchTransaction.deploy( + NATIVE, + WNATIVE[env][CHAIN_ID], + mockAssetForwarder.address, + DEXSPAN[env][CHAIN_ID] + ); + + const DexSpanAdapter = await ethers.getContractFactory("DexSpanAdapter"); + const dexSpanAdapter = await DexSpanAdapter.deploy( + NATIVE, + WNATIVE[env][CHAIN_ID], + deployer.address, + mockAssetForwarder.address, + DEXSPAN[env][CHAIN_ID], + DEFAULT_REFUND_ADDRESS + ); + + const FraxStakeEth = await ethers.getContractFactory("FraxStakeEth"); + const fraxStakeEthAdapter = await FraxStakeEth.deploy( + NATIVE, + WNATIVE[env][CHAIN_ID], + deployer.address, + mockAssetForwarder.address, + DEXSPAN[env][CHAIN_ID], + FRAX_ETH_TOKEN, + S_FRAX_ETH_TOKEN, + FRAX_POOL + ); + + return { + batchTransaction: BatchTransaction__factory.connect( + batchTransaction.address, + deployer + ), + fraxStakeEthAdapter: FraxStakeEth__factory.connect( + fraxStakeEthAdapter.address, + deployer + ), + dexSpanAdapter: DexSpanAdapter__factory.connect( + dexSpanAdapter.address, + deployer + ), + mockAssetForwarder: MockAssetForwarder__factory.connect( + mockAssetForwarder.address, + deployer + ), + usdt: TokenInterface__factory.connect(USDT, deployer), + fraxEth: TokenInterface__factory.connect(FRAX_ETH_TOKEN, deployer), + sFraxEth: TokenInterface__factory.connect(S_FRAX_ETH_TOKEN, deployer), + }; + }; + + beforeEach(async function () { + await hardhat.network.provider.request({ + method: "hardhat_reset", + params: [ + { + forking: { + jsonRpcUrl: RPC[CHAIN_ID], + }, + }, + ], + }); + }); + + const toBytes32 = (bn: BigNumber) => { + return ethers.utils.hexlify(ethers.utils.zeroPad(bn.toHexString(), 32)); + }; + + // This works for token when it has balance mapping at slot 0. + const setUserTokenBalance = async ( + contract: Contract, + user: Wallet, + balance: BigNumber + ) => { + const index = ethers.utils.solidityKeccak256( + ["uint256", "uint256"], + [user.address, 0] // key, slot + ); + + await hardhat.network.provider.request({ + method: "hardhat_setStorageAt", + params: [contract.address, index, toBytes32(balance).toString()], + }); + + await hardhat.network.provider.request({ + method: "evm_mine", + params: [], + }); + }; + + it("FRAX_ETH: Can stake on frax on same chain", async () => { + const { batchTransaction, fraxStakeEthAdapter, fraxEth } = + await setupTests(); + + const amount = ethers.utils.parseEther("1"); + const txType = "1"; + + const fraxData = defaultAbiCoder.encode( + ["address", "uint256", "uint256"], + [deployer.address, amount, txType] + ); + + const tokens = [NATIVE_TOKEN]; + const amounts = [amount]; + const targets = [fraxStakeEthAdapter.address]; + const data = [fraxData]; + const value = [0]; + const callType = [2]; + + const balBefore = await ethers.provider.getBalance(deployer.address); + const fraxEthBalBefore = await fraxEth.balanceOf(deployer.address); + + await batchTransaction.executeBatchCallsSameChain( + tokens, + amounts, + targets, + value, + callType, + data, + { value: amount } + ); + + const balAfter = await ethers.provider.getBalance(deployer.address); + const fraxEthBalAfter = await fraxEth.balanceOf(deployer.address); + + expect(balBefore).gt(balAfter); + expect(fraxEthBalAfter).gt(fraxEthBalBefore); + }); + + it("FRAX_ETH: Can stake ETH on FRAX on dest chain when instruction is received from BatchTransaction contract", async () => { + const { + batchTransaction, + fraxStakeEthAdapter, + fraxEth, + mockAssetForwarder, + } = await setupTests(); + + const amount = "100000000000000000"; + const txType = "1"; + + const targets = [fraxStakeEthAdapter.address]; + const data = [ + defaultAbiCoder.encode( + ["address", "uint256", "uint256"], + [deployer.address, amount, txType] + ), + ]; + const value = [0]; + const callType = [2]; + + const assetForwarderData = defaultAbiCoder.encode( + ["address", "address[]", "uint256[]", "uint256[]", "bytes[]"], + [deployer.address, targets, value, callType, data] + ); + + const balBefore = await ethers.provider.getBalance(deployer.address); + const fraxEthBalBefore = await fraxEth.balanceOf(deployer.address); + + await mockAssetForwarder.handleMessage( + NATIVE_TOKEN, + amount, + assetForwarderData, + batchTransaction.address, + { value: amount } + ); + + const balAfter = await ethers.provider.getBalance(deployer.address); + const fraxEthBalAfter = await fraxEth.balanceOf(deployer.address); + + expect(balAfter).lt(balBefore); + expect(fraxEthBalAfter).gt(fraxEthBalBefore); + }); + + it("FRAX_ETH: Can stake ETH on FRAX on dest chain when instruction is received directly on FraxStakeEth adapter", async () => { + const { fraxStakeEthAdapter, fraxEth, mockAssetForwarder } = + await setupTests(); + + const amount = "100000000000000000"; + const txType = "1"; + + const data = defaultAbiCoder.encode(["address", "uint256"], [deployer.address, txType]); + + const balBefore = await ethers.provider.getBalance(deployer.address); + const fraxEthBalBefore = await fraxEth.balanceOf(deployer.address); + + await mockAssetForwarder.handleMessage( + NATIVE_TOKEN, + amount, + data, + fraxStakeEthAdapter.address, + { value: amount } + ); + + const balAfter = await ethers.provider.getBalance(deployer.address); + const fraxEthBalAfter = await fraxEth.balanceOf(deployer.address); + + expect(balAfter).lt(balBefore); + expect(fraxEthBalAfter).gt(fraxEthBalBefore); + }); + + it("SFRAX_ETH: Can stake on frax on same chain", async () => { + const { batchTransaction, fraxStakeEthAdapter, sFraxEth } = + await setupTests(); + + const amount = ethers.utils.parseEther("1"); + const txType = "2"; + + const fraxData = defaultAbiCoder.encode( + ["address", "uint256", "uint256"], + [deployer.address, amount, txType] + ); + + const tokens = [NATIVE_TOKEN]; + const amounts = [amount]; + const targets = [fraxStakeEthAdapter.address]; + const data = [fraxData]; + const value = [0]; + const callType = [2]; + + const balBefore = await ethers.provider.getBalance(deployer.address); + const sFraxEthBalBefore = await sFraxEth.balanceOf(deployer.address); + + await batchTransaction.executeBatchCallsSameChain( + tokens, + amounts, + targets, + value, + callType, + data, + { value: amount } + ); + + const balAfter = await ethers.provider.getBalance(deployer.address); + const sFraxEthBalAfter = await sFraxEth.balanceOf(deployer.address); + + expect(balBefore).gt(balAfter); + expect(sFraxEthBalAfter).gt(sFraxEthBalBefore); + }); + + it("SFRAX_ETH: Can stake ETH on FRAX on dest chain when instruction is received from BatchTransaction contract", async () => { + const { + batchTransaction, + fraxStakeEthAdapter, + sFraxEth, + mockAssetForwarder, + } = await setupTests(); + + const amount = "100000000000000000"; + const txType = "2"; + + const targets = [fraxStakeEthAdapter.address]; + const data = [ + defaultAbiCoder.encode( + ["address", "uint256", "uint256"], + [deployer.address, amount, txType] + ), + ]; + const value = [0]; + const callType = [2]; + + const assetForwarderData = defaultAbiCoder.encode( + ["address", "address[]", "uint256[]", "uint256[]", "bytes[]"], + [deployer.address, targets, value, callType, data] + ); + + const balBefore = await ethers.provider.getBalance(deployer.address); + const sFraxEthBalBefore = await sFraxEth.balanceOf(deployer.address); + + await mockAssetForwarder.handleMessage( + NATIVE_TOKEN, + amount, + assetForwarderData, + batchTransaction.address, + { value: amount } + ); + + const balAfter = await ethers.provider.getBalance(deployer.address); + const sFraxEthBalAfter = await sFraxEth.balanceOf(deployer.address); + + expect(balAfter).lt(balBefore); + expect(sFraxEthBalAfter).gt(sFraxEthBalBefore); + }); + + it("SFRAX_ETH: Can stake ETH on FRAX on dest chain when instruction is received directly on FraxStakeEth adapter", async () => { + const { fraxStakeEthAdapter, sFraxEth, mockAssetForwarder } = + await setupTests(); + + const amount = "100000000000000000"; + const txType = "2"; + + const data = defaultAbiCoder.encode(["address", "uint256"], [deployer.address, txType]); + + const balBefore = await ethers.provider.getBalance(deployer.address); + const sFraxEthBalBefore = await sFraxEth.balanceOf(deployer.address); + + await mockAssetForwarder.handleMessage( + NATIVE_TOKEN, + amount, + data, + fraxStakeEthAdapter.address, + { value: amount } + ); + + const balAfter = await ethers.provider.getBalance(deployer.address); + const sFraxEthBalAfter = await sFraxEth.balanceOf(deployer.address); + + expect(balAfter).lt(balBefore); + expect(sFraxEthBalAfter).gt(sFraxEthBalBefore); + }); + + it("CanNOT stake on frax on same chain if invalid txtype", async () => { + const { batchTransaction, fraxStakeEthAdapter, sFraxEth } = + await setupTests(); + + const amount = ethers.utils.parseEther("1"); + const txType = "3"; + + const fraxData = defaultAbiCoder.encode( + ["address", "uint256", "uint256"], + [deployer.address, amount, txType] + ); + + const tokens = [NATIVE_TOKEN]; + const amounts = [amount]; + const targets = [fraxStakeEthAdapter.address]; + const data = [fraxData]; + const value = [0]; + const callType = [2]; + + await expect(batchTransaction.executeBatchCallsSameChain( + tokens, + amounts, + targets, + value, + callType, + data, + { value: amount } + )).to.be.reverted; + }); +}); diff --git a/evm/test/Lido/LidoStakeEth.specs.ts b/evm/test/Lido/LidoStakeEth.specs.ts new file mode 100644 index 0000000..a8b8e3f --- /dev/null +++ b/evm/test/Lido/LidoStakeEth.specs.ts @@ -0,0 +1,203 @@ +import hardhat, { ethers, waffle } from "hardhat"; +import { expect } from "chai"; +import { RPC } from "../constants"; +import { + DEXSPAN, + DEFAULT_ENV, + NATIVE, + WNATIVE, + DEFAULT_REFUND_ADDRESS, +} from "../../tasks/constants"; +import { LidoStakeEth__factory } from "../../typechain/factories/LidoStakeEth__factory"; +import { TokenInterface__factory } from "../../typechain/factories/TokenInterface__factory"; +import { MockAssetForwarder__factory } from "../../typechain/factories/MockAssetForwarder__factory"; +import { BatchTransaction__factory } from "../../typechain/factories/BatchTransaction__factory"; +import { defaultAbiCoder } from "ethers/lib/utils"; +import { DexSpanAdapter__factory } from "../../typechain/factories/DexSpanAdapter__factory"; + +const CHAIN_ID = "5"; +const LIDO_ST_TOKEN = "0x1643E812aE58766192Cf7D2Cf9567dF2C37e9B7F"; +const LIDO_REFERRAL_ADDRESS = "0x1643E812aE58766192Cf7D2Cf9567dF2C37e9B7F"; +const NATIVE_TOKEN = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"; +const USDT = "0x2227E4764be4c858E534405019488D9E5890Ff9E"; + +describe("LidoStakeEth Adapter: ", async () => { + const [deployer] = waffle.provider.getWallets(); + + const setupTests = async () => { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + const MockAssetForwarder = await ethers.getContractFactory( + "MockAssetForwarder" + ); + const mockAssetForwarder = await MockAssetForwarder.deploy(); + + const BatchTransaction = await ethers.getContractFactory( + "BatchTransaction" + ); + + const batchTransaction = await BatchTransaction.deploy( + NATIVE, + WNATIVE[env][CHAIN_ID], + mockAssetForwarder.address, + DEXSPAN[env][CHAIN_ID] + ); + + const DexSpanAdapter = await ethers.getContractFactory("DexSpanAdapter"); + const dexSpanAdapter = await DexSpanAdapter.deploy( + NATIVE, + WNATIVE[env][CHAIN_ID], + deployer.address, + mockAssetForwarder.address, + DEXSPAN[env][CHAIN_ID], + DEFAULT_REFUND_ADDRESS + ); + + const LidoStakeEth = await ethers.getContractFactory("LidoStakeEth"); + const lidoStakeEthAdapter = await LidoStakeEth.deploy( + NATIVE, + WNATIVE[env][CHAIN_ID], + deployer.address, + mockAssetForwarder.address, + DEXSPAN[env][CHAIN_ID], + LIDO_ST_TOKEN, + LIDO_REFERRAL_ADDRESS + ); + + return { + batchTransaction: BatchTransaction__factory.connect( + batchTransaction.address, + deployer + ), + lidoStakeEthAdapter: LidoStakeEth__factory.connect( + lidoStakeEthAdapter.address, + deployer + ), + dexSpanAdapter: DexSpanAdapter__factory.connect( + dexSpanAdapter.address, + deployer + ), + mockAssetForwarder: MockAssetForwarder__factory.connect( + mockAssetForwarder.address, + deployer + ), + usdt: TokenInterface__factory.connect(USDT, deployer), + steth: TokenInterface__factory.connect(LIDO_ST_TOKEN, deployer), + }; + }; + + beforeEach(async function () { + await hardhat.network.provider.request({ + method: "hardhat_reset", + params: [ + { + forking: { + jsonRpcUrl: RPC[CHAIN_ID], + }, + }, + ], + }); + }); + + it("Can stake on lido on same chain", async () => { + const { batchTransaction, lidoStakeEthAdapter, steth } = await setupTests(); + + const amount = ethers.utils.parseEther("1"); + + const lidoData = defaultAbiCoder.encode( + ["address", "uint256"], + [deployer.address, amount] + ); + + const tokens = [NATIVE_TOKEN]; + const amounts = [amount]; + const targets = [lidoStakeEthAdapter.address]; + const data = [lidoData]; + const value = [0]; + const callType = [2]; + + const balBefore = await ethers.provider.getBalance(deployer.address); + const stethBalBefore = await steth.balanceOf(deployer.address); + + await batchTransaction.executeBatchCallsSameChain( + tokens, + amounts, + targets, + value, + callType, + data, + { value: amount } + ); + + const balAfter = await ethers.provider.getBalance(deployer.address); + const stethBalAfter = await steth.balanceOf(deployer.address); + + expect(balBefore).gt(balAfter); + expect(stethBalAfter).gt(stethBalBefore); + }); + + it("Can stake ETH on Lido on dest chain when instruction is received from BatchTransaction contract", async () => { + const { batchTransaction, lidoStakeEthAdapter, steth, mockAssetForwarder } = + await setupTests(); + + const amount = ethers.utils.parseEther("1"); + + const targets = [lidoStakeEthAdapter.address]; + const data = [ + defaultAbiCoder.encode( + ["address", "uint256"], + [deployer.address, amount] + ), + ]; + const value = [0]; + const callType = [2]; + + const assetForwarderData = defaultAbiCoder.encode( + ["address", "address[]", "uint256[]", "uint256[]", "bytes[]"], + [deployer.address, targets, value, callType, data] + ); + + const balBefore = await ethers.provider.getBalance(deployer.address); + const stethBalBefore = await steth.balanceOf(deployer.address); + + await mockAssetForwarder.handleMessage( + NATIVE_TOKEN, + amount, + assetForwarderData, + batchTransaction.address, + { value: amount, gasLimit: 1000000 } + ); + + const balAfter = await ethers.provider.getBalance(deployer.address); + const stethBalAfter = await steth.balanceOf(deployer.address); + + expect(balAfter).lt(balBefore); + expect(stethBalAfter).gt(stethBalBefore); + }); + + it("Can stake ETH on Lido on dest chain when instruction is received directly on LidoStakeEth adapter", async () => { + const { lidoStakeEthAdapter, steth, mockAssetForwarder } = + await setupTests(); + + const amount = ethers.utils.parseEther("1"); + + const data = defaultAbiCoder.encode(["address"], [deployer.address]); + + const balBefore = await ethers.provider.getBalance(deployer.address); + const stethBalBefore = await steth.balanceOf(deployer.address); + + await mockAssetForwarder.handleMessage( + NATIVE_TOKEN, + amount, + data, + lidoStakeEthAdapter.address, + { value: amount } + ); + + const balAfter = await ethers.provider.getBalance(deployer.address); + const stethBalAfter = await steth.balanceOf(deployer.address); + + expect(balAfter).lt(balBefore); + expect(stethBalAfter).gt(stethBalBefore); + }); +}); diff --git a/evm/test/Lido/LidoStakeMatic.specs.ts b/evm/test/Lido/LidoStakeMatic.specs.ts new file mode 100644 index 0000000..5054c31 --- /dev/null +++ b/evm/test/Lido/LidoStakeMatic.specs.ts @@ -0,0 +1,305 @@ +import hardhat, { ethers, waffle } from "hardhat"; +import { expect } from "chai"; +import { RPC } from "../constants"; +import { + DEXSPAN, + DEFAULT_ENV, + NATIVE, + WNATIVE, + DEFAULT_REFUND_ADDRESS, +} from "../../tasks/constants"; +import { LidoStakeMatic__factory } from "../../typechain/factories/LidoStakeMatic__factory"; +import { TokenInterface__factory } from "../../typechain/factories/TokenInterface__factory"; +import { MockAssetForwarder__factory } from "../../typechain/factories/MockAssetForwarder__factory"; +import { BatchTransaction__factory } from "../../typechain/factories/BatchTransaction__factory"; +import { BigNumber, Contract, Wallet } from "ethers"; +import { getPathfinderData } from "../utils"; +import { defaultAbiCoder } from "ethers/lib/utils"; +import { DexSpanAdapter__factory } from "../../typechain/factories/DexSpanAdapter__factory"; + +const CHAIN_ID = "5"; +const LIDO_ST_TOKEN = "0x9A7c69A167160C507602ecB3Df4911e8E98e1279"; +const MATIC_TOKEN = "0x499d11E0b6eAC7c0593d8Fb292DCBbF815Fb29Ae"; +const LIDO_REFERRAL_ADDRESS = "0x1643E812aE58766192Cf7D2Cf9567dF2C37e9B7F"; +const USDT = "0x2227E4764be4c858E534405019488D9E5890Ff9E"; + +describe("LidoStakeMatic Adapter: ", async () => { + const [deployer] = waffle.provider.getWallets(); + + const setupTests = async () => { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + const MockAssetForwarder = await ethers.getContractFactory( + "MockAssetForwarder" + ); + const mockAssetForwarder = await MockAssetForwarder.deploy(); + + const BatchTransaction = await ethers.getContractFactory( + "BatchTransaction" + ); + + const batchTransaction = await BatchTransaction.deploy( + NATIVE, + WNATIVE[env][CHAIN_ID], + mockAssetForwarder.address, + DEXSPAN[env][CHAIN_ID] + ); + + const DexSpanAdapter = await ethers.getContractFactory("DexSpanAdapter"); + const dexSpanAdapter = await DexSpanAdapter.deploy( + NATIVE, + WNATIVE[env][CHAIN_ID], + deployer.address, + mockAssetForwarder.address, + DEXSPAN[env][CHAIN_ID], + DEFAULT_REFUND_ADDRESS + ); + + const LidoStakeMatic = await ethers.getContractFactory("LidoStakeMatic"); + const lidoStakeMaticAdapter = await LidoStakeMatic.deploy( + NATIVE, + WNATIVE[env][CHAIN_ID], + deployer.address, + mockAssetForwarder.address, + DEXSPAN[env][CHAIN_ID], + LIDO_ST_TOKEN, + MATIC_TOKEN, + LIDO_REFERRAL_ADDRESS + ); + + return { + batchTransaction: BatchTransaction__factory.connect( + batchTransaction.address, + deployer + ), + lidoStakeMaticAdapter: LidoStakeMatic__factory.connect( + lidoStakeMaticAdapter.address, + deployer + ), + dexSpanAdapter: DexSpanAdapter__factory.connect( + dexSpanAdapter.address, + deployer + ), + mockAssetForwarder: MockAssetForwarder__factory.connect( + mockAssetForwarder.address, + deployer + ), + matic: TokenInterface__factory.connect(MATIC_TOKEN, deployer), + usdt: TokenInterface__factory.connect(USDT, deployer), + steth: TokenInterface__factory.connect(LIDO_ST_TOKEN, deployer), + }; + }; + + beforeEach(async function () { + await hardhat.network.provider.request({ + method: "hardhat_reset", + params: [ + { + forking: { + jsonRpcUrl: RPC[CHAIN_ID], + }, + }, + ], + }); + }); + + const toBytes32 = (bn: BigNumber) => { + return ethers.utils.hexlify(ethers.utils.zeroPad(bn.toHexString(), 32)); + }; + + // This works for token when it has balance mapping at slot 0. + const setUserTokenBalance = async ( + contract: Contract, + user: Wallet, + balance: BigNumber + ) => { + const index = ethers.utils.solidityKeccak256( + ["uint256", "uint256"], + [user.address, 0] // key, slot + ); + + await hardhat.network.provider.request({ + method: "hardhat_setStorageAt", + params: [contract.address, index, toBytes32(balance).toString()], + }); + + await hardhat.network.provider.request({ + method: "evm_mine", + params: [], + }); + }; + + it("Can stake on lido on same chain", async () => { + const { batchTransaction, lidoStakeMaticAdapter, steth, matic } = + await setupTests(); + + const amount = ethers.utils.parseEther("1"); + + const lidoData = defaultAbiCoder.encode( + ["address", "uint256"], + [deployer.address, amount] + ); + + const tokens = [MATIC_TOKEN]; + const amounts = [amount]; + const targets = [lidoStakeMaticAdapter.address]; + const data = [lidoData]; + const value = [0]; + const callType = [2]; + + await setUserTokenBalance(matic, deployer, amount); + await matic.approve(batchTransaction.address, amount); + + const balBefore = await ethers.provider.getBalance(deployer.address); + const stethBalBefore = await steth.balanceOf(deployer.address); + + await batchTransaction.executeBatchCallsSameChain( + tokens, + amounts, + targets, + value, + callType, + data, + { value: amount } + ); + + const balAfter = await ethers.provider.getBalance(deployer.address); + const stethBalAfter = await steth.balanceOf(deployer.address); + + expect(balBefore).gt(balAfter); + expect(stethBalAfter).gt(stethBalBefore); + }); + + it("Can swap on dexspan and stake on lido on same chain", async () => { + // This may fail because the path finder may not give good estimate of minReturn + // due to which it may be lower than min amount to stake on lido + + const { + batchTransaction, + dexSpanAdapter, + lidoStakeMaticAdapter, + steth, + usdt, + } = await setupTests(); + + await setUserTokenBalance(usdt, deployer, BigNumber.from("10000000000000")); + + const dexSpanAmount = "10000000000000"; + await usdt.approve(batchTransaction.address, dexSpanAmount); + + const { data: swapData, minReturn } = await getPathfinderData( + usdt.address, + MATIC_TOKEN, + dexSpanAmount, + CHAIN_ID, + CHAIN_ID, + batchTransaction.address + ); + + const lidoData = defaultAbiCoder.encode( + ["address", "uint256"], + [deployer.address, minReturn] + ); + + const tokens = [usdt.address]; + const amounts = [dexSpanAmount]; + const targets = [dexSpanAdapter.address, lidoStakeMaticAdapter.address]; + const data = [swapData, lidoData]; + const value = [0, 0]; + const callType = [2, 2]; + + const usdtBalBefore = await usdt.balanceOf(deployer.address); + const stethBalBefore = await steth.balanceOf(deployer.address); + + await batchTransaction.executeBatchCallsSameChain( + tokens, + amounts, + targets, + value, + callType, + data + ); + + const usdtBalAfter = await usdt.balanceOf(deployer.address); + const stethBalAfter = await steth.balanceOf(deployer.address); + + expect(usdtBalBefore).gt(usdtBalAfter); + expect(stethBalAfter).gt(stethBalBefore); + }); + + it("Can stake ETH on Lido on dest chain when instruction is received from BatchTransaction contract", async () => { + const { + batchTransaction, + lidoStakeMaticAdapter, + steth, + mockAssetForwarder, + matic, + } = await setupTests(); + + const amount = ethers.utils.parseEther("1"); + + const targets = [lidoStakeMaticAdapter.address]; + const data = [ + defaultAbiCoder.encode( + ["address", "uint256"], + [deployer.address, amount] + ), + ]; + const value = [0]; + const callType = [2]; + + const assetForwarderData = defaultAbiCoder.encode( + ["address", "address[]", "uint256[]", "uint256[]", "bytes[]"], + [deployer.address, targets, value, callType, data] + ); + + await setUserTokenBalance(matic, deployer, amount); + await matic.approve(mockAssetForwarder.address, amount); + + const balBefore = await ethers.provider.getBalance(deployer.address); + const stethBalBefore = await steth.balanceOf(deployer.address); + + await mockAssetForwarder.handleMessage( + MATIC_TOKEN, + amount, + assetForwarderData, + batchTransaction.address, + { value: amount, gasLimit: 1000000 } + ); + + const balAfter = await ethers.provider.getBalance(deployer.address); + const stethBalAfter = await steth.balanceOf(deployer.address); + + expect(balAfter).lt(balBefore); + expect(stethBalAfter).gt(stethBalBefore); + }); + + it("Can stake ETH on Lido on dest chain when instruction is received directly on LidoStakeMatic adapter", async () => { + const { lidoStakeMaticAdapter, steth, mockAssetForwarder, matic } = + await setupTests(); + + const amount = ethers.utils.parseEther("1"); + + const data = defaultAbiCoder.encode(["address"], [deployer.address]); + + const balBefore = await ethers.provider.getBalance(deployer.address); + const stethBalBefore = await steth.balanceOf(deployer.address); + + await setUserTokenBalance(matic, deployer, amount); + await matic.approve(mockAssetForwarder.address, amount); + + await mockAssetForwarder.handleMessage( + MATIC_TOKEN, + amount, + data, + lidoStakeMaticAdapter.address, + { value: amount } + ); + + const balAfter = await ethers.provider.getBalance(deployer.address); + const stethBalAfter = await steth.balanceOf(deployer.address); + + expect(balAfter).lt(balBefore); + expect(stethBalAfter).gt(stethBalBefore); + }); +}); diff --git a/evm/test/MetaPool/MetaPoolStakeEth.specs.ts b/evm/test/MetaPool/MetaPoolStakeEth.specs.ts new file mode 100644 index 0000000..56e5f18 --- /dev/null +++ b/evm/test/MetaPool/MetaPoolStakeEth.specs.ts @@ -0,0 +1,293 @@ +import hardhat, { ethers, waffle } from "hardhat"; +import { expect } from "chai"; +import { RPC } from "../constants"; +import { + DEXSPAN, + DEFAULT_ENV, + NATIVE, + WNATIVE, + DEFAULT_REFUND_ADDRESS, +} from "../../tasks/constants"; +import { MetaPoolStakeEth__factory } from "../../typechain/factories/MetaPoolStakeEth__factory"; +import { TokenInterface__factory } from "../../typechain/factories/TokenInterface__factory"; +import { MockAssetForwarder__factory } from "../../typechain/factories/MockAssetForwarder__factory"; +import { BatchTransaction__factory } from "../../typechain/factories/BatchTransaction__factory"; +import { BigNumber, Contract, Wallet } from "ethers"; +import { getPathfinderData } from "../utils"; +import { defaultAbiCoder } from "ethers/lib/utils"; +import { DexSpanAdapter__factory } from "../../typechain/factories/DexSpanAdapter__factory"; + +const CHAIN_ID = "5"; +const MPETH_TOKEN = "0x748c905130CC15b92B97084Fd1eEBc2d2419146f"; +const METAPOOL_POOL = "0x748c905130CC15b92B97084Fd1eEBc2d2419146f"; +const NATIVE_TOKEN = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"; +const USDT = "0x2227E4764be4c858E534405019488D9E5890Ff9E"; + +describe("MetaPoolStakeEth Adapter: ", async () => { + const [deployer] = waffle.provider.getWallets(); + + const setupTests = async () => { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + const MockAssetForwarder = await ethers.getContractFactory( + "MockAssetForwarder" + ); + const mockAssetForwarder = await MockAssetForwarder.deploy(); + + const BatchTransaction = await ethers.getContractFactory( + "BatchTransaction" + ); + + const batchTransaction = await BatchTransaction.deploy( + NATIVE, + WNATIVE[env][CHAIN_ID], + mockAssetForwarder.address, + DEXSPAN[env][CHAIN_ID] + ); + + const DexSpanAdapter = await ethers.getContractFactory("DexSpanAdapter"); + const dexSpanAdapter = await DexSpanAdapter.deploy( + NATIVE, + WNATIVE[env][CHAIN_ID], + deployer.address, + mockAssetForwarder.address, + DEXSPAN[env][CHAIN_ID], + DEFAULT_REFUND_ADDRESS + ); + + const MetaPoolStakeEth = await ethers.getContractFactory("MetaPoolStakeEth"); + const metaPoolStakeEthAdapter = await MetaPoolStakeEth.deploy( + NATIVE, + WNATIVE[env][CHAIN_ID], + deployer.address, + mockAssetForwarder.address, + DEXSPAN[env][CHAIN_ID], + MPETH_TOKEN, + METAPOOL_POOL + ); + + return { + batchTransaction: BatchTransaction__factory.connect( + batchTransaction.address, + deployer + ), + metaPoolStakeEthAdapter: MetaPoolStakeEth__factory.connect( + metaPoolStakeEthAdapter.address, + deployer + ), + dexSpanAdapter: DexSpanAdapter__factory.connect( + dexSpanAdapter.address, + deployer + ), + mockAssetForwarder: MockAssetForwarder__factory.connect( + mockAssetForwarder.address, + deployer + ), + usdt: TokenInterface__factory.connect(USDT, deployer), + mpEth: TokenInterface__factory.connect(MPETH_TOKEN, deployer), + }; + }; + + beforeEach(async function () { + await hardhat.network.provider.request({ + method: "hardhat_reset", + params: [ + { + forking: { + jsonRpcUrl: RPC[CHAIN_ID], + }, + }, + ], + }); + }); + + const toBytes32 = (bn: BigNumber) => { + return ethers.utils.hexlify(ethers.utils.zeroPad(bn.toHexString(), 32)); + }; + + // This works for token when it has balance mapping at slot 0. + const setUserTokenBalance = async ( + contract: Contract, + user: Wallet, + balance: BigNumber + ) => { + const index = ethers.utils.solidityKeccak256( + ["uint256", "uint256"], + [user.address, 0] // key, slot + ); + + await hardhat.network.provider.request({ + method: "hardhat_setStorageAt", + params: [contract.address, index, toBytes32(balance).toString()], + }); + + await hardhat.network.provider.request({ + method: "evm_mine", + params: [], + }); + }; + + it("Can stake on metaPool on same chain", async () => { + const { batchTransaction, metaPoolStakeEthAdapter, mpEth } = + await setupTests(); + + const amount = ethers.utils.parseEther("1"); + + const metaPoolData = defaultAbiCoder.encode( + ["address", "uint256"], + [deployer.address, amount] + ); + + const tokens = [NATIVE_TOKEN]; + const amounts = [amount]; + const targets = [metaPoolStakeEthAdapter.address]; + const data = [metaPoolData]; + const value = [0]; + const callType = [2]; + + const balBefore = await ethers.provider.getBalance(deployer.address); + const mpEthBalBefore = await mpEth.balanceOf(deployer.address); + + await batchTransaction.executeBatchCallsSameChain( + tokens, + amounts, + targets, + value, + callType, + data, + { value: amount } + ); + + const balAfter = await ethers.provider.getBalance(deployer.address); + const mpEthBalAfter = await mpEth.balanceOf(deployer.address); + + expect(balBefore).gt(balAfter); + expect(mpEthBalAfter).gt(mpEthBalBefore); + }); + + it("Can swap on dexspan and stake on metaPool on same chain", async () => { + // This may fail because the path finder may not give good estimate of minReturn + // due to which it may be lower than min amount to stake on metaPool + + const { + batchTransaction, + dexSpanAdapter, + metaPoolStakeEthAdapter, + mpEth, + usdt, + } = await setupTests(); + + await setUserTokenBalance(usdt, deployer, BigNumber.from("10000000000000")); + + const dexSpanAmount = "10000000000000"; + await usdt.approve(batchTransaction.address, dexSpanAmount); + + const { data: swapData, minReturn } = await getPathfinderData( + usdt.address, + NATIVE_TOKEN, + dexSpanAmount, + CHAIN_ID, + CHAIN_ID, + batchTransaction.address + ); + + const metaPoolData = defaultAbiCoder.encode( + ["address", "uint256"], + [deployer.address, minReturn] + ); + + const tokens = [usdt.address]; + const amounts = [dexSpanAmount]; + const targets = [dexSpanAdapter.address, metaPoolStakeEthAdapter.address]; + const data = [swapData, metaPoolData]; + const value = [0, 0]; + const callType = [2, 2]; + + const usdtBalBefore = await usdt.balanceOf(deployer.address); + const mpEthBalBefore = await mpEth.balanceOf(deployer.address); + + await batchTransaction.executeBatchCallsSameChain( + tokens, + amounts, + targets, + value, + callType, + data + ); + + const usdtBalAfter = await usdt.balanceOf(deployer.address); + const mpEthBalAfter = await mpEth.balanceOf(deployer.address); + + expect(usdtBalBefore).gt(usdtBalAfter); + expect(mpEthBalAfter).gt(mpEthBalBefore); + }); + + it("Can stake ETH on MetaPool on dest chain when instruction is received from BatchTransaction contract", async () => { + const { + batchTransaction, + metaPoolStakeEthAdapter, + mpEth, + mockAssetForwarder, + } = await setupTests(); + + const amount = "100000000000000000"; + + const targets = [metaPoolStakeEthAdapter.address]; + const data = [ + defaultAbiCoder.encode( + ["address", "uint256"], + [deployer.address, amount] + ), + ]; + const value = [0]; + const callType = [2]; + + const assetForwarderData = defaultAbiCoder.encode( + ["address", "address[]", "uint256[]", "uint256[]", "bytes[]"], + [deployer.address, targets, value, callType, data] + ); + + const balBefore = await ethers.provider.getBalance(deployer.address); + const mpEthBalBefore = await mpEth.balanceOf(deployer.address); + + await mockAssetForwarder.handleMessage( + NATIVE_TOKEN, + amount, + assetForwarderData, + batchTransaction.address, + { value: amount } + ); + + const balAfter = await ethers.provider.getBalance(deployer.address); + const mpEthBalAfter = await mpEth.balanceOf(deployer.address); + + expect(balAfter).lt(balBefore); + expect(mpEthBalAfter).gt(mpEthBalBefore); + }); + + it("Can stake ETH on MetaPool on dest chain when instruction is received directly on MetaPoolStakeEth adapter", async () => { + const { metaPoolStakeEthAdapter, mpEth, mockAssetForwarder } = + await setupTests(); + + const amount = "100000000000000000"; + + const data = defaultAbiCoder.encode(["address"], [deployer.address]); + + const balBefore = await ethers.provider.getBalance(deployer.address); + const mpEthBalBefore = await mpEth.balanceOf(deployer.address); + + await mockAssetForwarder.handleMessage( + NATIVE_TOKEN, + amount, + data, + metaPoolStakeEthAdapter.address, + { value: amount } + ); + + const balAfter = await ethers.provider.getBalance(deployer.address); + const mpEthBalAfter = await mpEth.balanceOf(deployer.address); + + expect(balAfter).lt(balBefore); + expect(mpEthBalAfter).gt(mpEthBalBefore); + }); +}); diff --git a/evm/test/Origin/OriginStakeEth.specs.ts b/evm/test/Origin/OriginStakeEth.specs.ts new file mode 100644 index 0000000..9807862 --- /dev/null +++ b/evm/test/Origin/OriginStakeEth.specs.ts @@ -0,0 +1,236 @@ +import hardhat, { ethers, waffle } from "hardhat"; +import { expect } from "chai"; +import { RPC } from "../constants"; +import { + DEXSPAN, + DEFAULT_ENV, + NATIVE, + WNATIVE, + DEFAULT_REFUND_ADDRESS, +} from "../../tasks/constants"; +import { OriginStakeEth__factory } from "../../typechain/factories/OriginStakeEth__factory"; +import { TokenInterface__factory } from "../../typechain/factories/TokenInterface__factory"; +import { MockAssetForwarder__factory } from "../../typechain/factories/MockAssetForwarder__factory"; +import { BatchTransaction__factory } from "../../typechain/factories/BatchTransaction__factory"; +import { BigNumber, Contract, Wallet } from "ethers"; +import { getPathfinderData } from "../utils"; +import { defaultAbiCoder } from "ethers/lib/utils"; +import { DexSpanAdapter__factory } from "../../typechain/factories/DexSpanAdapter__factory"; + +const CHAIN_ID = "1"; +const O_TOKEN = "0x856c4Efb76C1D1AE02e20CEB03A2A6a08b0b8dC3"; +const ORIGIN_POOL = "0x9858e47BCbBe6fBAC040519B02d7cd4B2C470C66"; +const NATIVE_TOKEN = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"; +const USDT = "0xdac17f958d2ee523a2206206994597c13d831ec7"; + +describe("OriginStakeEth Adapter: ", async () => { + const [deployer] = waffle.provider.getWallets(); + + const setupTests = async () => { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + const MockAssetForwarder = await ethers.getContractFactory( + "MockAssetForwarder" + ); + const mockAssetForwarder = await MockAssetForwarder.deploy(); + + const BatchTransaction = await ethers.getContractFactory( + "BatchTransaction" + ); + + const batchTransaction = await BatchTransaction.deploy( + NATIVE, + WNATIVE[env][CHAIN_ID], + mockAssetForwarder.address, + DEXSPAN[env][CHAIN_ID] + ); + + const DexSpanAdapter = await ethers.getContractFactory("DexSpanAdapter"); + const dexSpanAdapter = await DexSpanAdapter.deploy( + NATIVE, + WNATIVE[env][CHAIN_ID], + deployer.address, + mockAssetForwarder.address, + DEXSPAN[env][CHAIN_ID], + DEFAULT_REFUND_ADDRESS + ); + + const OriginStakeEth = await ethers.getContractFactory("OriginStakeEth"); + const originStakeEthAdapter = await OriginStakeEth.deploy( + NATIVE, + WNATIVE[env][CHAIN_ID], + deployer.address, + mockAssetForwarder.address, + DEXSPAN[env][CHAIN_ID], + O_TOKEN, + ORIGIN_POOL + ); + + return { + batchTransaction: BatchTransaction__factory.connect( + batchTransaction.address, + deployer + ), + originStakeEthAdapter: OriginStakeEth__factory.connect( + originStakeEthAdapter.address, + deployer + ), + dexSpanAdapter: DexSpanAdapter__factory.connect( + dexSpanAdapter.address, + deployer + ), + mockAssetForwarder: MockAssetForwarder__factory.connect( + mockAssetForwarder.address, + deployer + ), + usdt: TokenInterface__factory.connect(USDT, deployer), + oEth: TokenInterface__factory.connect(O_TOKEN, deployer), + }; + }; + + beforeEach(async function () { + await hardhat.network.provider.request({ + method: "hardhat_reset", + params: [ + { + forking: { + jsonRpcUrl: RPC[CHAIN_ID], + }, + }, + ], + }); + }); + + const toBytes32 = (bn: BigNumber) => { + return ethers.utils.hexlify(ethers.utils.zeroPad(bn.toHexString(), 32)); + }; + + // This works for token when it has balance mapping at slot 0. + const setUserTokenBalance = async ( + contract: Contract, + user: Wallet, + balance: BigNumber + ) => { + const index = ethers.utils.solidityKeccak256( + ["uint256", "uint256"], + [user.address, 0] // key, slot + ); + + await hardhat.network.provider.request({ + method: "hardhat_setStorageAt", + params: [contract.address, index, toBytes32(balance).toString()], + }); + + await hardhat.network.provider.request({ + method: "evm_mine", + params: [], + }); + }; + + it("Can stake on origin on same chain", async () => { + const { batchTransaction, originStakeEthAdapter, oEth } = + await setupTests(); + + const amount = ethers.utils.parseEther("1"); + + const originData = defaultAbiCoder.encode( + ["address", "uint256"], + [deployer.address, amount] + ); + + const tokens = [NATIVE_TOKEN]; + const amounts = [amount]; + const targets = [originStakeEthAdapter.address]; + const data = [originData]; + const value = [0]; + const callType = [2]; + + const balBefore = await ethers.provider.getBalance(deployer.address); + const oEthBalBefore = await oEth.balanceOf(deployer.address); + + await batchTransaction.executeBatchCallsSameChain( + tokens, + amounts, + targets, + value, + callType, + data, + { value: amount } + ); + + const balAfter = await ethers.provider.getBalance(deployer.address); + const oEthBalAfter = await oEth.balanceOf(deployer.address); + + expect(balBefore).gt(balAfter); + expect(oEthBalAfter).gt(oEthBalBefore); + }); + + it("Can stake ETH on Origin on dest chain when instruction is received from BatchTransaction contract", async () => { + const { + batchTransaction, + originStakeEthAdapter, + oEth, + mockAssetForwarder, + } = await setupTests(); + + const amount = "100000000000000000"; + + const targets = [originStakeEthAdapter.address]; + const data = [ + defaultAbiCoder.encode( + ["address", "uint256"], + [deployer.address, amount] + ), + ]; + const value = [0]; + const callType = [2]; + + const assetForwarderData = defaultAbiCoder.encode( + ["address", "address[]", "uint256[]", "uint256[]", "bytes[]"], + [deployer.address, targets, value, callType, data] + ); + + const balBefore = await ethers.provider.getBalance(deployer.address); + const oEthBalBefore = await oEth.balanceOf(deployer.address); + + await mockAssetForwarder.handleMessage( + NATIVE_TOKEN, + amount, + assetForwarderData, + batchTransaction.address, + { value: amount } + ); + + const balAfter = await ethers.provider.getBalance(deployer.address); + const oEthBalAfter = await oEth.balanceOf(deployer.address); + + expect(balAfter).lt(balBefore); + expect(oEthBalAfter).gt(oEthBalBefore); + }); + + it("Can stake ETH on Origin on dest chain when instruction is received directly on OriginStakeEth adapter", async () => { + const { originStakeEthAdapter, oEth, mockAssetForwarder } = + await setupTests(); + + const amount = "100000000000000000"; + + const data = defaultAbiCoder.encode(["address"], [deployer.address]); + + const balBefore = await ethers.provider.getBalance(deployer.address); + const oEthBalBefore = await oEth.balanceOf(deployer.address); + + await mockAssetForwarder.handleMessage( + NATIVE_TOKEN, + amount, + data, + originStakeEthAdapter.address, + { value: amount } + ); + + const balAfter = await ethers.provider.getBalance(deployer.address); + const oEthBalAfter = await oEth.balanceOf(deployer.address); + + expect(balAfter).lt(balBefore); + expect(oEthBalAfter).gt(oEthBalBefore); + }); +}); diff --git a/evm/test/RocketPool/RPStakeEth.specs.ts b/evm/test/RocketPool/RPStakeEth.specs.ts new file mode 100644 index 0000000..eaa820f --- /dev/null +++ b/evm/test/RocketPool/RPStakeEth.specs.ts @@ -0,0 +1,220 @@ +import hardhat, { ethers, waffle } from "hardhat"; +import { expect } from "chai"; +import { RPC } from "../constants"; +import { + DEXSPAN, + DEFAULT_ENV, + NATIVE, + WNATIVE, + DEFAULT_REFUND_ADDRESS, +} from "../../tasks/constants"; +import { RPStakeEth__factory } from "../../typechain/factories/RPStakeEth__factory"; +import { TokenInterface__factory } from "../../typechain/factories/TokenInterface__factory"; +import { MockAssetForwarder__factory } from "../../typechain/factories/MockAssetForwarder__factory"; +import { BatchTransaction__factory } from "../../typechain/factories/BatchTransaction__factory"; +import { BigNumber, Contract, Wallet } from "ethers"; +import { getPathfinderData } from "../utils"; +import { defaultAbiCoder } from "ethers/lib/utils"; +import { DexSpanAdapter__factory } from "../../typechain/factories/DexSpanAdapter__factory"; + +const CHAIN_ID = "5"; +const R_ETH_TOKEN = "0x178E141a0E3b34152f73Ff610437A7bf9B83267A"; +const ROCKET_DEPOSIT_POOL = "0xa9A6A14A3643690D0286574976F45abBDAD8f505"; +const NATIVE_TOKEN = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"; +const USDT = "0x2227E4764be4c858E534405019488D9E5890Ff9E"; + +describe("RPStakeEth Adapter: ", async () => { + const [deployer] = waffle.provider.getWallets(); + + const setupTests = async () => { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + const MockAssetForwarder = await ethers.getContractFactory( + "MockAssetForwarder" + ); + const mockAssetForwarder = await MockAssetForwarder.deploy(); + + const BatchTransaction = await ethers.getContractFactory( + "BatchTransaction" + ); + + const batchTransaction = await BatchTransaction.deploy( + NATIVE, + WNATIVE[env][CHAIN_ID], + mockAssetForwarder.address, + DEXSPAN[env][CHAIN_ID] + ); + + const DexSpanAdapter = await ethers.getContractFactory("DexSpanAdapter"); + const dexSpanAdapter = await DexSpanAdapter.deploy( + NATIVE, + WNATIVE[env][CHAIN_ID], + deployer.address, + mockAssetForwarder.address, + DEXSPAN[env][CHAIN_ID], + DEFAULT_REFUND_ADDRESS + ); + + const RPStakeEth = await ethers.getContractFactory("RPStakeEth"); + const rpStakeEthAdapter = await RPStakeEth.deploy( + NATIVE, + WNATIVE[env][CHAIN_ID], + deployer.address, + mockAssetForwarder.address, + DEXSPAN[env][CHAIN_ID], + R_ETH_TOKEN, + ROCKET_DEPOSIT_POOL + ); + + return { + batchTransaction: BatchTransaction__factory.connect( + batchTransaction.address, + deployer + ), + rpStakeEthAdapter: RPStakeEth__factory.connect( + rpStakeEthAdapter.address, + deployer + ), + dexSpanAdapter: DexSpanAdapter__factory.connect( + dexSpanAdapter.address, + deployer + ), + mockAssetForwarder: MockAssetForwarder__factory.connect( + mockAssetForwarder.address, + deployer + ), + usdt: TokenInterface__factory.connect(USDT, deployer), + rpEth: TokenInterface__factory.connect(R_ETH_TOKEN, deployer), + }; + }; + + beforeEach(async function () { + await hardhat.network.provider.request({ + method: "hardhat_reset", + params: [ + { + forking: { + jsonRpcUrl: RPC[CHAIN_ID], + }, + }, + ], + }); + }); + + const toBytes32 = (bn: BigNumber) => { + return ethers.utils.hexlify(ethers.utils.zeroPad(bn.toHexString(), 32)); + }; + + // This works for token when it has balance mapping at slot 0. + const setUserTokenBalance = async ( + contract: Contract, + user: Wallet, + balance: BigNumber + ) => { + const index = ethers.utils.solidityKeccak256( + ["uint256", "uint256"], + [user.address, 0] // key, slot + ); + + await hardhat.network.provider.request({ + method: "hardhat_setStorageAt", + params: [contract.address, index, toBytes32(balance).toString()], + }); + + await hardhat.network.provider.request({ + method: "evm_mine", + params: [], + }); + }; + + it("Can stake on rp on same chain", async () => { + const { batchTransaction, dexSpanAdapter, rpStakeEthAdapter, rpEth } = + await setupTests(); + + const amount = "1000000000000000000"; + + const { data: swapData, minReturn } = await getPathfinderData( + NATIVE_TOKEN, + R_ETH_TOKEN, + amount, + CHAIN_ID, + CHAIN_ID, + batchTransaction.address + ); + + const tokens = [NATIVE_TOKEN]; + const amounts = [amount]; + const targets = [dexSpanAdapter.address]; + const data = [swapData]; + const value = [0]; + const callType = [2]; + + const balBefore = await ethers.provider.getBalance(deployer.address); + const rpEthBalBefore = await rpEth.balanceOf(deployer.address); + + await batchTransaction.executeBatchCallsSameChain( + tokens, + amounts, + targets, + value, + callType, + data, + { value: amount, + gasLimit: 10000000 } + ); + + const balAfter = await ethers.provider.getBalance(deployer.address); + const rpEthBalAfter = await rpEth.balanceOf(deployer.address); + + expect(balBefore).gt(balAfter); + expect(rpEthBalAfter).gt(rpEthBalBefore); + }); + + it("Can stake ETH on Rocket Pool on dest chain when instruction is received from BatchTransaction contract", async () => { + const { + batchTransaction, + rpStakeEthAdapter, + dexSpanAdapter, + rpEth, + mockAssetForwarder, + } = await setupTests(); + + const amount = "100000000000000000"; + + const { data: swapData, minReturn } = await getPathfinderData( + NATIVE_TOKEN, + R_ETH_TOKEN, + amount, + CHAIN_ID, + CHAIN_ID, + batchTransaction.address + ); + + const targets = [dexSpanAdapter.address]; + const data = [swapData]; + const value = [0]; + const callType = [2]; + + const assetForwarderData = defaultAbiCoder.encode( + ["address", "address[]", "uint256[]", "uint256[]", "bytes[]"], + [deployer.address, targets, value, callType, data] + ); + + const balBefore = await ethers.provider.getBalance(deployer.address); + const rpEthBalBefore = await rpEth.balanceOf(deployer.address); + + await mockAssetForwarder.handleMessage( + NATIVE_TOKEN, + amount, + assetForwarderData, + batchTransaction.address, + { value: amount } + ); + + const balAfter = await ethers.provider.getBalance(deployer.address); + const rpEthBalAfter = await rpEth.balanceOf(deployer.address); + + expect(balAfter).lt(balBefore); + expect(rpEthBalAfter).gt(rpEthBalBefore); + }); +}); diff --git a/evm/test/Stader/StaderStakeBnb.specs.ts b/evm/test/Stader/StaderStakeBnb.specs.ts new file mode 100644 index 0000000..fa3e958 --- /dev/null +++ b/evm/test/Stader/StaderStakeBnb.specs.ts @@ -0,0 +1,187 @@ +import hardhat, { ethers, waffle } from "hardhat"; +import { expect } from "chai"; +import { RPC } from "../constants"; +import { DEXSPAN, DEFAULT_ENV, WNATIVE } from "../../tasks/constants"; +import { StaderStakeBnb__factory } from "../../typechain/factories/StaderStakeBnb__factory"; +import { TokenInterface__factory } from "../../typechain/factories/TokenInterface__factory"; +import { MockAssetForwarder__factory } from "../../typechain/factories/MockAssetForwarder__factory"; +import { BatchTransaction__factory } from "../../typechain/factories/BatchTransaction__factory"; +import { defaultAbiCoder } from "ethers/lib/utils"; + +const CHAIN_ID = "56"; +const STADER_X_TOKEN = "0x1bdd3Cf7F79cfB8EdbB955f20ad99211551BA275"; +const STADER_POOL = "0x7276241a669489E4BBB76f63d2A43Bfe63080F2F"; +const NATIVE_TOKEN = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"; +const USDT = "0x55d398326f99059ff775485246999027b3197955"; + +describe("StaderStakeBnb Adapter: ", async () => { + const [deployer] = waffle.provider.getWallets(); + + const setupTests = async () => { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + const MockAssetForwarder = await ethers.getContractFactory( + "MockAssetForwarder" + ); + const mockAssetForwarder = await MockAssetForwarder.deploy(); + + const BatchTransaction = await ethers.getContractFactory( + "BatchTransaction" + ); + + const batchTransaction = await BatchTransaction.deploy( + NATIVE_TOKEN, + WNATIVE[env][CHAIN_ID], + mockAssetForwarder.address, + DEXSPAN[env][CHAIN_ID] + ); + + const StaderStakeBnb = await ethers.getContractFactory("StaderStakeBnb"); + const staderStakeBnbAdapter = await StaderStakeBnb.deploy( + NATIVE_TOKEN, + WNATIVE[env][CHAIN_ID], + deployer.address, + mockAssetForwarder.address, + DEXSPAN[env][CHAIN_ID], + STADER_X_TOKEN, + STADER_POOL + ); + + return { + batchTransaction: BatchTransaction__factory.connect( + batchTransaction.address, + deployer + ), + staderStakeBnbAdapter: StaderStakeBnb__factory.connect( + staderStakeBnbAdapter.address, + deployer + ), + mockAssetForwarder: MockAssetForwarder__factory.connect( + mockAssetForwarder.address, + deployer + ), + usdt: TokenInterface__factory.connect(USDT, deployer), + bnbx: TokenInterface__factory.connect(STADER_X_TOKEN, deployer), + }; + }; + + beforeEach(async function () { + await hardhat.network.provider.request({ + method: "hardhat_reset", + params: [ + { + forking: { + jsonRpcUrl: RPC[CHAIN_ID], + }, + }, + ], + }); + }); + + it("Can stake on stader on same chain", async () => { + const { batchTransaction, staderStakeBnbAdapter, bnbx } = + await setupTests(); + + const amount = ethers.utils.parseEther("1"); + + const staderData = defaultAbiCoder.encode( + ["address", "uint256"], + [deployer.address, amount] + ); + + const tokens = [NATIVE_TOKEN]; + const amounts = [amount]; + const targets = [staderStakeBnbAdapter.address]; + const data = [staderData]; + const value = [0]; + const callType = [2]; + + const balBefore = await ethers.provider.getBalance(deployer.address); + const bnbxBalBefore = await bnbx.balanceOf(deployer.address); + + await batchTransaction.executeBatchCallsSameChain( + tokens, + amounts, + targets, + value, + callType, + data, + { value: amount } + ); + + const balAfter = await ethers.provider.getBalance(deployer.address); + const bnbxBalAfter = await bnbx.balanceOf(deployer.address); + + expect(balBefore).gt(balAfter); + expect(bnbxBalAfter).gt(bnbxBalBefore); + }); + + it("Can stake BNB on Stader on dest chain when instruction is received from BatchTransaction contract", async () => { + const { + batchTransaction, + staderStakeBnbAdapter, + bnbx, + mockAssetForwarder, + } = await setupTests(); + + const amount = "100000000000000000"; + + const targets = [staderStakeBnbAdapter.address]; + const data = [ + defaultAbiCoder.encode( + ["address", "uint256"], + [deployer.address, amount] + ), + ]; + const value = [0]; + const callType = [2]; + + const assetForwarderData = defaultAbiCoder.encode( + ["address", "address[]", "uint256[]", "uint256[]", "bytes[]"], + [deployer.address, targets, value, callType, data] + ); + + const balBefore = await ethers.provider.getBalance(deployer.address); + const bnbxBalBefore = await bnbx.balanceOf(deployer.address); + + await mockAssetForwarder.handleMessage( + NATIVE_TOKEN, + amount, + assetForwarderData, + batchTransaction.address, + { value: amount } + ); + + const balAfter = await ethers.provider.getBalance(deployer.address); + const bnbxBalAfter = await bnbx.balanceOf(deployer.address); + + expect(balAfter).lt(balBefore); + expect(bnbxBalAfter).gt(bnbxBalBefore); + }); + + it("Can stake BNB on Stader on dest chain when instruction is received directly on StaderStakeBnb adapter", async () => { + const { staderStakeBnbAdapter, bnbx, mockAssetForwarder } = + await setupTests(); + + const amount = "100000000000000000"; + + const data = defaultAbiCoder.encode(["address"], [deployer.address]); + + const balBefore = await ethers.provider.getBalance(deployer.address); + const bnbxBalBefore = await bnbx.balanceOf(deployer.address); + + await mockAssetForwarder.handleMessage( + NATIVE_TOKEN, + amount, + data, + staderStakeBnbAdapter.address, + { value: amount } + ); + + const balAfter = await ethers.provider.getBalance(deployer.address); + const bnbxBalAfter = await bnbx.balanceOf(deployer.address); + + expect(balAfter).lt(balBefore); + expect(bnbxBalAfter).gt(bnbxBalBefore); + }); +}); diff --git a/evm/test/Stader/StaderStakeEth.specs.ts b/evm/test/Stader/StaderStakeEth.specs.ts new file mode 100644 index 0000000..28a7f4b --- /dev/null +++ b/evm/test/Stader/StaderStakeEth.specs.ts @@ -0,0 +1,293 @@ +import hardhat, { ethers, waffle } from "hardhat"; +import { expect } from "chai"; +import { RPC } from "../constants"; +import { + DEXSPAN, + DEFAULT_ENV, + NATIVE, + WNATIVE, + DEFAULT_REFUND_ADDRESS, +} from "../../tasks/constants"; +import { StaderStakeEth__factory } from "../../typechain/factories/StaderStakeEth__factory"; +import { TokenInterface__factory } from "../../typechain/factories/TokenInterface__factory"; +import { MockAssetForwarder__factory } from "../../typechain/factories/MockAssetForwarder__factory"; +import { BatchTransaction__factory } from "../../typechain/factories/BatchTransaction__factory"; +import { BigNumber, Contract, Wallet } from "ethers"; +import { getPathfinderData } from "../utils"; +import { defaultAbiCoder } from "ethers/lib/utils"; +import { DexSpanAdapter__factory } from "../../typechain/factories/DexSpanAdapter__factory"; + +const CHAIN_ID = "5"; +const STADER_X_TOKEN = "0x3338eCd3ab3d3503c55c931d759fA6d78d287236"; +const STADER_POOL = "0xd0e400Ec6Ed9C803A9D9D3a602494393E806F823"; +const NATIVE_TOKEN = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"; +const USDT = "0x2227E4764be4c858E534405019488D9E5890Ff9E"; + +describe("StaderStakeEth Adapter: ", async () => { + const [deployer] = waffle.provider.getWallets(); + + const setupTests = async () => { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + const MockAssetForwarder = await ethers.getContractFactory( + "MockAssetForwarder" + ); + const mockAssetForwarder = await MockAssetForwarder.deploy(); + + const BatchTransaction = await ethers.getContractFactory( + "BatchTransaction" + ); + + const batchTransaction = await BatchTransaction.deploy( + NATIVE, + WNATIVE[env][CHAIN_ID], + mockAssetForwarder.address, + DEXSPAN[env][CHAIN_ID] + ); + + const DexSpanAdapter = await ethers.getContractFactory("DexSpanAdapter"); + const dexSpanAdapter = await DexSpanAdapter.deploy( + NATIVE, + WNATIVE[env][CHAIN_ID], + deployer.address, + mockAssetForwarder.address, + DEXSPAN[env][CHAIN_ID], + DEFAULT_REFUND_ADDRESS + ); + + const StaderStakeEth = await ethers.getContractFactory("StaderStakeEth"); + const staderStakeEthAdapter = await StaderStakeEth.deploy( + NATIVE, + WNATIVE[env][CHAIN_ID], + deployer.address, + mockAssetForwarder.address, + DEXSPAN[env][CHAIN_ID], + STADER_X_TOKEN, + STADER_POOL + ); + + return { + batchTransaction: BatchTransaction__factory.connect( + batchTransaction.address, + deployer + ), + staderStakeEthAdapter: StaderStakeEth__factory.connect( + staderStakeEthAdapter.address, + deployer + ), + dexSpanAdapter: DexSpanAdapter__factory.connect( + dexSpanAdapter.address, + deployer + ), + mockAssetForwarder: MockAssetForwarder__factory.connect( + mockAssetForwarder.address, + deployer + ), + usdt: TokenInterface__factory.connect(USDT, deployer), + ethx: TokenInterface__factory.connect(STADER_X_TOKEN, deployer), + }; + }; + + beforeEach(async function () { + await hardhat.network.provider.request({ + method: "hardhat_reset", + params: [ + { + forking: { + jsonRpcUrl: RPC[CHAIN_ID], + }, + }, + ], + }); + }); + + const toBytes32 = (bn: BigNumber) => { + return ethers.utils.hexlify(ethers.utils.zeroPad(bn.toHexString(), 32)); + }; + + // This works for token when it has balance mapping at slot 0. + const setUserTokenBalance = async ( + contract: Contract, + user: Wallet, + balance: BigNumber + ) => { + const index = ethers.utils.solidityKeccak256( + ["uint256", "uint256"], + [user.address, 0] // key, slot + ); + + await hardhat.network.provider.request({ + method: "hardhat_setStorageAt", + params: [contract.address, index, toBytes32(balance).toString()], + }); + + await hardhat.network.provider.request({ + method: "evm_mine", + params: [], + }); + }; + + it("Can stake on stader on same chain", async () => { + const { batchTransaction, staderStakeEthAdapter, ethx } = + await setupTests(); + + const amount = ethers.utils.parseEther("1"); + + const staderData = defaultAbiCoder.encode( + ["address", "uint256"], + [deployer.address, amount] + ); + + const tokens = [NATIVE_TOKEN]; + const amounts = [amount]; + const targets = [staderStakeEthAdapter.address]; + const data = [staderData]; + const value = [0]; + const callType = [2]; + + const balBefore = await ethers.provider.getBalance(deployer.address); + const ethxBalBefore = await ethx.balanceOf(deployer.address); + + await batchTransaction.executeBatchCallsSameChain( + tokens, + amounts, + targets, + value, + callType, + data, + { value: amount } + ); + + const balAfter = await ethers.provider.getBalance(deployer.address); + const ethxBalAfter = await ethx.balanceOf(deployer.address); + + expect(balBefore).gt(balAfter); + expect(ethxBalAfter).gt(ethxBalBefore); + }); + + it("Can swap on dexspan and stake on stader on same chain", async () => { + // This may fail because the path finder may not give good estimate of minReturn + // due to which it may be lower than min amount to stake on stader + + const { + batchTransaction, + dexSpanAdapter, + staderStakeEthAdapter, + ethx, + usdt, + } = await setupTests(); + + await setUserTokenBalance(usdt, deployer, BigNumber.from("10000000000000")); + + const dexSpanAmount = "10000000000000"; + await usdt.approve(batchTransaction.address, dexSpanAmount); + + const { data: swapData, minReturn } = await getPathfinderData( + usdt.address, + NATIVE_TOKEN, + dexSpanAmount, + CHAIN_ID, + CHAIN_ID, + batchTransaction.address + ); + + const staderData = defaultAbiCoder.encode( + ["address", "uint256"], + [deployer.address, minReturn] + ); + + const tokens = [usdt.address]; + const amounts = [dexSpanAmount]; + const targets = [dexSpanAdapter.address, staderStakeEthAdapter.address]; + const data = [swapData, staderData]; + const value = [0, 0]; + const callType = [2, 2]; + + const usdtBalBefore = await usdt.balanceOf(deployer.address); + const ethxBalBefore = await ethx.balanceOf(deployer.address); + + await batchTransaction.executeBatchCallsSameChain( + tokens, + amounts, + targets, + value, + callType, + data + ); + + const usdtBalAfter = await usdt.balanceOf(deployer.address); + const ethxBalAfter = await ethx.balanceOf(deployer.address); + + expect(usdtBalBefore).gt(usdtBalAfter); + expect(ethxBalAfter).gt(ethxBalBefore); + }); + + it("Can stake ETH on Stader on dest chain when instruction is received from BatchTransaction contract", async () => { + const { + batchTransaction, + staderStakeEthAdapter, + ethx, + mockAssetForwarder, + } = await setupTests(); + + const amount = "100000000000000000"; + + const targets = [staderStakeEthAdapter.address]; + const data = [ + defaultAbiCoder.encode( + ["address", "uint256"], + [deployer.address, amount] + ), + ]; + const value = [0]; + const callType = [2]; + + const assetForwarderData = defaultAbiCoder.encode( + ["address", "address[]", "uint256[]", "uint256[]", "bytes[]"], + [deployer.address, targets, value, callType, data] + ); + + const balBefore = await ethers.provider.getBalance(deployer.address); + const ethxBalBefore = await ethx.balanceOf(deployer.address); + + await mockAssetForwarder.handleMessage( + NATIVE_TOKEN, + amount, + assetForwarderData, + batchTransaction.address, + { value: amount } + ); + + const balAfter = await ethers.provider.getBalance(deployer.address); + const ethxBalAfter = await ethx.balanceOf(deployer.address); + + expect(balAfter).lt(balBefore); + expect(ethxBalAfter).gt(ethxBalBefore); + }); + + it("Can stake ETH on Stader on dest chain when instruction is received directly on StaderStakeEth adapter", async () => { + const { staderStakeEthAdapter, ethx, mockAssetForwarder } = + await setupTests(); + + const amount = "100000000000000000"; + + const data = defaultAbiCoder.encode(["address"], [deployer.address]); + + const balBefore = await ethers.provider.getBalance(deployer.address); + const ethxBalBefore = await ethx.balanceOf(deployer.address); + + await mockAssetForwarder.handleMessage( + NATIVE_TOKEN, + amount, + data, + staderStakeEthAdapter.address, + { value: amount } + ); + + const balAfter = await ethers.provider.getBalance(deployer.address); + const ethxBalAfter = await ethx.balanceOf(deployer.address); + + expect(balAfter).lt(balBefore); + expect(ethxBalAfter).gt(ethxBalBefore); + }); +}); diff --git a/evm/test/Stader/StaderStakeFtm.specs.ts b/evm/test/Stader/StaderStakeFtm.specs.ts new file mode 100644 index 0000000..938356e --- /dev/null +++ b/evm/test/Stader/StaderStakeFtm.specs.ts @@ -0,0 +1,187 @@ +import hardhat, { ethers, waffle } from "hardhat"; +import { expect } from "chai"; +import { RPC } from "../constants"; +import { DEXSPAN, DEFAULT_ENV, WNATIVE } from "../../tasks/constants"; +import { StaderStakeFtm__factory } from "../../typechain/factories/StaderStakeFtm__factory"; +import { TokenInterface__factory } from "../../typechain/factories/TokenInterface__factory"; +import { MockAssetForwarder__factory } from "../../typechain/factories/MockAssetForwarder__factory"; +import { BatchTransaction__factory } from "../../typechain/factories/BatchTransaction__factory"; +import { defaultAbiCoder } from "ethers/lib/utils"; + +const CHAIN_ID = "250"; +const STADER_X_TOKEN = "0xd7028092c830b5C8FcE061Af2E593413EbbC1fc1"; +const STADER_POOL = "0xB458BfC855ab504a8a327720FcEF98886065529b"; +const NATIVE_TOKEN = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"; +const USDT = "0x049d68029688eabf473097a2fc38ef61633a3c7a"; + +describe("StaderStakeFtm Adapter: ", async () => { + const [deployer] = waffle.provider.getWallets(); + + const setupTests = async () => { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + const MockAssetForwarder = await ethers.getContractFactory( + "MockAssetForwarder" + ); + const mockAssetForwarder = await MockAssetForwarder.deploy(); + + const BatchTransaction = await ethers.getContractFactory( + "BatchTransaction" + ); + + const batchTransaction = await BatchTransaction.deploy( + NATIVE_TOKEN, + WNATIVE[env][CHAIN_ID], + mockAssetForwarder.address, + DEXSPAN[env][CHAIN_ID] + ); + + const StaderStakeFtm = await ethers.getContractFactory("StaderStakeFtm"); + const staderStakeFtmAdapter = await StaderStakeFtm.deploy( + NATIVE_TOKEN, + WNATIVE[env][CHAIN_ID], + deployer.address, + mockAssetForwarder.address, + DEXSPAN[env][CHAIN_ID], + STADER_X_TOKEN, + STADER_POOL + ); + + return { + batchTransaction: BatchTransaction__factory.connect( + batchTransaction.address, + deployer + ), + staderStakeFtmAdapter: StaderStakeFtm__factory.connect( + staderStakeFtmAdapter.address, + deployer + ), + mockAssetForwarder: MockAssetForwarder__factory.connect( + mockAssetForwarder.address, + deployer + ), + usdt: TokenInterface__factory.connect(USDT, deployer), + sftmx: TokenInterface__factory.connect(STADER_X_TOKEN, deployer), + }; + }; + + beforeEach(async function () { + await hardhat.network.provider.request({ + method: "hardhat_reset", + params: [ + { + forking: { + jsonRpcUrl: RPC[CHAIN_ID], + }, + }, + ], + }); + }); + + it("Can stake on stader on same chain", async () => { + const { batchTransaction, staderStakeFtmAdapter, sftmx } = + await setupTests(); + + const amount = ethers.utils.parseEther("1"); + + const staderData = defaultAbiCoder.encode( + ["address", "uint256"], + [deployer.address, amount] + ); + + const tokens = [NATIVE_TOKEN]; + const amounts = [amount]; + const targets = [staderStakeFtmAdapter.address]; + const data = [staderData]; + const value = [0]; + const callType = [2]; + + const balBefore = await ethers.provider.getBalance(deployer.address); + const sftmxBalBefore = await sftmx.balanceOf(deployer.address); + + await batchTransaction.executeBatchCallsSameChain( + tokens, + amounts, + targets, + value, + callType, + data, + { value: amount } + ); + + const balAfter = await ethers.provider.getBalance(deployer.address); + const sftmxBalAfter = await sftmx.balanceOf(deployer.address); + + expect(balBefore).gt(balAfter); + expect(sftmxBalAfter).gt(sftmxBalBefore); + }); + + it("Can stake FTM on Stader on dest chain when instruction is received from BatchTransaction contract", async () => { + const { + batchTransaction, + staderStakeFtmAdapter, + sftmx, + mockAssetForwarder, + } = await setupTests(); + + const amount = ethers.utils.parseEther("1"); + + const targets = [staderStakeFtmAdapter.address]; + const data = [ + defaultAbiCoder.encode( + ["address", "uint256"], + [deployer.address, amount] + ), + ]; + const value = [0]; + const callType = [2]; + + const assetForwarderData = defaultAbiCoder.encode( + ["address", "address[]", "uint256[]", "uint256[]", "bytes[]"], + [deployer.address, targets, value, callType, data] + ); + + const balBefore = await ethers.provider.getBalance(deployer.address); + const sftmxBalBefore = await sftmx.balanceOf(deployer.address); + + await mockAssetForwarder.handleMessage( + NATIVE_TOKEN, + amount, + assetForwarderData, + batchTransaction.address, + { value: amount, gasLimit: 10000000 } + ); + + const balAfter = await ethers.provider.getBalance(deployer.address); + const sftmxBalAfter = await sftmx.balanceOf(deployer.address); + + expect(balAfter).lt(balBefore); + expect(sftmxBalAfter).gt(sftmxBalBefore); + }); + + it("Can stake FTM on Stader on dest chain when instruction is received directly on StaderStakeFtm adapter", async () => { + const { staderStakeFtmAdapter, sftmx, mockAssetForwarder } = + await setupTests(); + + const amount = ethers.utils.parseEther("1"); + + const data = defaultAbiCoder.encode(["address"], [deployer.address]); + + const balBefore = await ethers.provider.getBalance(deployer.address); + const sftmxBalBefore = await sftmx.balanceOf(deployer.address); + + await mockAssetForwarder.handleMessage( + NATIVE_TOKEN, + amount, + data, + staderStakeFtmAdapter.address, + { value: amount, gasLimit: 1000000 } + ); + + const balAfter = await ethers.provider.getBalance(deployer.address); + const sftmxBalAfter = await sftmx.balanceOf(deployer.address); + + expect(balAfter).lt(balBefore); + expect(sftmxBalAfter).gt(sftmxBalBefore); + }); +}); diff --git a/evm/test/Stader/StaderStakeMatic.specs.ts b/evm/test/Stader/StaderStakeMatic.specs.ts new file mode 100644 index 0000000..f112a5e --- /dev/null +++ b/evm/test/Stader/StaderStakeMatic.specs.ts @@ -0,0 +1,215 @@ +import hardhat, { ethers, waffle } from "hardhat"; +import { expect } from "chai"; +import { RPC } from "../constants"; +import { DEXSPAN, DEFAULT_ENV, WNATIVE } from "../../tasks/constants"; +import { StaderStakeMatic__factory } from "../../typechain/factories/StaderStakeMatic__factory"; +import { TokenInterface__factory } from "../../typechain/factories/TokenInterface__factory"; +import { MockAssetForwarder__factory } from "../../typechain/factories/MockAssetForwarder__factory"; +import { BatchTransaction__factory } from "../../typechain/factories/BatchTransaction__factory"; +import { BigNumber, Contract, Wallet } from "ethers"; +import { defaultAbiCoder } from "ethers/lib/utils"; + +const CHAIN_ID = "1"; +const STADER_X_TOKEN = "0xf03A7Eb46d01d9EcAA104558C732Cf82f6B6B645"; +const NATIVE_TOKEN = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"; +const MATIC_TOKEN = "0x7D1AfA7B718fb893dB30A3aBc0Cfc608AaCfeBB0"; +const USDT = "0xdac17f958d2ee523a2206206994597c13d831ec7"; + +describe("StaderStakeMatic Adapter: ", async () => { + const [deployer] = waffle.provider.getWallets(); + + const setupTests = async () => { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + const MockAssetForwarder = await ethers.getContractFactory( + "MockAssetForwarder" + ); + const mockAssetForwarder = await MockAssetForwarder.deploy(); + + const BatchTransaction = await ethers.getContractFactory( + "BatchTransaction" + ); + + const batchTransaction = await BatchTransaction.deploy( + NATIVE_TOKEN, + WNATIVE[env][CHAIN_ID], + mockAssetForwarder.address, + DEXSPAN[env][CHAIN_ID] + ); + + const StaderStakeMatic = await ethers.getContractFactory( + "StaderStakeMatic" + ); + const staderStakeMaticAdapter = await StaderStakeMatic.deploy( + NATIVE_TOKEN, + WNATIVE[env][CHAIN_ID], + deployer.address, + mockAssetForwarder.address, + DEXSPAN[env][CHAIN_ID], + STADER_X_TOKEN, + MATIC_TOKEN + ); + + return { + batchTransaction: BatchTransaction__factory.connect( + batchTransaction.address, + deployer + ), + staderStakeMaticAdapter: StaderStakeMatic__factory.connect( + staderStakeMaticAdapter.address, + deployer + ), + mockAssetForwarder: MockAssetForwarder__factory.connect( + mockAssetForwarder.address, + deployer + ), + usdt: TokenInterface__factory.connect(USDT, deployer), + maticx: TokenInterface__factory.connect(STADER_X_TOKEN, deployer), + matic: TokenInterface__factory.connect(MATIC_TOKEN, deployer), + }; + }; + + beforeEach(async function () { + await hardhat.network.provider.request({ + method: "hardhat_reset", + params: [ + { + forking: { + jsonRpcUrl: RPC[CHAIN_ID], + }, + }, + ], + }); + }); + + const toBytes32 = (bn: BigNumber) => { + return ethers.utils.hexlify(ethers.utils.zeroPad(bn.toHexString(), 32)); + }; + + // This works for token when it has balance mapping at slot 0. + const setUserTokenBalance = async ( + contract: Contract, + user: Wallet, + balance: BigNumber + ) => { + const index = ethers.utils.solidityKeccak256( + ["uint256", "uint256"], + [user.address, 0] // key, slot + ); + + await hardhat.network.provider.request({ + method: "hardhat_setStorageAt", + params: [contract.address, index, toBytes32(balance).toString()], + }); + + await hardhat.network.provider.request({ + method: "evm_mine", + params: [], + }); + }; + + it("Can stake on stader on same chain", async () => { + const { batchTransaction, staderStakeMaticAdapter, maticx, matic } = + await setupTests(); + + const amount = ethers.utils.parseEther("1"); + + const staderData = defaultAbiCoder.encode( + ["address", "uint256"], + [deployer.address, amount] + ); + + await setUserTokenBalance(matic, deployer, amount); + await matic.approve(batchTransaction.address, amount); + + const tokens = [MATIC_TOKEN]; + const amounts = [amount]; + const targets = [staderStakeMaticAdapter.address]; + const data = [staderData]; + const value = [0]; + const callType = [2]; + + const maticxBalBefore = await maticx.balanceOf(deployer.address); + + await batchTransaction.executeBatchCallsSameChain( + tokens, + amounts, + targets, + value, + callType, + data + ); + + const maticxBalAfter = await maticx.balanceOf(deployer.address); + + expect(maticxBalAfter).gt(maticxBalBefore); + }); + + it("Can stake Matic on Stader on dest chain when instruction is received from BatchTransaction contract", async () => { + const { + batchTransaction, + staderStakeMaticAdapter, + maticx, + mockAssetForwarder, + matic, + } = await setupTests(); + + const amount = ethers.utils.parseEther("1"); + + const targets = [staderStakeMaticAdapter.address]; + const data = [ + defaultAbiCoder.encode( + ["address", "uint256"], + [deployer.address, amount] + ), + ]; + const value = [0]; + const callType = [2]; + + const assetForwarderData = defaultAbiCoder.encode( + ["address", "address[]", "uint256[]", "uint256[]", "bytes[]"], + [deployer.address, targets, value, callType, data] + ); + const maticxBalBefore = await maticx.balanceOf(deployer.address); + + await setUserTokenBalance(matic, deployer, amount); + await matic.approve(mockAssetForwarder.address, amount); + + await mockAssetForwarder.handleMessage( + MATIC_TOKEN, + amount, + assetForwarderData, + batchTransaction.address, + { gasLimit: 1000000 } + ); + + const maticxBalAfter = await maticx.balanceOf(deployer.address); + + expect(maticxBalAfter).gt(maticxBalBefore); + }); + + it("Can stake MATIC on Stader on dest chain when instruction is received directly on StaderStakeMatic adapter", async () => { + const { staderStakeMaticAdapter, maticx, mockAssetForwarder, matic } = + await setupTests(); + + const amount = ethers.utils.parseEther("1"); + + const data = defaultAbiCoder.encode(["address"], [deployer.address]); + + const maticxBalBefore = await maticx.balanceOf(deployer.address); + await setUserTokenBalance(matic, deployer, amount); + await matic.approve(mockAssetForwarder.address, amount); + + await mockAssetForwarder.handleMessage( + MATIC_TOKEN, + amount, + data, + staderStakeMaticAdapter.address, + { gasLimit: 1000000 } + ); + + const maticxBalAfter = await maticx.balanceOf(deployer.address); + + expect(maticxBalAfter).gt(maticxBalBefore); + }); +}); diff --git a/evm/test/Stader/StaderStakePolygon.specs.ts b/evm/test/Stader/StaderStakePolygon.specs.ts new file mode 100644 index 0000000..ce8f553 --- /dev/null +++ b/evm/test/Stader/StaderStakePolygon.specs.ts @@ -0,0 +1,189 @@ +import hardhat, { ethers, waffle } from "hardhat"; +import { expect } from "chai"; +import { RPC } from "../constants"; +import { DEXSPAN, DEFAULT_ENV, WNATIVE } from "../../tasks/constants"; +import { StaderStakePolygon__factory } from "../../typechain/factories/StaderStakePolygon__factory"; +import { TokenInterface__factory } from "../../typechain/factories/TokenInterface__factory"; +import { MockAssetForwarder__factory } from "../../typechain/factories/MockAssetForwarder__factory"; +import { BatchTransaction__factory } from "../../typechain/factories/BatchTransaction__factory"; +import { defaultAbiCoder } from "ethers/lib/utils"; + +const CHAIN_ID = "137"; +const STADER_X_TOKEN = "0xfa68FB4628DFF1028CFEc22b4162FCcd0d45efb6"; +const STADER_POOL = "0xfd225C9e6601C9d38d8F98d8731BF59eFcF8C0E3"; +const NATIVE_TOKEN = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"; +const USDT = "0xc2132d05d31c914a87c6611c10748aeb04b58e8f"; + +describe("StaderStakePolygon Adapter: ", async () => { + const [deployer] = waffle.provider.getWallets(); + + const setupTests = async () => { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + const MockAssetForwarder = await ethers.getContractFactory( + "MockAssetForwarder" + ); + const mockAssetForwarder = await MockAssetForwarder.deploy(); + + const BatchTransaction = await ethers.getContractFactory( + "BatchTransaction" + ); + + const batchTransaction = await BatchTransaction.deploy( + NATIVE_TOKEN, + WNATIVE[env][CHAIN_ID], + mockAssetForwarder.address, + DEXSPAN[env][CHAIN_ID] + ); + + const StaderStakePolygon = await ethers.getContractFactory( + "StaderStakePolygon" + ); + const staderStakePolygonAdapter = await StaderStakePolygon.deploy( + NATIVE_TOKEN, + WNATIVE[env][CHAIN_ID], + deployer.address, + mockAssetForwarder.address, + DEXSPAN[env][CHAIN_ID], + STADER_X_TOKEN, + STADER_POOL + ); + + return { + batchTransaction: BatchTransaction__factory.connect( + batchTransaction.address, + deployer + ), + staderStakePolygonAdapter: StaderStakePolygon__factory.connect( + staderStakePolygonAdapter.address, + deployer + ), + mockAssetForwarder: MockAssetForwarder__factory.connect( + mockAssetForwarder.address, + deployer + ), + usdt: TokenInterface__factory.connect(USDT, deployer), + maticx: TokenInterface__factory.connect(STADER_X_TOKEN, deployer), + }; + }; + + beforeEach(async function () { + await hardhat.network.provider.request({ + method: "hardhat_reset", + params: [ + { + forking: { + jsonRpcUrl: RPC[CHAIN_ID], + }, + }, + ], + }); + }); + + it("Can stake on stader on same chain", async () => { + const { batchTransaction, staderStakePolygonAdapter, maticx } = + await setupTests(); + + const amount = ethers.utils.parseEther("1"); + + const staderData = defaultAbiCoder.encode( + ["address", "uint256"], + [deployer.address, amount] + ); + + const tokens = [NATIVE_TOKEN]; + const amounts = [amount]; + const targets = [staderStakePolygonAdapter.address]; + const data = [staderData]; + const value = [0]; + const callType = [2]; + + const balBefore = await ethers.provider.getBalance(deployer.address); + const maticxBalBefore = await maticx.balanceOf(deployer.address); + + await batchTransaction.executeBatchCallsSameChain( + tokens, + amounts, + targets, + value, + callType, + data, + { value: amount } + ); + + const balAfter = await ethers.provider.getBalance(deployer.address); + const maticxBalAfter = await maticx.balanceOf(deployer.address); + + expect(balBefore).gt(balAfter); + expect(maticxBalAfter).gt(maticxBalBefore); + }); + + it("Can stake Matic on Stader on dest chain when instruction is received from BatchTransaction contract", async () => { + const { + batchTransaction, + staderStakePolygonAdapter, + maticx, + mockAssetForwarder, + } = await setupTests(); + + const amount = "100000000000000000"; + + const targets = [staderStakePolygonAdapter.address]; + const data = [ + defaultAbiCoder.encode( + ["address", "uint256"], + [deployer.address, amount] + ), + ]; + const value = [0]; + const callType = [2]; + + const assetForwarderData = defaultAbiCoder.encode( + ["address", "address[]", "uint256[]", "uint256[]", "bytes[]"], + [deployer.address, targets, value, callType, data] + ); + + const balBefore = await ethers.provider.getBalance(deployer.address); + const maticxBalBefore = await maticx.balanceOf(deployer.address); + + await mockAssetForwarder.handleMessage( + NATIVE_TOKEN, + amount, + assetForwarderData, + batchTransaction.address, + { value: amount } + ); + + const balAfter = await ethers.provider.getBalance(deployer.address); + const maticxBalAfter = await maticx.balanceOf(deployer.address); + + expect(balAfter).lt(balBefore); + expect(maticxBalAfter).gt(maticxBalBefore); + }); + + it("Can stake MATIC on Stader on dest chain when instruction is received directly on StaderStakePolygon adapter", async () => { + const { staderStakePolygonAdapter, maticx, mockAssetForwarder } = + await setupTests(); + + const amount = "100000000000000000"; + + const data = defaultAbiCoder.encode(["address"], [deployer.address]); + + const balBefore = await ethers.provider.getBalance(deployer.address); + const maticxBalBefore = await maticx.balanceOf(deployer.address); + + await mockAssetForwarder.handleMessage( + NATIVE_TOKEN, + amount, + data, + staderStakePolygonAdapter.address, + { value: amount } + ); + + const balAfter = await ethers.provider.getBalance(deployer.address); + const maticxBalAfter = await maticx.balanceOf(deployer.address); + + expect(balAfter).lt(balBefore); + expect(maticxBalAfter).gt(maticxBalBefore); + }); +}); diff --git a/evm/test/Swell/SwellStakeEth.specs.ts b/evm/test/Swell/SwellStakeEth.specs.ts new file mode 100644 index 0000000..b9430b1 --- /dev/null +++ b/evm/test/Swell/SwellStakeEth.specs.ts @@ -0,0 +1,234 @@ +import hardhat, { ethers, waffle } from "hardhat"; +import { expect } from "chai"; +import { RPC } from "../constants"; +import { + DEXSPAN, + DEFAULT_ENV, + NATIVE, + WNATIVE, + DEFAULT_REFUND_ADDRESS, +} from "../../tasks/constants"; +import { SwellStakeEth__factory } from "../../typechain/factories/SwellStakeEth__factory"; +import { TokenInterface__factory } from "../../typechain/factories/TokenInterface__factory"; +import { MockAssetForwarder__factory } from "../../typechain/factories/MockAssetForwarder__factory"; +import { BatchTransaction__factory } from "../../typechain/factories/BatchTransaction__factory"; +import { BigNumber, Contract, Wallet } from "ethers"; +import { getPathfinderData } from "../utils"; +import { defaultAbiCoder } from "ethers/lib/utils"; +import { DexSpanAdapter__factory } from "../../typechain/factories/DexSpanAdapter__factory"; + +const CHAIN_ID = "1"; +const SW_TOKEN = "0xf951E335afb289353dc249e82926178EaC7DEd78"; +const NATIVE_TOKEN = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"; +const USDT = "0xdac17f958d2ee523a2206206994597c13d831ec7"; + +describe("SwellStakeEth Adapter: ", async () => { + const [deployer] = waffle.provider.getWallets(); + + const setupTests = async () => { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + const MockAssetForwarder = await ethers.getContractFactory( + "MockAssetForwarder" + ); + const mockAssetForwarder = await MockAssetForwarder.deploy(); + + const BatchTransaction = await ethers.getContractFactory( + "BatchTransaction" + ); + + const batchTransaction = await BatchTransaction.deploy( + NATIVE, + WNATIVE[env][CHAIN_ID], + mockAssetForwarder.address, + DEXSPAN[env][CHAIN_ID] + ); + + const DexSpanAdapter = await ethers.getContractFactory("DexSpanAdapter"); + const dexSpanAdapter = await DexSpanAdapter.deploy( + NATIVE, + WNATIVE[env][CHAIN_ID], + deployer.address, + mockAssetForwarder.address, + DEXSPAN[env][CHAIN_ID], + DEFAULT_REFUND_ADDRESS + ); + + const SwellStakeEth = await ethers.getContractFactory("SwellStakeEth"); + const swellStakeEthAdapter = await SwellStakeEth.deploy( + NATIVE, + WNATIVE[env][CHAIN_ID], + deployer.address, + mockAssetForwarder.address, + DEXSPAN[env][CHAIN_ID], + SW_TOKEN, + ); + + return { + batchTransaction: BatchTransaction__factory.connect( + batchTransaction.address, + deployer + ), + swellStakeEthAdapter: SwellStakeEth__factory.connect( + swellStakeEthAdapter.address, + deployer + ), + dexSpanAdapter: DexSpanAdapter__factory.connect( + dexSpanAdapter.address, + deployer + ), + mockAssetForwarder: MockAssetForwarder__factory.connect( + mockAssetForwarder.address, + deployer + ), + usdt: TokenInterface__factory.connect(USDT, deployer), + swEth: TokenInterface__factory.connect(SW_TOKEN, deployer), + }; + }; + + beforeEach(async function () { + await hardhat.network.provider.request({ + method: "hardhat_reset", + params: [ + { + forking: { + jsonRpcUrl: RPC[CHAIN_ID], + }, + }, + ], + }); + }); + + const toBytes32 = (bn: BigNumber) => { + return ethers.utils.hexlify(ethers.utils.zeroPad(bn.toHexString(), 32)); + }; + + // This works for token when it has balance mapping at slot 0. + const setUserTokenBalance = async ( + contract: Contract, + user: Wallet, + balance: BigNumber + ) => { + const index = ethers.utils.solidityKeccak256( + ["uint256", "uint256"], + [user.address, 0] // key, slot + ); + + await hardhat.network.provider.request({ + method: "hardhat_setStorageAt", + params: [contract.address, index, toBytes32(balance).toString()], + }); + + await hardhat.network.provider.request({ + method: "evm_mine", + params: [], + }); + }; + + it("Can stake on swell on same chain", async () => { + const { batchTransaction, swellStakeEthAdapter, swEth } = + await setupTests(); + + const amount = ethers.utils.parseEther("1"); + + const swellData = defaultAbiCoder.encode( + ["address", "uint256"], + [deployer.address, amount] + ); + + const tokens = [NATIVE_TOKEN]; + const amounts = [amount]; + const targets = [swellStakeEthAdapter.address]; + const data = [swellData]; + const value = [0]; + const callType = [2]; + + const balBefore = await ethers.provider.getBalance(deployer.address); + const swEthBalBefore = await swEth.balanceOf(deployer.address); + + await batchTransaction.executeBatchCallsSameChain( + tokens, + amounts, + targets, + value, + callType, + data, + { value: amount } + ); + + const balAfter = await ethers.provider.getBalance(deployer.address); + const swEthBalAfter = await swEth.balanceOf(deployer.address); + + expect(balBefore).gt(balAfter); + expect(swEthBalAfter).gt(swEthBalBefore); + }); + + it("Can stake ETH on Swell on dest chain when instruction is received from BatchTransaction contract", async () => { + const { + batchTransaction, + swellStakeEthAdapter, + swEth, + mockAssetForwarder, + } = await setupTests(); + + const amount = "100000000000000000"; + + const targets = [swellStakeEthAdapter.address]; + const data = [ + defaultAbiCoder.encode( + ["address", "uint256"], + [deployer.address, amount] + ), + ]; + const value = [0]; + const callType = [2]; + + const assetForwarderData = defaultAbiCoder.encode( + ["address", "address[]", "uint256[]", "uint256[]", "bytes[]"], + [deployer.address, targets, value, callType, data] + ); + + const balBefore = await ethers.provider.getBalance(deployer.address); + const swEthBalBefore = await swEth.balanceOf(deployer.address); + + await mockAssetForwarder.handleMessage( + NATIVE_TOKEN, + amount, + assetForwarderData, + batchTransaction.address, + { value: amount } + ); + + const balAfter = await ethers.provider.getBalance(deployer.address); + const swEthBalAfter = await swEth.balanceOf(deployer.address); + + expect(balAfter).lt(balBefore); + expect(swEthBalAfter).gt(swEthBalBefore); + }); + + it("Can stake ETH on Swell on dest chain when instruction is received directly on SwellStakeEth adapter", async () => { + const { swellStakeEthAdapter, swEth, mockAssetForwarder } = + await setupTests(); + + const amount = "100000000000000000"; + + const data = defaultAbiCoder.encode(["address"], [deployer.address]); + + const balBefore = await ethers.provider.getBalance(deployer.address); + const swEthBalBefore = await swEth.balanceOf(deployer.address); + + await mockAssetForwarder.handleMessage( + NATIVE_TOKEN, + amount, + data, + swellStakeEthAdapter.address, + { value: amount } + ); + + const balAfter = await ethers.provider.getBalance(deployer.address); + const swEthBalAfter = await swEth.balanceOf(deployer.address); + + expect(balAfter).lt(balBefore); + expect(swEthBalAfter).gt(swEthBalBefore); + }); +}); diff --git a/evm/test/SynClub/SynClubStakeBnb.specs.ts b/evm/test/SynClub/SynClubStakeBnb.specs.ts new file mode 100644 index 0000000..482033b --- /dev/null +++ b/evm/test/SynClub/SynClubStakeBnb.specs.ts @@ -0,0 +1,187 @@ +import hardhat, { ethers, waffle } from "hardhat"; +import { expect } from "chai"; +import { RPC } from "../constants"; +import { DEXSPAN, DEFAULT_ENV, WNATIVE } from "../../tasks/constants"; +import { SynClubStakeBnb__factory } from "../../typechain/factories/SynClubStakeBnb__factory"; +import { TokenInterface__factory } from "../../typechain/factories/TokenInterface__factory"; +import { MockAssetForwarder__factory } from "../../typechain/factories/MockAssetForwarder__factory"; +import { BatchTransaction__factory } from "../../typechain/factories/BatchTransaction__factory"; +import { defaultAbiCoder } from "ethers/lib/utils"; + +const CHAIN_ID = "56"; +const SYNCLUB_TOKEN = "0xB0b84D294e0C75A6abe60171b70edEb2EFd14A1B"; +const SYNCLUB_POOL = "0x1adB950d8bB3dA4bE104211D5AB038628e477fE6"; +const NATIVE_TOKEN = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"; +const USDT = "0x55d398326f99059ff775485246999027b3197955"; + +describe("SynClubStakeBnb Adapter: ", async () => { + const [deployer] = waffle.provider.getWallets(); + + const setupTests = async () => { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + const MockAssetForwarder = await ethers.getContractFactory( + "MockAssetForwarder" + ); + const mockAssetForwarder = await MockAssetForwarder.deploy(); + + const BatchTransaction = await ethers.getContractFactory( + "BatchTransaction" + ); + + const batchTransaction = await BatchTransaction.deploy( + NATIVE_TOKEN, + WNATIVE[env][CHAIN_ID], + mockAssetForwarder.address, + DEXSPAN[env][CHAIN_ID] + ); + + const SynClubStakeBnb = await ethers.getContractFactory("SynClubStakeBnb"); + const synClubStakeBnbAdapter = await SynClubStakeBnb.deploy( + NATIVE_TOKEN, + WNATIVE[env][CHAIN_ID], + deployer.address, + mockAssetForwarder.address, + DEXSPAN[env][CHAIN_ID], + SYNCLUB_TOKEN, + SYNCLUB_POOL + ); + + return { + batchTransaction: BatchTransaction__factory.connect( + batchTransaction.address, + deployer + ), + synClubStakeBnbAdapter: SynClubStakeBnb__factory.connect( + synClubStakeBnbAdapter.address, + deployer + ), + mockAssetForwarder: MockAssetForwarder__factory.connect( + mockAssetForwarder.address, + deployer + ), + usdt: TokenInterface__factory.connect(USDT, deployer), + snBnb: TokenInterface__factory.connect(SYNCLUB_TOKEN, deployer), + }; + }; + + beforeEach(async function () { + await hardhat.network.provider.request({ + method: "hardhat_reset", + params: [ + { + forking: { + jsonRpcUrl: RPC[CHAIN_ID], + }, + }, + ], + }); + }); + + it("Can stake on synClub on same chain", async () => { + const { batchTransaction, synClubStakeBnbAdapter, snBnb } = + await setupTests(); + + const amount = ethers.utils.parseEther("1"); + + const synClubData = defaultAbiCoder.encode( + ["address", "uint256"], + [deployer.address, amount] + ); + + const tokens = [NATIVE_TOKEN]; + const amounts = [amount]; + const targets = [synClubStakeBnbAdapter.address]; + const data = [synClubData]; + const value = [0]; + const callType = [2]; + + const balBefore = await ethers.provider.getBalance(deployer.address); + const snBnbBalBefore = await snBnb.balanceOf(deployer.address); + + await batchTransaction.executeBatchCallsSameChain( + tokens, + amounts, + targets, + value, + callType, + data, + { value: amount } + ); + + const balAfter = await ethers.provider.getBalance(deployer.address); + const snBnbBalAfter = await snBnb.balanceOf(deployer.address); + + expect(balBefore).gt(balAfter); + expect(snBnbBalAfter).gt(snBnbBalBefore); + }); + + it("Can stake BNB on SynClub on dest chain when instruction is received from BatchTransaction contract", async () => { + const { + batchTransaction, + synClubStakeBnbAdapter, + snBnb, + mockAssetForwarder, + } = await setupTests(); + + const amount = "100000000000000000"; + + const targets = [synClubStakeBnbAdapter.address]; + const data = [ + defaultAbiCoder.encode( + ["address", "uint256"], + [deployer.address, amount] + ), + ]; + const value = [0]; + const callType = [2]; + + const assetForwarderData = defaultAbiCoder.encode( + ["address", "address[]", "uint256[]", "uint256[]", "bytes[]"], + [deployer.address, targets, value, callType, data] + ); + + const balBefore = await ethers.provider.getBalance(deployer.address); + const snBnbBalBefore = await snBnb.balanceOf(deployer.address); + + await mockAssetForwarder.handleMessage( + NATIVE_TOKEN, + amount, + assetForwarderData, + batchTransaction.address, + { value: amount } + ); + + const balAfter = await ethers.provider.getBalance(deployer.address); + const snBnbBalAfter = await snBnb.balanceOf(deployer.address); + + expect(balAfter).lt(balBefore); + expect(snBnbBalAfter).gt(snBnbBalBefore); + }); + + it("Can stake BNB on SynClub on dest chain when instruction is received directly on SynClubStakeBnb adapter", async () => { + const { synClubStakeBnbAdapter, snBnb, mockAssetForwarder } = + await setupTests(); + + const amount = "100000000000000000"; + + const data = defaultAbiCoder.encode(["address"], [deployer.address]); + + const balBefore = await ethers.provider.getBalance(deployer.address); + const snBnbBalBefore = await snBnb.balanceOf(deployer.address); + + await mockAssetForwarder.handleMessage( + NATIVE_TOKEN, + amount, + data, + synClubStakeBnbAdapter.address, + { value: amount } + ); + + const balAfter = await ethers.provider.getBalance(deployer.address); + const snBnbBalAfter = await snBnb.balanceOf(deployer.address); + + expect(balAfter).lt(balBefore); + expect(snBnbBalAfter).gt(snBnbBalBefore); + }); +}); diff --git a/evm/test/UniswapV3/UniswapV3MintPosition.specs.ts b/evm/test/UniswapV3/UniswapV3MintPosition.specs.ts new file mode 100644 index 0000000..afe33ca --- /dev/null +++ b/evm/test/UniswapV3/UniswapV3MintPosition.specs.ts @@ -0,0 +1,203 @@ +import hardhat, { ethers, waffle } from "hardhat"; +import { expect } from "chai"; +import { defaultAbiCoder } from "ethers/lib/utils"; +import { RPC } from "../constants"; +import { + DEXSPAN, + DEFAULT_ENV, + DEFAULT_REFUND_ADDRESS, +} from "../../tasks/constants"; +import { UniswapV3Mint__factory } from "../../typechain/factories/UniswapV3Mint__factory"; +import { TokenInterface__factory } from "../../typechain/factories/TokenInterface__factory"; +import { MockAssetForwarder__factory } from "../../typechain/factories/MockAssetForwarder__factory"; +import { BatchTransaction__factory } from "../../typechain/factories/BatchTransaction__factory"; +import { IWETH__factory } from "../../typechain/factories/IWETH__factory"; +import { IUniswapV3NonfungiblePositionManager__factory } from "../../typechain/factories/IUniswapV3NonfungiblePositionManager__factory"; +import { BigNumber, Contract, Wallet } from "ethers"; +import { getUniswapV3Data } from "./utils"; +import { decodeExecutionEvent } from "../utils"; + +const CHAIN_ID = "5"; +const UNISWAP_V3_POSITION_MANAGER = + "0xC36442b4a4522E871399CD717aBDD847Ab11FE88"; +const USDT = "0x2227E4764be4c858E534405019488D9E5890Ff9E"; +const NATIVE_TOKEN = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"; +const WNATIVE = "0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6"; + +describe("UniswapV3Mint Adapter: ", async () => { + const [deployer] = waffle.provider.getWallets(); + + const setupTests = async () => { + let env = process.env.ENV; + if (!env) env = DEFAULT_ENV; + const MockAssetForwarder = await ethers.getContractFactory( + "MockAssetForwarder" + ); + const mockAssetForwarder = await MockAssetForwarder.deploy(); + + const BatchTransaction = await ethers.getContractFactory( + "BatchTransaction" + ); + + const batchTransaction = await BatchTransaction.deploy( + NATIVE_TOKEN, + WNATIVE, + mockAssetForwarder.address, + DEXSPAN[env][CHAIN_ID] + ); + + const UniswapV3MintPositionAdapter = await ethers.getContractFactory( + "UniswapV3Mint" + ); + const uniswapV3MintPositionAdapter = + await UniswapV3MintPositionAdapter.deploy( + NATIVE_TOKEN, + WNATIVE, + deployer.address, + mockAssetForwarder.address, + DEXSPAN[env][CHAIN_ID], + DEFAULT_REFUND_ADDRESS, + UNISWAP_V3_POSITION_MANAGER + ); + + const MockToken = await ethers.getContractFactory("MockToken"); + const mockToken = await MockToken.deploy(); + await mockToken.mint(deployer.address, ethers.utils.parseEther("10000")); + + return { + batchTransaction: BatchTransaction__factory.connect( + batchTransaction.address, + deployer + ), + uniswapV3MintPositionAdapter: UniswapV3Mint__factory.connect( + uniswapV3MintPositionAdapter.address, + deployer + ), + mockToken: TokenInterface__factory.connect(mockToken.address, deployer), + mockAssetForwarder: MockAssetForwarder__factory.connect( + mockAssetForwarder.address, + deployer + ), + usdt: TokenInterface__factory.connect(USDT, deployer), + wnative: IWETH__factory.connect(WNATIVE, deployer), + positionManager: IUniswapV3NonfungiblePositionManager__factory.connect( + UNISWAP_V3_POSITION_MANAGER, + deployer + ), + }; + }; + + beforeEach(async function () { + await hardhat.network.provider.request({ + method: "hardhat_reset", + params: [ + { + forking: { + jsonRpcUrl: RPC[CHAIN_ID], + }, + }, + ], + }); + }); + + const toBytes32 = (bn: BigNumber) => { + return ethers.utils.hexlify(ethers.utils.zeroPad(bn.toHexString(), 32)); + }; + + // This works for token when it has balance mapping at slot 0. + const setUserTokenBalance = async ( + contract: Contract, + user: Wallet, + balance: BigNumber + ) => { + const index = ethers.utils.solidityKeccak256( + ["uint256", "uint256"], + [user.address, 0] // key, slot + ); + + await hardhat.network.provider.request({ + method: "hardhat_setStorageAt", + params: [contract.address, index, toBytes32(balance).toString()], + }); + + await hardhat.network.provider.request({ + method: "evm_mine", + params: [], + }); + }; + + it("Can mint a new position on Uniswap", async () => { + const { + batchTransaction, + uniswapV3MintPositionAdapter, + positionManager, + usdt, + wnative, + } = await setupTests(); + + await wnative.deposit({ value: ethers.utils.parseEther("10") }); + await setUserTokenBalance(usdt, deployer, ethers.utils.parseEther("10")); + + const user = deployer; + const chainId = CHAIN_ID; + const token0 = wnative.address; + const token1 = usdt.address; + const amount0 = ethers.utils.parseEther("0.1").toString(); + const amount1 = "1000000000".toString(); + const fee = 3000; + + const mintParams = await getUniswapV3Data({ + user, + chainId, + token0, + token1, + amount0, + amount1, + fee, + }); + + const mintParamsIface = + "tuple(address token0, address token1, uint24 fee, int24 tickLower, int24 tickUpper, uint256 amount0Desired, uint256 amount1Desired, uint256 amount0Min, uint256 amount1Min, address recipient, uint256 deadline) MintParams"; + + const uniswapData = defaultAbiCoder.encode([mintParamsIface], [mintParams]); + + const tokens = [mintParams.token0, mintParams.token1]; + const amounts = [mintParams.amount0Desired, mintParams.amount1Desired]; + + if (mintParams.token0 === wnative.address) { + await wnative.approve( + batchTransaction.address, + mintParams.amount0Desired + ); + await usdt.approve(batchTransaction.address, mintParams.amount1Desired); + } else { + await usdt.approve(batchTransaction.address, mintParams.amount0Desired); + await wnative.approve( + batchTransaction.address, + mintParams.amount1Desired + ); + } + + const tx = await batchTransaction.executeBatchCallsSameChain( + tokens, + amounts, + [uniswapV3MintPositionAdapter.address], + [0], + [2], + [uniswapData] + ); + const txReceipt = await tx.wait(); + + const { data: uniswapExecutionEventData } = decodeExecutionEvent(txReceipt); + + const uniswapEventData = defaultAbiCoder.decode( + [mintParamsIface, "uint256"], + uniswapExecutionEventData + ); + + const position = await positionManager.positions(uniswapEventData[1]); + expect(position.token0).eq(mintParams.token0); + expect(position.token1).eq(mintParams.token1); + expect(position.fee).eq(mintParams.fee); + }); +}); diff --git a/evm/test/UniswapV3/utils.ts b/evm/test/UniswapV3/utils.ts new file mode 100644 index 0000000..f4f4324 --- /dev/null +++ b/evm/test/UniswapV3/utils.ts @@ -0,0 +1,233 @@ +/* eslint-disable node/no-unsupported-features/es-syntax */ +import { Percent, Token } from "@uniswap/sdk-core"; +import { abi as IUniswapV3PoolABI } from "@uniswap/v3-core/artifacts/contracts/interfaces/IUniswapV3Pool.sol/IUniswapV3Pool.json"; +import { + FeeAmount, + Pool, + Position, + TICK_SPACINGS, + computePoolAddress, + nearestUsableTick, +} from "@uniswap/v3-sdk"; +import { Contract, Wallet } from "ethers"; +import { TokenInterface__factory } from "../../typechain/factories/TokenInterface__factory"; + +const UNISWAP_V3_FACTORY: { [chainId: string]: string } = { + "80001": "0x1F98431c8aD98523631AE4a59f267346ea31F984", + "5": "0x1F98431c8aD98523631AE4a59f267346ea31F984", +}; + +interface PoolDataResponse { + pool: string; + token0: Token; + token1: Token; + tick: number; + sqrtPriceX96: string; + liquidity: string; + initialized?: boolean; +} + +export const getPoolData = async ( + user: Wallet, + chainId: string, + token0: string, + token1: string, + fee: number +): Promise => { + const provider = user.provider; + const tokenAAddress = token0; + const tokenBAddress = token1; + const poolFee = fee; + + const factoryAddress = UNISWAP_V3_FACTORY[chainId]; + + const tokenAContract = TokenInterface__factory.connect(token0, user); + const tokenBContract = TokenInterface__factory.connect(token1, user); + + const [tokenADecimals, tokenBDecimals] = await Promise.all([ + tokenAContract.decimals(), + tokenBContract.decimals(), + ]); + + const tokenA = new Token( + Number(chainId), + tokenAAddress, + Number(tokenADecimals) + ); + const tokenB = new Token( + Number(chainId), + tokenBAddress, + Number(tokenBDecimals) + ); + + let uniToken0: Token, uniToken1: Token; + if (tokenA.sortsBefore(tokenB)) { + uniToken0 = tokenA; + uniToken1 = tokenB; + } else { + uniToken0 = tokenB; + uniToken1 = tokenA; + } + + const currentPoolAddress = computePoolAddress({ + factoryAddress, + tokenA: uniToken0, + tokenB: uniToken1, + fee: poolFee, + }); + + const poolContract = new Contract( + currentPoolAddress, + IUniswapV3PoolABI, + provider + ); + + const code = await provider.getCode(currentPoolAddress); + if (code === "0x" || !code) { + return { + pool: currentPoolAddress, + token0: uniToken0, + token1: uniToken1, + tick: 0, + sqrtPriceX96: "0", + liquidity: "0", + initialized: false, + }; + } + + const [liquidity, slot0] = await Promise.all([ + poolContract.liquidity(), + poolContract.slot0(), + ]); + + return { + pool: currentPoolAddress, + token0: uniToken0, + token1: uniToken1, + tick: Number(slot0.tick), + sqrtPriceX96: slot0.sqrtPriceX96.toString(), + liquidity: liquidity.toString(), + initialized: true, + }; +}; + +const getPool = async ( + token0: Token, + token1: Token, + poolFee: FeeAmount, + poolAddress: string, + user: Wallet +) => { + const provider = user.provider; + // get liquidity, tick, sqrtPriceX96, fee, token0, token1 + const poolContract = new Contract(poolAddress, IUniswapV3PoolABI, user); + + let liquidity, slot0; + + const code = await provider.getCode(poolAddress); + if (code === "0x" || !code) { + liquidity = 0n; + slot0 = { + tick: 0, + sqrtPriceX96: 0n, + }; + } else { + [liquidity, slot0] = await Promise.all([ + poolContract.liquidity(), + poolContract.slot0(), + ]); + } + + liquidity = liquidity.toString(); + const sqrtPriceX96: string = slot0.sqrtPriceX96.toString(); + + const tick = Number(slot0.tick); + + return new Pool(token0, token1, poolFee, sqrtPriceX96, liquidity, tick); +}; + +export const getUniswapV3Data = async (data: { + user: Wallet; + chainId: string; + token0: string; + token1: string; + amount0: string; + amount1: string; + fee: number; + deadline?: number; +}) => { + const { + pool: poolAddress, + token0, + token1, + tick, + } = await getPoolData( + data.user, + data.chainId, + data.token0, + data.token1, + data.fee + ); + + const poolFee = data.fee as FeeAmount; + const tickSpacing = TICK_SPACINGS[poolFee]; + const tickLower = nearestUsableTick(tick - 10000, tickSpacing); + const tickUpper = nearestUsableTick(tick + 10000, tickSpacing); + + const pool = await getPool(token0, token1, data.fee, poolAddress, data.user); + + // const position = Position.fromAmounts({ + // pool, + // tickLower: tickLower, + // tickUpper: tickUpper, + // amount0: ethers.utils.parseEther("100000000").toString(), + // amount1: ethers.utils.parseEther("100000000").toString(), + // useFullPrecision: true, + // }); + const position = Position.fromAmount0({ + pool, + tickLower: tickLower, + tickUpper: tickUpper, + amount0: data.amount0.toString(), + useFullPrecision: true, + }); + + // get token0 amount and token1 amount. calculate ratio of token0 and token1 + const token0Amount = position.mintAmounts.amount0; + const token1Amount = position.mintAmounts.amount1; + + // Current price is out of range of tickLower and tickUpper + if (token0Amount.toString() === "0" || token1Amount.toString() === "0") { + throw new Error("Price out of range"); + } else { + const minPosition = Position.fromAmounts({ + pool, + tickLower: tickLower, + tickUpper: tickUpper, + amount0: data.amount0, + amount1: data.amount1, + useFullPrecision: true, + }); + + const minOutputAmounts = minPosition.mintAmounts; + const minOutputAmountsWithSlippage = minPosition.mintAmountsWithSlippage( + new Percent(1, 100) + ); + + return { + token0: token0.address, + token1: token1.address, + fee: poolFee, + tickLower: tickLower, + tickUpper: tickUpper, + amount0Desired: minOutputAmounts.amount0.toString(), + amount1Desired: minOutputAmounts.amount1.toString(), + amount0Min: minOutputAmountsWithSlippage.amount0.toString(), + amount1Min: minOutputAmountsWithSlippage.amount1.toString(), + recipient: data.user.address, + deadline: data.deadline + ? data.deadline + : Math.floor(Date.now() / 1000) + 60 * 20, + }; + } +}; diff --git a/evm/test/constants.ts b/evm/test/constants.ts new file mode 100644 index 0000000..ac47406 --- /dev/null +++ b/evm/test/constants.ts @@ -0,0 +1,13 @@ +export const RPC: { [networkId: string]: string } = { + "1": "https://rpc.ankr.com/eth", + "56": "https://rpc.ankr.com/bsc", + "250": "https://fantom-mainnet.public.blastapi.io", + "42161": "https://arbitrum.llamarpc.com", + "137": "https://rpc-mainnet.matic.quiknode.pro", + "10": "https://optimism-mainnet.public.blastapi.io", + "43114": "https://avalanche.public-rpc.com", + "8453": "https://base.meowrpc.com", + "5": "https://rpc.ankr.com/eth_goerli", + "80001": "https://polygon-mumbai-bor.publicnode.com", + "17000": "https://ethereum-holesky.publicnode.com", +}; diff --git a/evm/test/utils.ts b/evm/test/utils.ts new file mode 100644 index 0000000..883c530 --- /dev/null +++ b/evm/test/utils.ts @@ -0,0 +1,118 @@ +/* eslint-disable node/no-unsupported-features/es-syntax */ +import axios from "axios"; +import { defaultAbiCoder } from "ethers/lib/utils"; +import { NATIVE } from "../tasks/constants"; +import { ContractReceipt, ethers } from "ethers"; + +const PATH_FINDER_API_URL = "https://api.pf.testnet.routerprotocol.com/api"; + +export const getPathfinderData = async ( + fromTokenAddress: string, + toTokenAddress: string, + amount: string, + fromTokenChainId: string, + toTokenChainId: string, + recipient: string +) => { + const quoteParams = { + fromTokenAddress, + toTokenAddress, + amount, + fromTokenChainId, + toTokenChainId, + }; + + const quoteData = await getQuote(quoteParams); + + if (toTokenAddress === NATIVE && fromTokenChainId === toTokenChainId) { + quoteData.source.path[quoteData.source.path.length - 1] = NATIVE; + } + + if (fromTokenAddress === NATIVE) { + quoteData.source.path[0] = NATIVE; + } + + const swapParamsIface = + "tuple(address[] tokens,uint256 amount,uint256 minReturn,uint256[] flags,bytes[] dataTx, address recipient) SwapParams"; + + const data = defaultAbiCoder.encode( + [swapParamsIface], + [ + { + tokens: quoteData?.source?.path, + amount, + minReturn: quoteData?.destination?.tokenAmount, + flags: quoteData?.source?.flags, + dataTx: quoteData?.source?.dataTx, + recipient, + }, + ] + ); + + return { + data: data, + minReturn: quoteData?.destination?.tokenAmount, + }; +}; + +const getQuote = async (params: any) => { + const endpoint = "v2/quote"; + const quoteUrl = `${PATH_FINDER_API_URL}/${endpoint}`; + + try { + const res = await axios.get(quoteUrl, { params }); + return res.data; + } catch (e) { + console.error(`Fetching quote data from pathfinder: ${e}`); + } +}; + +export const decodeUnsupportedOperationEvent = ( + txReceipt: ContractReceipt +): { token: string; refundAddress: string; refundAmount: string } => { + const EventInterface = new ethers.utils.Interface([ + "event UnsupportedOperation(address token,address refundAddress,uint256 amount)", + ]); + + const unsupportedOperationEvent = txReceipt.logs.filter( + (_log: any) => + _log.topics[0] === EventInterface.getEventTopic("UnsupportedOperation") + ); + + const eventData = EventInterface.decodeEventLog( + "UnsupportedOperation", + unsupportedOperationEvent[0].data, + unsupportedOperationEvent[0].topics + ); + + const [token, refundAddress, refundAmount] = [ + eventData[0], + eventData[1], + eventData[2], + ]; + + return { token, refundAddress, refundAmount }; +}; + +export const decodeExecutionEvent = ( + txReceipt: ContractReceipt +): { name: string; data: string } => { + const EventInterface = new ethers.utils.Interface([ + "event ExecutionEvent(string indexed adapterName, bytes data)", + ]); + + const executionEvent = txReceipt.logs.filter( + (_log: any) => + _log.topics[0] === EventInterface.getEventTopic("ExecutionEvent") + ); + + const eventData = EventInterface.decodeEventLog( + "ExecutionEvent", + executionEvent[0].data, + executionEvent[0].topics + ); + + // name is the hash of the string passed on the contract + // example: for UniswapV3Mint adapter, name is keccak256("UniswapV3Mint") + return { name: eventData[0], data: eventData[1] }; +}; diff --git a/evm/tsconfig.json b/evm/tsconfig.json new file mode 100644 index 0000000..b83a7c6 --- /dev/null +++ b/evm/tsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "target": "es2020", + "module": "commonjs", + "strict": true, + "esModuleInterop": true, + "outDir": "dist", + "declaration": true, + "resolveJsonModule": true + }, + "include": ["./hardhat.config.ts", "./scripts", "./tasks", "test"] +} diff --git a/evm/yarn.lock b/evm/yarn.lock new file mode 100644 index 0000000..246c8b5 --- /dev/null +++ b/evm/yarn.lock @@ -0,0 +1,8889 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@aashutoshrathi/word-wrap@^1.2.3": + version "1.2.6" + resolved "https://registry.yarnpkg.com/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz#bd9154aec9983f77b3a034ecaa015c2e4201f6cf" + integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA== + +"@babel/code-frame@7.12.11": + version "7.12.11" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f" + integrity sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw== + dependencies: + "@babel/highlight" "^7.10.4" + +"@babel/code-frame@^7.0.0": + version "7.22.13" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.22.13.tgz#e3c1c099402598483b7a8c46a721d1038803755e" + integrity sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w== + dependencies: + "@babel/highlight" "^7.22.13" + chalk "^2.4.2" + +"@babel/helper-validator-identifier@^7.22.20": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz#c4ae002c61d2879e724581d96665583dbc1dc0e0" + integrity sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A== + +"@babel/highlight@^7.10.4", "@babel/highlight@^7.22.13": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.22.20.tgz#4ca92b71d80554b01427815e06f2df965b9c1f54" + integrity sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg== + dependencies: + "@babel/helper-validator-identifier" "^7.22.20" + chalk "^2.4.2" + js-tokens "^4.0.0" + +"@babel/runtime@^7.4.4": + version "7.23.2" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.2.tgz#062b0ac103261d68a966c4c7baf2ae3e62ec3885" + integrity sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg== + dependencies: + regenerator-runtime "^0.14.0" + +"@chainsafe/as-sha256@^0.3.1": + version "0.3.1" + resolved "https://registry.yarnpkg.com/@chainsafe/as-sha256/-/as-sha256-0.3.1.tgz#3639df0e1435cab03f4d9870cc3ac079e57a6fc9" + integrity sha512-hldFFYuf49ed7DAakWVXSJODuq3pzJEguD8tQ7h+sGkM18vja+OFoJI9krnGmgzyuZC2ETX0NOIcCTy31v2Mtg== + +"@chainsafe/persistent-merkle-tree@^0.4.2": + version "0.4.2" + resolved "https://registry.yarnpkg.com/@chainsafe/persistent-merkle-tree/-/persistent-merkle-tree-0.4.2.tgz#4c9ee80cc57cd3be7208d98c40014ad38f36f7ff" + integrity sha512-lLO3ihKPngXLTus/L7WHKaw9PnNJWizlOF1H9NNzHP6Xvh82vzg9F2bzkXhYIFshMZ2gTCEz8tq6STe7r5NDfQ== + dependencies: + "@chainsafe/as-sha256" "^0.3.1" + +"@chainsafe/persistent-merkle-tree@^0.5.0": + version "0.5.0" + resolved "https://registry.yarnpkg.com/@chainsafe/persistent-merkle-tree/-/persistent-merkle-tree-0.5.0.tgz#2b4a62c9489a5739dedd197250d8d2f5427e9f63" + integrity sha512-l0V1b5clxA3iwQLXP40zYjyZYospQLZXzBVIhhr9kDg/1qHZfzzHw0jj4VPBijfYCArZDlPkRi1wZaV2POKeuw== + dependencies: + "@chainsafe/as-sha256" "^0.3.1" + +"@chainsafe/ssz@^0.10.0": + version "0.10.2" + resolved "https://registry.yarnpkg.com/@chainsafe/ssz/-/ssz-0.10.2.tgz#c782929e1bb25fec66ba72e75934b31fd087579e" + integrity sha512-/NL3Lh8K+0q7A3LsiFq09YXS9fPE+ead2rr7vM2QK8PLzrNsw3uqrif9bpRX5UxgeRjM+vYi+boCM3+GM4ovXg== + dependencies: + "@chainsafe/as-sha256" "^0.3.1" + "@chainsafe/persistent-merkle-tree" "^0.5.0" + +"@chainsafe/ssz@^0.9.2": + version "0.9.4" + resolved "https://registry.yarnpkg.com/@chainsafe/ssz/-/ssz-0.9.4.tgz#696a8db46d6975b600f8309ad3a12f7c0e310497" + integrity sha512-77Qtg2N1ayqs4Bg/wvnWfg5Bta7iy7IRh8XqXh7oNMeP2HBbBwx8m6yTpA8p0EHItWPEBkgZd5S5/LSlp3GXuQ== + dependencies: + "@chainsafe/as-sha256" "^0.3.1" + "@chainsafe/persistent-merkle-tree" "^0.4.2" + case "^1.6.3" + +"@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" + +"@ensdomains/address-encoder@^0.1.7": + version "0.1.9" + resolved "https://registry.yarnpkg.com/@ensdomains/address-encoder/-/address-encoder-0.1.9.tgz#f948c485443d9ef7ed2c0c4790e931c33334d02d" + integrity sha512-E2d2gP4uxJQnDu2Kfg1tHNspefzbLT8Tyjrm5sEuim32UkU2sm5xL4VXtgc2X33fmPEw9+jUMpGs4veMbf+PYg== + dependencies: + bech32 "^1.1.3" + blakejs "^1.1.0" + bn.js "^4.11.8" + bs58 "^4.0.1" + crypto-addr-codec "^0.1.7" + nano-base32 "^1.0.1" + ripemd160 "^2.0.2" + +"@ensdomains/ens@0.4.5": + version "0.4.5" + resolved "https://registry.yarnpkg.com/@ensdomains/ens/-/ens-0.4.5.tgz#e0aebc005afdc066447c6e22feb4eda89a5edbfc" + integrity sha512-JSvpj1iNMFjK6K+uVl4unqMoa9rf5jopb8cya5UGBWz23Nw8hSNT7efgUx4BTlAPAgpNlEioUfeTyQ6J9ZvTVw== + dependencies: + bluebird "^3.5.2" + eth-ens-namehash "^2.0.8" + solc "^0.4.20" + testrpc "0.0.1" + web3-utils "^1.0.0-beta.31" + +"@ensdomains/ensjs@^2.0.1": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@ensdomains/ensjs/-/ensjs-2.1.0.tgz#0a7296c1f3d735ef019320d863a7846a0760c460" + integrity sha512-GRbGPT8Z/OJMDuxs75U/jUNEC0tbL0aj7/L/QQznGYKm/tiasp+ndLOaoULy9kKJFC0TBByqfFliEHDgoLhyog== + dependencies: + "@babel/runtime" "^7.4.4" + "@ensdomains/address-encoder" "^0.1.7" + "@ensdomains/ens" "0.4.5" + "@ensdomains/resolver" "0.2.4" + content-hash "^2.5.2" + eth-ens-namehash "^2.0.8" + ethers "^5.0.13" + js-sha3 "^0.8.0" + +"@ensdomains/resolver@0.2.4": + version "0.2.4" + resolved "https://registry.yarnpkg.com/@ensdomains/resolver/-/resolver-0.2.4.tgz#c10fe28bf5efbf49bff4666d909aed0265efbc89" + integrity sha512-bvaTH34PMCbv6anRa9I/0zjLJgY4EuznbEMgbV77JBCQ9KNC46rzi0avuxpOfu+xDjPEtSFGqVEOr5GlUSGudA== + +"@eslint/eslintrc@^0.4.3": + version "0.4.3" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.3.tgz#9e42981ef035beb3dd49add17acb96e8ff6f394c" + integrity sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw== + dependencies: + ajv "^6.12.4" + debug "^4.1.1" + espree "^7.3.0" + globals "^13.9.0" + ignore "^4.0.6" + import-fresh "^3.2.1" + js-yaml "^3.13.1" + minimatch "^3.0.4" + strip-json-comments "^3.1.1" + +"@ethereum-waffle/chai@4.0.10": + version "4.0.10" + resolved "https://registry.yarnpkg.com/@ethereum-waffle/chai/-/chai-4.0.10.tgz#6f600a40b6fdaed331eba42b8625ff23f3a0e59a" + integrity sha512-X5RepE7Dn8KQLFO7HHAAe+KeGaX/by14hn90wePGBhzL54tq4Y8JscZFu+/LCwCl6TnkAAy5ebiMoqJ37sFtWw== + dependencies: + "@ethereum-waffle/provider" "4.0.5" + debug "^4.3.4" + json-bigint "^1.0.0" + +"@ethereum-waffle/compiler@4.0.3": + version "4.0.3" + resolved "https://registry.yarnpkg.com/@ethereum-waffle/compiler/-/compiler-4.0.3.tgz#069e2df24b879b8a7b78857bad6f8bf6ebc8a5b1" + integrity sha512-5x5U52tSvEVJS6dpCeXXKvRKyf8GICDwiTwUvGD3/WD+DpvgvaoHOL82XqpTSUHgV3bBq6ma5/8gKUJUIAnJCw== + dependencies: + "@resolver-engine/imports" "^0.3.3" + "@resolver-engine/imports-fs" "^0.3.3" + "@typechain/ethers-v5" "^10.0.0" + "@types/mkdirp" "^0.5.2" + "@types/node-fetch" "^2.6.1" + mkdirp "^0.5.1" + node-fetch "^2.6.7" + +"@ethereum-waffle/ens@4.0.3": + version "4.0.3" + resolved "https://registry.yarnpkg.com/@ethereum-waffle/ens/-/ens-4.0.3.tgz#4a46ac926414f3c83b4e8cc2562c8e2aee06377a" + integrity sha512-PVLcdnTbaTfCrfSOrvtlA9Fih73EeDvFS28JQnT5M5P4JMplqmchhcZB1yg/fCtx4cvgHlZXa0+rOCAk2Jk0Jw== + +"@ethereum-waffle/mock-contract@4.0.4": + version "4.0.4" + resolved "https://registry.yarnpkg.com/@ethereum-waffle/mock-contract/-/mock-contract-4.0.4.tgz#f13fea29922d87a4d2e7c4fc8fe72ea04d2c13de" + integrity sha512-LwEj5SIuEe9/gnrXgtqIkWbk2g15imM/qcJcxpLyAkOj981tQxXmtV4XmQMZsdedEsZ/D/rbUAOtZbgwqgUwQA== + +"@ethereum-waffle/provider@4.0.5": + version "4.0.5" + resolved "https://registry.yarnpkg.com/@ethereum-waffle/provider/-/provider-4.0.5.tgz#8a65dbf0263f4162c9209608205dee1c960e716b" + integrity sha512-40uzfyzcrPh+Gbdzv89JJTMBlZwzya1YLDyim8mVbEqYLP5VRYWoGp0JMyaizgV3hMoUFRqJKVmIUw4v7r3hYw== + dependencies: + "@ethereum-waffle/ens" "4.0.3" + "@ganache/ethereum-options" "0.1.4" + debug "^4.3.4" + ganache "7.4.3" + +"@ethereumjs/block@^3.5.0", "@ethereumjs/block@^3.6.0", "@ethereumjs/block@^3.6.2": + version "3.6.3" + resolved "https://registry.yarnpkg.com/@ethereumjs/block/-/block-3.6.3.tgz#d96cbd7af38b92ebb3424223dbf773f5ccd27f84" + integrity sha512-CegDeryc2DVKnDkg5COQrE0bJfw/p0v3GBk2W5/Dj5dOVfEmb50Ux0GLnSPypooLnfqjwFaorGuT9FokWB3GRg== + dependencies: + "@ethereumjs/common" "^2.6.5" + "@ethereumjs/tx" "^3.5.2" + ethereumjs-util "^7.1.5" + merkle-patricia-tree "^4.2.4" + +"@ethereumjs/blockchain@^5.5.0": + version "5.5.3" + resolved "https://registry.yarnpkg.com/@ethereumjs/blockchain/-/blockchain-5.5.3.tgz#aa49a6a04789da6b66b5bcbb0d0b98efc369f640" + integrity sha512-bi0wuNJ1gw4ByNCV56H0Z4Q7D+SxUbwyG12Wxzbvqc89PXLRNR20LBcSUZRKpN0+YCPo6m0XZL/JLio3B52LTw== + dependencies: + "@ethereumjs/block" "^3.6.2" + "@ethereumjs/common" "^2.6.4" + "@ethereumjs/ethash" "^1.1.0" + debug "^4.3.3" + ethereumjs-util "^7.1.5" + level-mem "^5.0.1" + lru-cache "^5.1.1" + semaphore-async-await "^1.5.1" + +"@ethereumjs/common@2.5.0": + version "2.5.0" + resolved "https://registry.yarnpkg.com/@ethereumjs/common/-/common-2.5.0.tgz#ec61551b31bef7a69d1dc634d8932468866a4268" + integrity sha512-DEHjW6e38o+JmB/NO3GZBpW4lpaiBpkFgXF6jLcJ6gETBYpEyaA5nTimsWBUJR3Vmtm/didUEbNjajskugZORg== + dependencies: + crc-32 "^1.2.0" + ethereumjs-util "^7.1.1" + +"@ethereumjs/common@2.6.0": + version "2.6.0" + resolved "https://registry.yarnpkg.com/@ethereumjs/common/-/common-2.6.0.tgz#feb96fb154da41ee2cc2c5df667621a440f36348" + integrity sha512-Cq2qS0FTu6O2VU1sgg+WyU9Ps0M6j/BEMHN+hRaECXCV/r0aI78u4N6p52QW/BDVhwWZpCdrvG8X7NJdzlpNUA== + dependencies: + crc-32 "^1.2.0" + ethereumjs-util "^7.1.3" + +"@ethereumjs/common@2.6.5", "@ethereumjs/common@^2.5.0", "@ethereumjs/common@^2.6.0", "@ethereumjs/common@^2.6.4", "@ethereumjs/common@^2.6.5": + version "2.6.5" + resolved "https://registry.yarnpkg.com/@ethereumjs/common/-/common-2.6.5.tgz#0a75a22a046272579d91919cb12d84f2756e8d30" + integrity sha512-lRyVQOeCDaIVtgfbowla32pzeDv2Obr8oR8Put5RdUBNRGr1VGPGQNGP6elWIpgK3YdpzqTOh4GyUGOureVeeA== + dependencies: + crc-32 "^1.2.0" + ethereumjs-util "^7.1.5" + +"@ethereumjs/ethash@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@ethereumjs/ethash/-/ethash-1.1.0.tgz#7c5918ffcaa9cb9c1dc7d12f77ef038c11fb83fb" + integrity sha512-/U7UOKW6BzpA+Vt+kISAoeDie1vAvY4Zy2KF5JJb+So7+1yKmJeJEHOGSnQIj330e9Zyl3L5Nae6VZyh2TJnAA== + dependencies: + "@ethereumjs/block" "^3.5.0" + "@types/levelup" "^4.3.0" + buffer-xor "^2.0.1" + ethereumjs-util "^7.1.1" + miller-rabin "^4.0.0" + +"@ethereumjs/rlp@^4.0.1": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@ethereumjs/rlp/-/rlp-4.0.1.tgz#626fabfd9081baab3d0a3074b0c7ecaf674aaa41" + integrity sha512-tqsQiBQDQdmPWE1xkkBq4rlSW5QZpLOUJ5RJh2/9fug+q9tnUhuZoVLk7s0scUIKTOzEtR72DFBXI4WiZcMpvw== + +"@ethereumjs/tx@3.3.2": + version "3.3.2" + resolved "https://registry.yarnpkg.com/@ethereumjs/tx/-/tx-3.3.2.tgz#348d4624bf248aaab6c44fec2ae67265efe3db00" + integrity sha512-6AaJhwg4ucmwTvw/1qLaZUX5miWrwZ4nLOUsKyb/HtzS3BMw/CasKhdi1ims9mBKeK9sOJCH4qGKOBGyJCeeog== + dependencies: + "@ethereumjs/common" "^2.5.0" + ethereumjs-util "^7.1.2" + +"@ethereumjs/tx@3.4.0": + version "3.4.0" + resolved "https://registry.yarnpkg.com/@ethereumjs/tx/-/tx-3.4.0.tgz#7eb1947eefa55eb9cf05b3ca116fb7a3dbd0bce7" + integrity sha512-WWUwg1PdjHKZZxPPo274ZuPsJCWV3SqATrEKQP1n2DrVYVP1aZIYpo/mFaA0BDoE0tIQmBeimRCEA0Lgil+yYw== + dependencies: + "@ethereumjs/common" "^2.6.0" + ethereumjs-util "^7.1.3" + +"@ethereumjs/tx@3.5.2", "@ethereumjs/tx@^3.4.0", "@ethereumjs/tx@^3.5.2": + version "3.5.2" + resolved "https://registry.yarnpkg.com/@ethereumjs/tx/-/tx-3.5.2.tgz#197b9b6299582ad84f9527ca961466fce2296c1c" + integrity sha512-gQDNJWKrSDGu2w7w0PzVXVBNMzb7wwdDOmOqczmhNjqFxFuIbhVJDwiGEnxFNC2/b8ifcZzY7MLcluizohRzNw== + dependencies: + "@ethereumjs/common" "^2.6.4" + ethereumjs-util "^7.1.5" + +"@ethereumjs/util@^8.1.0": + version "8.1.0" + resolved "https://registry.yarnpkg.com/@ethereumjs/util/-/util-8.1.0.tgz#299df97fb6b034e0577ce9f94c7d9d1004409ed4" + integrity sha512-zQ0IqbdX8FZ9aw11vP+dZkKDkS+kgIvQPHnSAXzP9pLu+Rfu3D3XEeLbicvoXJTYnhZiPmsZUxgdzXwNKxRPbA== + dependencies: + "@ethereumjs/rlp" "^4.0.1" + ethereum-cryptography "^2.0.0" + micro-ftch "^0.3.1" + +"@ethereumjs/vm@5.6.0": + version "5.6.0" + resolved "https://registry.yarnpkg.com/@ethereumjs/vm/-/vm-5.6.0.tgz#e0ca62af07de820143674c30b776b86c1983a464" + integrity sha512-J2m/OgjjiGdWF2P9bj/4LnZQ1zRoZhY8mRNVw/N3tXliGI8ai1sI1mlDPkLpeUUM4vq54gH6n0ZlSpz8U/qlYQ== + dependencies: + "@ethereumjs/block" "^3.6.0" + "@ethereumjs/blockchain" "^5.5.0" + "@ethereumjs/common" "^2.6.0" + "@ethereumjs/tx" "^3.4.0" + async-eventemitter "^0.2.4" + core-js-pure "^3.0.1" + debug "^2.2.0" + ethereumjs-util "^7.1.3" + functional-red-black-tree "^1.0.1" + mcl-wasm "^0.7.1" + merkle-patricia-tree "^4.2.2" + rustbn.js "~0.2.0" + +"@ethersproject/abi@5.7.0", "@ethersproject/abi@^5.0.12", "@ethersproject/abi@^5.0.9", "@ethersproject/abi@^5.1.2", "@ethersproject/abi@^5.6.3", "@ethersproject/abi@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.7.0.tgz#b3f3e045bbbeed1af3947335c247ad625a44e449" + integrity sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA== + dependencies: + "@ethersproject/address" "^5.7.0" + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/constants" "^5.7.0" + "@ethersproject/hash" "^5.7.0" + "@ethersproject/keccak256" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + "@ethersproject/strings" "^5.7.0" + +"@ethersproject/abstract-provider@5.7.0", "@ethersproject/abstract-provider@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/abstract-provider/-/abstract-provider-5.7.0.tgz#b0a8550f88b6bf9d51f90e4795d48294630cb9ef" + integrity sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw== + dependencies: + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/networks" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + "@ethersproject/transactions" "^5.7.0" + "@ethersproject/web" "^5.7.0" + +"@ethersproject/abstract-signer@5.7.0", "@ethersproject/abstract-signer@^5.6.2", "@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.0.2", "@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.6.1", "@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", "@ethersproject/contracts@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/contracts/-/contracts-5.7.0.tgz#c305e775abd07e48aa590e1a877ed5c316f8bd1e" + integrity sha512-5GJbzEU3X+d33CdfPhcyS+z8MzsTrBGk/sc+G+59+tPa9yFkl6HQ9D6L0QMgNTA9q8dT0XKxxkyp883XsQvbbg== + dependencies: + "@ethersproject/abi" "^5.7.0" + "@ethersproject/abstract-provider" "^5.7.0" + "@ethersproject/abstract-signer" "^5.7.0" + "@ethersproject/address" "^5.7.0" + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/constants" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + "@ethersproject/transactions" "^5.7.0" + +"@ethersproject/hash@5.7.0", "@ethersproject/hash@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/hash/-/hash-5.7.0.tgz#eb7aca84a588508369562e16e514b539ba5240a7" + integrity sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g== + dependencies: + "@ethersproject/abstract-signer" "^5.7.0" + "@ethersproject/address" "^5.7.0" + "@ethersproject/base64" "^5.7.0" + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/keccak256" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + "@ethersproject/strings" "^5.7.0" + +"@ethersproject/hdnode@5.7.0", "@ethersproject/hdnode@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/hdnode/-/hdnode-5.7.0.tgz#e627ddc6b466bc77aebf1a6b9e47405ca5aef9cf" + integrity sha512-OmyYo9EENBPPf4ERhR7oj6uAtUAhYGqOnIS+jE5pTXvdKBS99ikzq1E7Iv0ZQZ5V36Lqx1qZLeak0Ra16qpeOg== + dependencies: + "@ethersproject/abstract-signer" "^5.7.0" + "@ethersproject/basex" "^5.7.0" + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/pbkdf2" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + "@ethersproject/sha2" "^5.7.0" + "@ethersproject/signing-key" "^5.7.0" + "@ethersproject/strings" "^5.7.0" + "@ethersproject/transactions" "^5.7.0" + "@ethersproject/wordlists" "^5.7.0" + +"@ethersproject/json-wallets@5.7.0", "@ethersproject/json-wallets@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/json-wallets/-/json-wallets-5.7.0.tgz#5e3355287b548c32b368d91014919ebebddd5360" + integrity sha512-8oee5Xgu6+RKgJTkvEMl2wDgSPSAQ9MB/3JYjFV9jlKvcYHUXZC+cQp0njgmxdHkYWn8s6/IqIZYm0YWCjO/0g== + dependencies: + "@ethersproject/abstract-signer" "^5.7.0" + "@ethersproject/address" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/hdnode" "^5.7.0" + "@ethersproject/keccak256" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/pbkdf2" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + "@ethersproject/random" "^5.7.0" + "@ethersproject/strings" "^5.7.0" + "@ethersproject/transactions" "^5.7.0" + aes-js "3.0.0" + scrypt-js "3.0.1" + +"@ethersproject/keccak256@5.7.0", "@ethersproject/keccak256@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/keccak256/-/keccak256-5.7.0.tgz#3186350c6e1cd6aba7940384ec7d6d9db01f335a" + integrity sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg== + dependencies: + "@ethersproject/bytes" "^5.7.0" + js-sha3 "0.8.0" + +"@ethersproject/logger@5.7.0", "@ethersproject/logger@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.7.0.tgz#6ce9ae168e74fecf287be17062b590852c311892" + integrity sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig== + +"@ethersproject/networks@5.7.1", "@ethersproject/networks@^5.7.0": + version "5.7.1" + resolved "https://registry.yarnpkg.com/@ethersproject/networks/-/networks-5.7.1.tgz#118e1a981d757d45ccea6bb58d9fd3d9db14ead6" + integrity sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ== + dependencies: + "@ethersproject/logger" "^5.7.0" + +"@ethersproject/pbkdf2@5.7.0", "@ethersproject/pbkdf2@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/pbkdf2/-/pbkdf2-5.7.0.tgz#d2267d0a1f6e123f3771007338c47cccd83d3102" + integrity sha512-oR/dBRZR6GTyaofd86DehG72hY6NpAjhabkhxgr3X2FpJtJuodEl2auADWBZfhDHgVCbu3/H/Ocq2uC6dpNjjw== + dependencies: + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/sha2" "^5.7.0" + +"@ethersproject/properties@5.7.0", "@ethersproject/properties@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/properties/-/properties-5.7.0.tgz#a6e12cb0439b878aaf470f1902a176033067ed30" + integrity sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw== + dependencies: + "@ethersproject/logger" "^5.7.0" + +"@ethersproject/providers@5.7.2", "@ethersproject/providers@^5.7.1", "@ethersproject/providers@^5.7.2": + version "5.7.2" + resolved "https://registry.yarnpkg.com/@ethersproject/providers/-/providers-5.7.2.tgz#f8b1a4f275d7ce58cf0a2eec222269a08beb18cb" + integrity sha512-g34EWZ1WWAVgr4aptGlVBF8mhl3VWjv+8hoAnzStu8Ah22VHBsuGzP17eb6xDVRzw895G4W7vvx60lFFur/1Rg== + dependencies: + "@ethersproject/abstract-provider" "^5.7.0" + "@ethersproject/abstract-signer" "^5.7.0" + "@ethersproject/address" "^5.7.0" + "@ethersproject/base64" "^5.7.0" + "@ethersproject/basex" "^5.7.0" + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/constants" "^5.7.0" + "@ethersproject/hash" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/networks" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + "@ethersproject/random" "^5.7.0" + "@ethersproject/rlp" "^5.7.0" + "@ethersproject/sha2" "^5.7.0" + "@ethersproject/strings" "^5.7.0" + "@ethersproject/transactions" "^5.7.0" + "@ethersproject/web" "^5.7.0" + bech32 "1.1.4" + ws "7.4.6" + +"@ethersproject/random@5.7.0", "@ethersproject/random@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/random/-/random-5.7.0.tgz#af19dcbc2484aae078bb03656ec05df66253280c" + integrity sha512-19WjScqRA8IIeWclFme75VMXSBvi4e6InrUNuaR4s5pTF2qNhcGdCUwdxUVGtDDqC00sDLCO93jPQoDUH4HVmQ== + dependencies: + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + +"@ethersproject/rlp@5.7.0", "@ethersproject/rlp@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/rlp/-/rlp-5.7.0.tgz#de39e4d5918b9d74d46de93af80b7685a9c21304" + integrity sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w== + dependencies: + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + +"@ethersproject/sha2@5.7.0", "@ethersproject/sha2@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/sha2/-/sha2-5.7.0.tgz#9a5f7a7824ef784f7f7680984e593a800480c9fb" + integrity sha512-gKlH42riwb3KYp0reLsFTokByAKoJdgFCwI+CCiX/k+Jm2mbNs6oOaCjYQSlI1+XBVejwH2KrmCbMAT/GnRDQw== + dependencies: + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + hash.js "1.1.7" + +"@ethersproject/signing-key@5.7.0", "@ethersproject/signing-key@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/signing-key/-/signing-key-5.7.0.tgz#06b2df39411b00bc57c7c09b01d1e41cf1b16ab3" + integrity sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q== + dependencies: + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + bn.js "^5.2.1" + elliptic "6.5.4" + hash.js "1.1.7" + +"@ethersproject/solidity@5.7.0", "@ethersproject/solidity@^5.0.9", "@ethersproject/solidity@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/solidity/-/solidity-5.7.0.tgz#5e9c911d8a2acce2a5ebb48a5e2e0af20b631cb8" + integrity sha512-HmabMd2Dt/raavyaGukF4XxizWKhKQ24DoLtdNbBmNKUOPqwjsKQSdV9GQtj9CBEea9DlzETlVER1gYeXXBGaA== + dependencies: + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/keccak256" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/sha2" "^5.7.0" + "@ethersproject/strings" "^5.7.0" + +"@ethersproject/strings@5.7.0", "@ethersproject/strings@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.7.0.tgz#54c9d2a7c57ae8f1205c88a9d3a56471e14d5ed2" + integrity sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg== + dependencies: + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/constants" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + +"@ethersproject/transactions@5.7.0", "@ethersproject/transactions@^5.6.2", "@ethersproject/transactions@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/transactions/-/transactions-5.7.0.tgz#91318fc24063e057885a6af13fdb703e1f993d3b" + integrity sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ== + dependencies: + "@ethersproject/address" "^5.7.0" + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/constants" "^5.7.0" + "@ethersproject/keccak256" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + "@ethersproject/rlp" "^5.7.0" + "@ethersproject/signing-key" "^5.7.0" + +"@ethersproject/units@5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/units/-/units-5.7.0.tgz#637b563d7e14f42deeee39245275d477aae1d8b1" + integrity sha512-pD3xLMy3SJu9kG5xDGI7+xhTEmGXlEqXU4OfNapmfnxLVY4EMSSRp7j1k7eezutBPH7RBN/7QPnwR7hzNlEFeg== + dependencies: + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/constants" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + +"@ethersproject/wallet@5.7.0", "@ethersproject/wallet@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/wallet/-/wallet-5.7.0.tgz#4e5d0790d96fe21d61d38fb40324e6c7ef350b2d" + integrity sha512-MhmXlJXEJFBFVKrDLB4ZdDzxcBxQ3rLyCkhNqVu3CDYvR97E+8r01UgrI+TI99Le+aYm/in/0vp86guJuM7FCA== + dependencies: + "@ethersproject/abstract-provider" "^5.7.0" + "@ethersproject/abstract-signer" "^5.7.0" + "@ethersproject/address" "^5.7.0" + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/hash" "^5.7.0" + "@ethersproject/hdnode" "^5.7.0" + "@ethersproject/json-wallets" "^5.7.0" + "@ethersproject/keccak256" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + "@ethersproject/random" "^5.7.0" + "@ethersproject/signing-key" "^5.7.0" + "@ethersproject/transactions" "^5.7.0" + "@ethersproject/wordlists" "^5.7.0" + +"@ethersproject/web@5.7.1", "@ethersproject/web@^5.7.0": + version "5.7.1" + resolved "https://registry.yarnpkg.com/@ethersproject/web/-/web-5.7.1.tgz#de1f285b373149bee5928f4eb7bcb87ee5fbb4ae" + integrity sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w== + dependencies: + "@ethersproject/base64" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + "@ethersproject/strings" "^5.7.0" + +"@ethersproject/wordlists@5.7.0", "@ethersproject/wordlists@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/wordlists/-/wordlists-5.7.0.tgz#8fb2c07185d68c3e09eb3bfd6e779ba2774627f5" + integrity sha512-S2TFNJNfHWVHNE6cNDjbVlZ6MgE17MIxMbMg2zv3wn+3XSJGosL1m9ZVv3GXCf/2ymSsQ+hRI5IzoMJTG6aoVA== + dependencies: + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/hash" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + "@ethersproject/strings" "^5.7.0" + +"@fastify/busboy@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@fastify/busboy/-/busboy-2.0.0.tgz#f22824caff3ae506b18207bad4126dbc6ccdb6b8" + integrity sha512-JUFJad5lv7jxj926GPgymrWQxxjPYuJNiNjNMzqT+HiuP6Vl3dk5xzG+8sTX96np0ZAluvaMzPsjhHZ5rNuNQQ== + +"@ganache/ethereum-address@0.1.4": + version "0.1.4" + resolved "https://registry.yarnpkg.com/@ganache/ethereum-address/-/ethereum-address-0.1.4.tgz#0e6d66f4a24f64bf687cb3ff7358fb85b9d9005e" + integrity sha512-sTkU0M9z2nZUzDeHRzzGlW724xhMLXo2LeX1hixbnjHWY1Zg1hkqORywVfl+g5uOO8ht8T0v+34IxNxAhmWlbw== + dependencies: + "@ganache/utils" "0.1.4" + +"@ganache/ethereum-options@0.1.4": + version "0.1.4" + resolved "https://registry.yarnpkg.com/@ganache/ethereum-options/-/ethereum-options-0.1.4.tgz#6a559abb44225e2b8741a8f78a19a46714a71cd6" + integrity sha512-i4l46taoK2yC41FPkcoDlEVoqHS52wcbHPqJtYETRWqpOaoj9hAg/EJIHLb1t6Nhva2CdTO84bG+qlzlTxjAHw== + dependencies: + "@ganache/ethereum-address" "0.1.4" + "@ganache/ethereum-utils" "0.1.4" + "@ganache/options" "0.1.4" + "@ganache/utils" "0.1.4" + bip39 "3.0.4" + seedrandom "3.0.5" + +"@ganache/ethereum-utils@0.1.4": + version "0.1.4" + resolved "https://registry.yarnpkg.com/@ganache/ethereum-utils/-/ethereum-utils-0.1.4.tgz#fae4b5b9e642e751ff1fa0cd7316c92996317257" + integrity sha512-FKXF3zcdDrIoCqovJmHLKZLrJ43234Em2sde/3urUT/10gSgnwlpFmrv2LUMAmSbX3lgZhW/aSs8krGhDevDAg== + dependencies: + "@ethereumjs/common" "2.6.0" + "@ethereumjs/tx" "3.4.0" + "@ethereumjs/vm" "5.6.0" + "@ganache/ethereum-address" "0.1.4" + "@ganache/rlp" "0.1.4" + "@ganache/utils" "0.1.4" + emittery "0.10.0" + ethereumjs-abi "0.6.8" + ethereumjs-util "7.1.3" + +"@ganache/options@0.1.4": + version "0.1.4" + resolved "https://registry.yarnpkg.com/@ganache/options/-/options-0.1.4.tgz#325b07e6de85094667aaaaf3d653e32404a04b78" + integrity sha512-zAe/craqNuPz512XQY33MOAG6Si1Xp0hCvfzkBfj2qkuPcbJCq6W/eQ5MB6SbXHrICsHrZOaelyqjuhSEmjXRw== + dependencies: + "@ganache/utils" "0.1.4" + bip39 "3.0.4" + seedrandom "3.0.5" + +"@ganache/rlp@0.1.4": + version "0.1.4" + resolved "https://registry.yarnpkg.com/@ganache/rlp/-/rlp-0.1.4.tgz#f4043afda83e1a14a4f80607b103daf166a9b374" + integrity sha512-Do3D1H6JmhikB+6rHviGqkrNywou/liVeFiKIpOBLynIpvZhRCgn3SEDxyy/JovcaozTo/BynHumfs5R085MFQ== + dependencies: + "@ganache/utils" "0.1.4" + rlp "2.2.6" + +"@ganache/utils@0.1.4": + version "0.1.4" + resolved "https://registry.yarnpkg.com/@ganache/utils/-/utils-0.1.4.tgz#25d60d7689e3dda6a8a7ad70e3646f07c2c39a1f" + integrity sha512-oatUueU3XuXbUbUlkyxeLLH3LzFZ4y5aSkNbx6tjSIhVTPeh+AuBKYt4eQ73FFcTB3nj/gZoslgAh5CN7O369w== + dependencies: + emittery "0.10.0" + keccak "3.0.1" + seedrandom "3.0.5" + optionalDependencies: + "@trufflesuite/bigint-buffer" "1.1.9" + +"@humanwhocodes/config-array@^0.5.0": + version "0.5.0" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.5.0.tgz#1407967d4c6eecd7388f83acf1eaf4d0c6e58ef9" + integrity sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg== + dependencies: + "@humanwhocodes/object-schema" "^1.2.0" + debug "^4.1.1" + minimatch "^3.0.4" + +"@humanwhocodes/object-schema@^1.2.0": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" + integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== + +"@jridgewell/resolve-uri@^3.0.3": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz#c08679063f279615a3326583ba3a90d1d82cc721" + integrity sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA== + +"@jridgewell/sourcemap-codec@^1.4.10": + version "1.4.15" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" + integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== + +"@jridgewell/trace-mapping@0.3.9": + version "0.3.9" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9" + integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ== + dependencies: + "@jridgewell/resolve-uri" "^3.0.3" + "@jridgewell/sourcemap-codec" "^1.4.10" + +"@metamask/eth-sig-util@^4.0.0": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@metamask/eth-sig-util/-/eth-sig-util-4.0.1.tgz#3ad61f6ea9ad73ba5b19db780d40d9aae5157088" + integrity sha512-tghyZKLHZjcdlDqCA3gNZmLeR0XvOE9U1qoQO9ohyAZT6Pya+H9vkBPcsyXytmYLNgVoin7CKCmweo/R43V+tQ== + dependencies: + ethereumjs-abi "^0.6.8" + ethereumjs-util "^6.2.1" + ethjs-util "^0.1.6" + tweetnacl "^1.0.3" + tweetnacl-util "^0.15.1" + +"@noble/curves@1.1.0", "@noble/curves@~1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.1.0.tgz#f13fc667c89184bc04cccb9b11e8e7bae27d8c3d" + integrity sha512-091oBExgENk/kGj3AZmtBDMpxQPDtxQABR2B9lb1JbVTs6ytdzZNwvhxQ4MWasRNEzlbEH8jCWFCwhF/Obj5AA== + dependencies: + "@noble/hashes" "1.3.1" + +"@noble/hashes@1.2.0", "@noble/hashes@~1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.2.0.tgz#a3150eeb09cc7ab207ebf6d7b9ad311a9bdbed12" + integrity sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ== + +"@noble/hashes@1.3.1": + version "1.3.1" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.1.tgz#8831ef002114670c603c458ab8b11328406953a9" + integrity sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA== + +"@noble/hashes@~1.3.0", "@noble/hashes@~1.3.1": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.2.tgz#6f26dbc8fbc7205873ce3cee2f690eba0d421b39" + integrity sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ== + +"@noble/secp256k1@1.7.1", "@noble/secp256k1@~1.7.0": + version "1.7.1" + resolved "https://registry.yarnpkg.com/@noble/secp256k1/-/secp256k1-1.7.1.tgz#b251c70f824ce3ca7f8dc3df08d58f005cc0507c" + integrity sha512-hOUk6AyBFmqVrv7k5WAw/LpszxVbj9gGN4JRkIX52fdFAj1UA61KXmZDvqVEm+pOyec3+fIeZB02LYa/pWOArw== + +"@nodelib/fs.scandir@2.1.5": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" + integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== + dependencies: + "@nodelib/fs.stat" "2.0.5" + run-parallel "^1.1.9" + +"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== + +"@nodelib/fs.walk@^1.2.3": + version "1.2.8" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" + integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== + dependencies: + "@nodelib/fs.scandir" "2.1.5" + fastq "^1.6.0" + +"@nomicfoundation/ethereumjs-block@5.0.2": + version "5.0.2" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-block/-/ethereumjs-block-5.0.2.tgz#13a7968f5964f1697da941281b7f7943b0465d04" + integrity sha512-hSe6CuHI4SsSiWWjHDIzWhSiAVpzMUcDRpWYzN0T9l8/Rz7xNn3elwVOJ/tAyS0LqL6vitUD78Uk7lQDXZun7Q== + dependencies: + "@nomicfoundation/ethereumjs-common" "4.0.2" + "@nomicfoundation/ethereumjs-rlp" "5.0.2" + "@nomicfoundation/ethereumjs-trie" "6.0.2" + "@nomicfoundation/ethereumjs-tx" "5.0.2" + "@nomicfoundation/ethereumjs-util" "9.0.2" + ethereum-cryptography "0.1.3" + ethers "^5.7.1" + +"@nomicfoundation/ethereumjs-blockchain@7.0.2": + version "7.0.2" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-blockchain/-/ethereumjs-blockchain-7.0.2.tgz#45323b673b3d2fab6b5008535340d1b8fea7d446" + integrity sha512-8UUsSXJs+MFfIIAKdh3cG16iNmWzWC/91P40sazNvrqhhdR/RtGDlFk2iFTGbBAZPs2+klZVzhRX8m2wvuvz3w== + dependencies: + "@nomicfoundation/ethereumjs-block" "5.0.2" + "@nomicfoundation/ethereumjs-common" "4.0.2" + "@nomicfoundation/ethereumjs-ethash" "3.0.2" + "@nomicfoundation/ethereumjs-rlp" "5.0.2" + "@nomicfoundation/ethereumjs-trie" "6.0.2" + "@nomicfoundation/ethereumjs-tx" "5.0.2" + "@nomicfoundation/ethereumjs-util" "9.0.2" + abstract-level "^1.0.3" + debug "^4.3.3" + ethereum-cryptography "0.1.3" + level "^8.0.0" + lru-cache "^5.1.1" + memory-level "^1.0.0" + +"@nomicfoundation/ethereumjs-common@4.0.2": + version "4.0.2" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-common/-/ethereumjs-common-4.0.2.tgz#a15d1651ca36757588fdaf2a7d381a150662a3c3" + integrity sha512-I2WGP3HMGsOoycSdOTSqIaES0ughQTueOsddJ36aYVpI3SN8YSusgRFLwzDJwRFVIYDKx/iJz0sQ5kBHVgdDwg== + dependencies: + "@nomicfoundation/ethereumjs-util" "9.0.2" + crc-32 "^1.2.0" + +"@nomicfoundation/ethereumjs-ethash@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-ethash/-/ethereumjs-ethash-3.0.2.tgz#da77147f806401ee996bfddfa6487500118addca" + integrity sha512-8PfoOQCcIcO9Pylq0Buijuq/O73tmMVURK0OqdjhwqcGHYC2PwhbajDh7GZ55ekB0Px197ajK3PQhpKoiI/UPg== + dependencies: + "@nomicfoundation/ethereumjs-block" "5.0.2" + "@nomicfoundation/ethereumjs-rlp" "5.0.2" + "@nomicfoundation/ethereumjs-util" "9.0.2" + abstract-level "^1.0.3" + bigint-crypto-utils "^3.0.23" + ethereum-cryptography "0.1.3" + +"@nomicfoundation/ethereumjs-evm@2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-evm/-/ethereumjs-evm-2.0.2.tgz#4c2f4b84c056047102a4fa41c127454e3f0cfcf6" + integrity sha512-rBLcUaUfANJxyOx9HIdMX6uXGin6lANCulIm/pjMgRqfiCRMZie3WKYxTSd8ZE/d+qT+zTedBF4+VHTdTSePmQ== + dependencies: + "@ethersproject/providers" "^5.7.1" + "@nomicfoundation/ethereumjs-common" "4.0.2" + "@nomicfoundation/ethereumjs-tx" "5.0.2" + "@nomicfoundation/ethereumjs-util" "9.0.2" + debug "^4.3.3" + ethereum-cryptography "0.1.3" + mcl-wasm "^0.7.1" + rustbn.js "~0.2.0" + +"@nomicfoundation/ethereumjs-rlp@5.0.2": + version "5.0.2" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-rlp/-/ethereumjs-rlp-5.0.2.tgz#4fee8dc58a53ac6ae87fb1fca7c15dc06c6b5dea" + integrity sha512-QwmemBc+MMsHJ1P1QvPl8R8p2aPvvVcKBbvHnQOKBpBztEo0omN0eaob6FeZS/e3y9NSe+mfu3nNFBHszqkjTA== + +"@nomicfoundation/ethereumjs-statemanager@2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-statemanager/-/ethereumjs-statemanager-2.0.2.tgz#3ba4253b29b1211cafe4f9265fee5a0d780976e0" + integrity sha512-dlKy5dIXLuDubx8Z74sipciZnJTRSV/uHG48RSijhgm1V7eXYFC567xgKtsKiVZB1ViTP9iFL4B6Je0xD6X2OA== + dependencies: + "@nomicfoundation/ethereumjs-common" "4.0.2" + "@nomicfoundation/ethereumjs-rlp" "5.0.2" + debug "^4.3.3" + ethereum-cryptography "0.1.3" + ethers "^5.7.1" + js-sdsl "^4.1.4" + +"@nomicfoundation/ethereumjs-trie@6.0.2": + version "6.0.2" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-trie/-/ethereumjs-trie-6.0.2.tgz#9a6dbd28482dca1bc162d12b3733acab8cd12835" + integrity sha512-yw8vg9hBeLYk4YNg5MrSJ5H55TLOv2FSWUTROtDtTMMmDGROsAu+0tBjiNGTnKRi400M6cEzoFfa89Fc5k8NTQ== + dependencies: + "@nomicfoundation/ethereumjs-rlp" "5.0.2" + "@nomicfoundation/ethereumjs-util" "9.0.2" + "@types/readable-stream" "^2.3.13" + ethereum-cryptography "0.1.3" + readable-stream "^3.6.0" + +"@nomicfoundation/ethereumjs-tx@5.0.2": + version "5.0.2" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-tx/-/ethereumjs-tx-5.0.2.tgz#117813b69c0fdc14dd0446698a64be6df71d7e56" + integrity sha512-T+l4/MmTp7VhJeNloMkM+lPU3YMUaXdcXgTGCf8+ZFvV9NYZTRLFekRwlG6/JMmVfIfbrW+dRRJ9A6H5Q/Z64g== + dependencies: + "@chainsafe/ssz" "^0.9.2" + "@ethersproject/providers" "^5.7.2" + "@nomicfoundation/ethereumjs-common" "4.0.2" + "@nomicfoundation/ethereumjs-rlp" "5.0.2" + "@nomicfoundation/ethereumjs-util" "9.0.2" + ethereum-cryptography "0.1.3" + +"@nomicfoundation/ethereumjs-util@9.0.2": + version "9.0.2" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-util/-/ethereumjs-util-9.0.2.tgz#16bdc1bb36f333b8a3559bbb4b17dac805ce904d" + integrity sha512-4Wu9D3LykbSBWZo8nJCnzVIYGvGCuyiYLIJa9XXNVt1q1jUzHdB+sJvx95VGCpPkCT+IbLecW6yfzy3E1bQrwQ== + dependencies: + "@chainsafe/ssz" "^0.10.0" + "@nomicfoundation/ethereumjs-rlp" "5.0.2" + ethereum-cryptography "0.1.3" + +"@nomicfoundation/ethereumjs-vm@7.0.2": + version "7.0.2" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-vm/-/ethereumjs-vm-7.0.2.tgz#3b0852cb3584df0e18c182d0672a3596c9ca95e6" + integrity sha512-Bj3KZT64j54Tcwr7Qm/0jkeZXJMfdcAtRBedou+Hx0dPOSIgqaIr0vvLwP65TpHbak2DmAq+KJbW2KNtIoFwvA== + dependencies: + "@nomicfoundation/ethereumjs-block" "5.0.2" + "@nomicfoundation/ethereumjs-blockchain" "7.0.2" + "@nomicfoundation/ethereumjs-common" "4.0.2" + "@nomicfoundation/ethereumjs-evm" "2.0.2" + "@nomicfoundation/ethereumjs-rlp" "5.0.2" + "@nomicfoundation/ethereumjs-statemanager" "2.0.2" + "@nomicfoundation/ethereumjs-trie" "6.0.2" + "@nomicfoundation/ethereumjs-tx" "5.0.2" + "@nomicfoundation/ethereumjs-util" "9.0.2" + debug "^4.3.3" + ethereum-cryptography "0.1.3" + mcl-wasm "^0.7.1" + rustbn.js "~0.2.0" + +"@nomicfoundation/solidity-analyzer-darwin-arm64@0.1.1": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-darwin-arm64/-/solidity-analyzer-darwin-arm64-0.1.1.tgz#4c858096b1c17fe58a474fe81b46815f93645c15" + integrity sha512-KcTodaQw8ivDZyF+D76FokN/HdpgGpfjc/gFCImdLUyqB6eSWVaZPazMbeAjmfhx3R0zm/NYVzxwAokFKgrc0w== + +"@nomicfoundation/solidity-analyzer-darwin-x64@0.1.1": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-darwin-x64/-/solidity-analyzer-darwin-x64-0.1.1.tgz#6e25ccdf6e2d22389c35553b64fe6f3fdaec432c" + integrity sha512-XhQG4BaJE6cIbjAVtzGOGbK3sn1BO9W29uhk9J8y8fZF1DYz0Doj8QDMfpMu+A6TjPDs61lbsmeYodIDnfveSA== + +"@nomicfoundation/solidity-analyzer-freebsd-x64@0.1.1": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-freebsd-x64/-/solidity-analyzer-freebsd-x64-0.1.1.tgz#0a224ea50317139caeebcdedd435c28a039d169c" + integrity sha512-GHF1VKRdHW3G8CndkwdaeLkVBi5A9u2jwtlS7SLhBc8b5U/GcoL39Q+1CSO3hYqePNP+eV5YI7Zgm0ea6kMHoA== + +"@nomicfoundation/solidity-analyzer-linux-arm64-gnu@0.1.1": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-linux-arm64-gnu/-/solidity-analyzer-linux-arm64-gnu-0.1.1.tgz#dfa085d9ffab9efb2e7b383aed3f557f7687ac2b" + integrity sha512-g4Cv2fO37ZsUENQ2vwPnZc2zRenHyAxHcyBjKcjaSmmkKrFr64yvzeNO8S3GBFCo90rfochLs99wFVGT/0owpg== + +"@nomicfoundation/solidity-analyzer-linux-arm64-musl@0.1.1": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-linux-arm64-musl/-/solidity-analyzer-linux-arm64-musl-0.1.1.tgz#c9e06b5d513dd3ab02a7ac069c160051675889a4" + integrity sha512-WJ3CE5Oek25OGE3WwzK7oaopY8xMw9Lhb0mlYuJl/maZVo+WtP36XoQTb7bW/i8aAdHW5Z+BqrHMux23pvxG3w== + +"@nomicfoundation/solidity-analyzer-linux-x64-gnu@0.1.1": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-linux-x64-gnu/-/solidity-analyzer-linux-x64-gnu-0.1.1.tgz#8d328d16839e52571f72f2998c81e46bf320f893" + integrity sha512-5WN7leSr5fkUBBjE4f3wKENUy9HQStu7HmWqbtknfXkkil+eNWiBV275IOlpXku7v3uLsXTOKpnnGHJYI2qsdA== + +"@nomicfoundation/solidity-analyzer-linux-x64-musl@0.1.1": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-linux-x64-musl/-/solidity-analyzer-linux-x64-musl-0.1.1.tgz#9b49d0634b5976bb5ed1604a1e1b736f390959bb" + integrity sha512-KdYMkJOq0SYPQMmErv/63CwGwMm5XHenEna9X9aB8mQmhDBrYrlAOSsIPgFCUSL0hjxE3xHP65/EPXR/InD2+w== + +"@nomicfoundation/solidity-analyzer-win32-arm64-msvc@0.1.1": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-win32-arm64-msvc/-/solidity-analyzer-win32-arm64-msvc-0.1.1.tgz#e2867af7264ebbcc3131ef837878955dd6a3676f" + integrity sha512-VFZASBfl4qiBYwW5xeY20exWhmv6ww9sWu/krWSesv3q5hA0o1JuzmPHR4LPN6SUZj5vcqci0O6JOL8BPw+APg== + +"@nomicfoundation/solidity-analyzer-win32-ia32-msvc@0.1.1": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-win32-ia32-msvc/-/solidity-analyzer-win32-ia32-msvc-0.1.1.tgz#0685f78608dd516c8cdfb4896ed451317e559585" + integrity sha512-JnFkYuyCSA70j6Si6cS1A9Gh1aHTEb8kOTBApp/c7NRTFGNMH8eaInKlyuuiIbvYFhlXW4LicqyYuWNNq9hkpQ== + +"@nomicfoundation/solidity-analyzer-win32-x64-msvc@0.1.1": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-win32-x64-msvc/-/solidity-analyzer-win32-x64-msvc-0.1.1.tgz#c9a44f7108646f083b82e851486e0f6aeb785836" + integrity sha512-HrVJr6+WjIXGnw3Q9u6KQcbZCtk0caVWhCdFADySvRyUxJ8PnzlaP+MhwNE8oyT8OZ6ejHBRrrgjSqDCFXGirw== + +"@nomicfoundation/solidity-analyzer@^0.1.0": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer/-/solidity-analyzer-0.1.1.tgz#f5f4d36d3f66752f59a57e7208cd856f3ddf6f2d" + integrity sha512-1LMtXj1puAxyFusBgUIy5pZk3073cNXYnXUpuNKFghHbIit/xZgbk0AokpUADbNm3gyD6bFWl3LRFh3dhVdREg== + optionalDependencies: + "@nomicfoundation/solidity-analyzer-darwin-arm64" "0.1.1" + "@nomicfoundation/solidity-analyzer-darwin-x64" "0.1.1" + "@nomicfoundation/solidity-analyzer-freebsd-x64" "0.1.1" + "@nomicfoundation/solidity-analyzer-linux-arm64-gnu" "0.1.1" + "@nomicfoundation/solidity-analyzer-linux-arm64-musl" "0.1.1" + "@nomicfoundation/solidity-analyzer-linux-x64-gnu" "0.1.1" + "@nomicfoundation/solidity-analyzer-linux-x64-musl" "0.1.1" + "@nomicfoundation/solidity-analyzer-win32-arm64-msvc" "0.1.1" + "@nomicfoundation/solidity-analyzer-win32-ia32-msvc" "0.1.1" + "@nomicfoundation/solidity-analyzer-win32-x64-msvc" "0.1.1" + +"@nomiclabs/hardhat-ethers@npm:hardhat-deploy-ethers@^0.3.0-beta.13": + version "0.3.0-beta.13" + resolved "https://registry.yarnpkg.com/hardhat-deploy-ethers/-/hardhat-deploy-ethers-0.3.0-beta.13.tgz#b96086ff768ddf69928984d5eb0a8d78cfca9366" + integrity sha512-PdWVcKB9coqWV1L7JTpfXRCI91Cgwsm7KLmBcwZ8f0COSm1xtABHZTyz3fvF6p42cTnz1VM0QnfDvMFlIRkSNw== + +"@nomiclabs/hardhat-etherscan@^3.1.7": + version "3.1.7" + resolved "https://registry.yarnpkg.com/@nomiclabs/hardhat-etherscan/-/hardhat-etherscan-3.1.7.tgz#72e3d5bd5d0ceb695e097a7f6f5ff6fcbf062b9a" + integrity sha512-tZ3TvSgpvsQ6B6OGmo1/Au6u8BrAkvs1mIC/eURA3xgIfznUZBhmpne8hv7BXUzw9xNL3fXdpOYgOQlVMTcoHQ== + dependencies: + "@ethersproject/abi" "^5.1.2" + "@ethersproject/address" "^5.0.2" + cbor "^8.1.0" + chalk "^2.4.2" + debug "^4.1.1" + fs-extra "^7.0.1" + lodash "^4.17.11" + semver "^6.3.0" + table "^6.8.0" + undici "^5.14.0" + +"@nomiclabs/hardhat-truffle5@^2.0.6": + version "2.0.7" + resolved "https://registry.yarnpkg.com/@nomiclabs/hardhat-truffle5/-/hardhat-truffle5-2.0.7.tgz#7519eadd2c6c460c2addc3d4d6efda7a8883361e" + integrity sha512-Pw8451IUZp1bTp0QqCHCYfCHs66sCnyxPcaorapu9mfOV9xnZsVaFdtutnhNEiXdiZwbed7LFKpRsde4BjFwig== + dependencies: + "@nomiclabs/truffle-contract" "^4.2.23" + "@types/chai" "^4.2.0" + chai "^4.2.0" + ethereumjs-util "^7.1.4" + fs-extra "^7.0.1" + +"@nomiclabs/hardhat-waffle@^2.0.3": + version "2.0.6" + resolved "https://registry.yarnpkg.com/@nomiclabs/hardhat-waffle/-/hardhat-waffle-2.0.6.tgz#d11cb063a5f61a77806053e54009c40ddee49a54" + integrity sha512-+Wz0hwmJGSI17B+BhU/qFRZ1l6/xMW82QGXE/Gi+WTmwgJrQefuBs1lIf7hzQ1hLk6hpkvb/zwcNkpVKRYTQYg== + +"@nomiclabs/hardhat-web3@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@nomiclabs/hardhat-web3/-/hardhat-web3-2.0.0.tgz#2d9850cb285a2cebe1bd718ef26a9523542e52a9" + integrity sha512-zt4xN+D+fKl3wW2YlTX3k9APR3XZgPkxJYf36AcliJn3oujnKEVRZaHu0PhgLjO+gR+F/kiYayo9fgd2L8970Q== + dependencies: + "@types/bignumber.js" "^5.0.0" + +"@nomiclabs/truffle-contract@^4.2.23": + version "4.5.10" + resolved "https://registry.yarnpkg.com/@nomiclabs/truffle-contract/-/truffle-contract-4.5.10.tgz#52adcca1068647e1c2b44bf0e6a89fc4ad7f9213" + integrity sha512-nF/6InFV+0hUvutyFgsdOMCoYlr//2fJbRER4itxYtQtc4/O1biTwZIKRu+5l2J5Sq6LU2WX7vZHtDgQdhWxIQ== + dependencies: + "@ensdomains/ensjs" "^2.0.1" + "@truffle/blockchain-utils" "^0.1.3" + "@truffle/contract-schema" "^3.4.7" + "@truffle/debug-utils" "^6.0.22" + "@truffle/error" "^0.1.0" + "@truffle/interface-adapter" "^0.5.16" + bignumber.js "^7.2.1" + ethereum-ens "^0.8.0" + ethers "^4.0.0-beta.1" + source-map-support "^0.5.19" + +"@openzeppelin/contracts@3.4.1-solc-0.7-2": + version "3.4.1-solc-0.7-2" + resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-3.4.1-solc-0.7-2.tgz#371c67ebffe50f551c3146a9eec5fe6ffe862e92" + integrity sha512-tAG9LWg8+M2CMu7hIsqHPaTyG4uDzjr6mhvH96LvOpLZZj6tgzTluBt+LsCf1/QaYrlis6pITvpIaIhE+iZB+Q== + +"@openzeppelin/contracts@3.4.2-solc-0.7": + version "3.4.2-solc-0.7" + resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-3.4.2-solc-0.7.tgz#38f4dbab672631034076ccdf2f3201fab1726635" + integrity sha512-W6QmqgkADuFcTLzHL8vVoNBtkwjvQRpYIAom7KiUNoLKghyx3FgH0GBjt8NRvigV1ZmMOBllvE1By1C+bi8WpA== + +"@openzeppelin/contracts@4.9.3": + version "4.9.3" + resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.9.3.tgz#00d7a8cf35a475b160b3f0293a6403c511099364" + integrity sha512-He3LieZ1pP2TNt5JbkPA4PNT9WC3gOTOlDcFGJW4Le4QKqwmiNJCRt44APfxMxvq7OugU/cqYuPcSBzOw38DAg== + +"@resolver-engine/core@^0.3.3": + version "0.3.3" + resolved "https://registry.yarnpkg.com/@resolver-engine/core/-/core-0.3.3.tgz#590f77d85d45bc7ecc4e06c654f41345db6ca967" + integrity sha512-eB8nEbKDJJBi5p5SrvrvILn4a0h42bKtbCTri3ZxCGt6UvoQyp7HnGOfki944bUjBSHKK3RvgfViHn+kqdXtnQ== + dependencies: + debug "^3.1.0" + is-url "^1.2.4" + request "^2.85.0" + +"@resolver-engine/fs@^0.3.3": + version "0.3.3" + resolved "https://registry.yarnpkg.com/@resolver-engine/fs/-/fs-0.3.3.tgz#fbf83fa0c4f60154a82c817d2fe3f3b0c049a973" + integrity sha512-wQ9RhPUcny02Wm0IuJwYMyAG8fXVeKdmhm8xizNByD4ryZlx6PP6kRen+t/haF43cMfmaV7T3Cx6ChOdHEhFUQ== + dependencies: + "@resolver-engine/core" "^0.3.3" + debug "^3.1.0" + +"@resolver-engine/imports-fs@^0.3.3": + version "0.3.3" + resolved "https://registry.yarnpkg.com/@resolver-engine/imports-fs/-/imports-fs-0.3.3.tgz#4085db4b8d3c03feb7a425fbfcf5325c0d1e6c1b" + integrity sha512-7Pjg/ZAZtxpeyCFlZR5zqYkz+Wdo84ugB5LApwriT8XFeQoLwGUj4tZFFvvCuxaNCcqZzCYbonJgmGObYBzyCA== + dependencies: + "@resolver-engine/fs" "^0.3.3" + "@resolver-engine/imports" "^0.3.3" + debug "^3.1.0" + +"@resolver-engine/imports@^0.3.3": + version "0.3.3" + resolved "https://registry.yarnpkg.com/@resolver-engine/imports/-/imports-0.3.3.tgz#badfb513bb3ff3c1ee9fd56073e3144245588bcc" + integrity sha512-anHpS4wN4sRMwsAbMXhMfOD/y4a4Oo0Cw/5+rue7hSwGWsDOQaAU1ClK1OxjUC35/peazxEl8JaSRRS+Xb8t3Q== + dependencies: + "@resolver-engine/core" "^0.3.3" + debug "^3.1.0" + hosted-git-info "^2.6.0" + path-browserify "^1.0.0" + url "^0.11.0" + +"@scure/base@~1.1.0": + version "1.1.3" + resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.3.tgz#8584115565228290a6c6c4961973e0903bb3df2f" + integrity sha512-/+SgoRjLq7Xlf0CWuLHq2LUZeL/w65kfzAPG5NH9pcmBhs+nunQTn4gvdwgMTIXnt9b2C/1SeL2XiysZEyIC9Q== + +"@scure/bip32@1.1.5": + version "1.1.5" + resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.1.5.tgz#d2ccae16dcc2e75bc1d75f5ef3c66a338d1ba300" + integrity sha512-XyNh1rB0SkEqd3tXcXMi+Xe1fvg+kUIcoRIEujP1Jgv7DqW2r9lg3Ah0NkFaCs9sTkQAQA8kw7xiRXzENi9Rtw== + dependencies: + "@noble/hashes" "~1.2.0" + "@noble/secp256k1" "~1.7.0" + "@scure/base" "~1.1.0" + +"@scure/bip32@1.3.1": + version "1.3.1" + resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.3.1.tgz#7248aea723667f98160f593d621c47e208ccbb10" + integrity sha512-osvveYtyzdEVbt3OfwwXFr4P2iVBL5u1Q3q4ONBfDY/UpOuXmOlbgwc1xECEboY8wIays8Yt6onaWMUdUbfl0A== + dependencies: + "@noble/curves" "~1.1.0" + "@noble/hashes" "~1.3.1" + "@scure/base" "~1.1.0" + +"@scure/bip39@1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.1.1.tgz#b54557b2e86214319405db819c4b6a370cf340c5" + integrity sha512-t+wDck2rVkh65Hmv280fYdVdY25J9YeEUIgn2LG1WM6gxFkGzcksoDiUkWVpVp3Oex9xGC68JU2dSbUfwZ2jPg== + dependencies: + "@noble/hashes" "~1.2.0" + "@scure/base" "~1.1.0" + +"@scure/bip39@1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.2.1.tgz#5cee8978656b272a917b7871c981e0541ad6ac2a" + integrity sha512-Z3/Fsz1yr904dduJD0NpiyRHhRYHdcnyh73FZWiV+/qhWi83wNJ3NWolYqCEN+ZWsUz2TWwajJggcRE9r1zUYg== + dependencies: + "@noble/hashes" "~1.3.0" + "@scure/base" "~1.1.0" + +"@sentry/core@5.30.0": + version "5.30.0" + resolved "https://registry.yarnpkg.com/@sentry/core/-/core-5.30.0.tgz#6b203664f69e75106ee8b5a2fe1d717379b331f3" + integrity sha512-TmfrII8w1PQZSZgPpUESqjB+jC6MvZJZdLtE/0hZ+SrnKhW3x5WlYLvTXZpcWePYBku7rl2wn1RZu6uT0qCTeg== + dependencies: + "@sentry/hub" "5.30.0" + "@sentry/minimal" "5.30.0" + "@sentry/types" "5.30.0" + "@sentry/utils" "5.30.0" + tslib "^1.9.3" + +"@sentry/hub@5.30.0": + version "5.30.0" + resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-5.30.0.tgz#2453be9b9cb903404366e198bd30c7ca74cdc100" + integrity sha512-2tYrGnzb1gKz2EkMDQcfLrDTvmGcQPuWxLnJKXJvYTQDGLlEvi2tWz1VIHjunmOvJrB5aIQLhm+dcMRwFZDCqQ== + dependencies: + "@sentry/types" "5.30.0" + "@sentry/utils" "5.30.0" + tslib "^1.9.3" + +"@sentry/minimal@5.30.0": + version "5.30.0" + resolved "https://registry.yarnpkg.com/@sentry/minimal/-/minimal-5.30.0.tgz#ce3d3a6a273428e0084adcb800bc12e72d34637b" + integrity sha512-BwWb/owZKtkDX+Sc4zCSTNcvZUq7YcH3uAVlmh/gtR9rmUvbzAA3ewLuB3myi4wWRAMEtny6+J/FN/x+2wn9Xw== + dependencies: + "@sentry/hub" "5.30.0" + "@sentry/types" "5.30.0" + tslib "^1.9.3" + +"@sentry/node@^5.18.1": + version "5.30.0" + resolved "https://registry.yarnpkg.com/@sentry/node/-/node-5.30.0.tgz#4ca479e799b1021285d7fe12ac0858951c11cd48" + integrity sha512-Br5oyVBF0fZo6ZS9bxbJZG4ApAjRqAnqFFurMVJJdunNb80brh7a5Qva2kjhm+U6r9NJAB5OmDyPkA1Qnt+QVg== + dependencies: + "@sentry/core" "5.30.0" + "@sentry/hub" "5.30.0" + "@sentry/tracing" "5.30.0" + "@sentry/types" "5.30.0" + "@sentry/utils" "5.30.0" + cookie "^0.4.1" + https-proxy-agent "^5.0.0" + lru_map "^0.3.3" + tslib "^1.9.3" + +"@sentry/tracing@5.30.0": + version "5.30.0" + resolved "https://registry.yarnpkg.com/@sentry/tracing/-/tracing-5.30.0.tgz#501d21f00c3f3be7f7635d8710da70d9419d4e1f" + integrity sha512-dUFowCr0AIMwiLD7Fs314Mdzcug+gBVo/+NCMyDw8tFxJkwWAKl7Qa2OZxLQ0ZHjakcj1hNKfCQJ9rhyfOl4Aw== + dependencies: + "@sentry/hub" "5.30.0" + "@sentry/minimal" "5.30.0" + "@sentry/types" "5.30.0" + "@sentry/utils" "5.30.0" + tslib "^1.9.3" + +"@sentry/types@5.30.0": + version "5.30.0" + resolved "https://registry.yarnpkg.com/@sentry/types/-/types-5.30.0.tgz#19709bbe12a1a0115bc790b8942917da5636f402" + integrity sha512-R8xOqlSTZ+htqrfteCWU5Nk0CDN5ApUTvrlvBuiH1DyP6czDZ4ktbZB0hAgBlVcK0U+qpD3ag3Tqqpa5Q67rPw== + +"@sentry/utils@5.30.0": + version "5.30.0" + resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-5.30.0.tgz#9a5bd7ccff85ccfe7856d493bffa64cabc41e980" + integrity sha512-zaYmoH0NWWtvnJjC9/CBseXMtKHm/tm40sz3YfJRxeQjyzRqNQPgivpd9R/oDJCYj999mzdW382p/qi2ypjLww== + dependencies: + "@sentry/types" "5.30.0" + tslib "^1.9.3" + +"@sindresorhus/is@^4.0.0", "@sindresorhus/is@^4.6.0": + version "4.6.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.6.0.tgz#3c7c9c46e678feefe7a2e5bb609d3dbd665ffb3f" + integrity sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw== + +"@solidity-parser/parser@^0.14.0": + version "0.14.5" + resolved "https://registry.yarnpkg.com/@solidity-parser/parser/-/parser-0.14.5.tgz#87bc3cc7b068e08195c219c91cd8ddff5ef1a804" + integrity sha512-6dKnHZn7fg/iQATVEzqyUOyEidbn05q7YA2mQ9hC0MMXhhV3/JrsxmFSYZAcr7j1yUP700LLhTruvJ3MiQmjJg== + dependencies: + antlr4ts "^0.5.0-alpha.4" + +"@solidity-parser/parser@^0.16.0": + version "0.16.1" + resolved "https://registry.yarnpkg.com/@solidity-parser/parser/-/parser-0.16.1.tgz#f7c8a686974e1536da0105466c4db6727311253c" + integrity sha512-PdhRFNhbTtu3x8Axm0uYpqOy/lODYQK+MlYSgqIsq2L8SFYEHJPHNUiOTAJbDGzNjjr1/n9AcIayxafR/fWmYw== + dependencies: + antlr4ts "^0.5.0-alpha.4" + +"@szmarczak/http-timer@^4.0.5": + version "4.0.6" + resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-4.0.6.tgz#b4a914bb62e7c272d4e5989fe4440f812ab1d807" + integrity sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w== + dependencies: + defer-to-connect "^2.0.0" + +"@szmarczak/http-timer@^5.0.1": + version "5.0.1" + resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-5.0.1.tgz#c7c1bf1141cdd4751b0399c8fc7b8b664cd5be3a" + integrity sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw== + dependencies: + defer-to-connect "^2.0.1" + +"@truffle/abi-utils@^1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@truffle/abi-utils/-/abi-utils-1.0.3.tgz#9f0df7a8aaf5e815bee47e0ad26bd4c91e4045f2" + integrity sha512-AWhs01HCShaVKjml7Z4AbVREr/u4oiWxCcoR7Cktm0mEvtT04pvnxW5xB/cI4znRkrbPdFQlFt67kgrAjesYkw== + dependencies: + change-case "3.0.2" + fast-check "3.1.1" + web3-utils "1.10.0" + +"@truffle/blockchain-utils@^0.1.3": + version "0.1.9" + resolved "https://registry.yarnpkg.com/@truffle/blockchain-utils/-/blockchain-utils-0.1.9.tgz#d9b55bd23a134578e4217bae55a6dfbbb038d6dc" + integrity sha512-RHfumgbIVo68Rv9ofDYfynjnYZIfP/f1vZy4RoqkfYAO+fqfc58PDRzB1WAGq2U6GPuOnipOJxQhnqNnffORZg== + +"@truffle/codec@^0.17.3": + version "0.17.3" + resolved "https://registry.yarnpkg.com/@truffle/codec/-/codec-0.17.3.tgz#94057e56e1a947594b35eba498d96915df3861d2" + integrity sha512-Ko/+dsnntNyrJa57jUD9u4qx9nQby+H4GsUO6yjiCPSX0TQnEHK08XWqBSg0WdmCH2+h0y1nr2CXSx8gbZapxg== + dependencies: + "@truffle/abi-utils" "^1.0.3" + "@truffle/compile-common" "^0.9.8" + big.js "^6.0.3" + bn.js "^5.1.3" + cbor "^5.2.0" + debug "^4.3.1" + lodash "^4.17.21" + semver "^7.5.4" + utf8 "^3.0.0" + web3-utils "1.10.0" + +"@truffle/compile-common@^0.9.8": + version "0.9.8" + resolved "https://registry.yarnpkg.com/@truffle/compile-common/-/compile-common-0.9.8.tgz#f91507c895852289a17bf401eefebc293c4c69f0" + integrity sha512-DTpiyo32t/YhLI1spn84D3MHYHrnoVqO+Gp7ZHrYNwDs86mAxtNiH5lsVzSb8cPgiqlvNsRCU9nm9R0YmKMTBQ== + dependencies: + "@truffle/error" "^0.2.2" + colors "1.4.0" + +"@truffle/contract-schema@^3.4.7": + version "3.4.16" + resolved "https://registry.yarnpkg.com/@truffle/contract-schema/-/contract-schema-3.4.16.tgz#c529c3f230db407b2f03290373b20b7366f2d37e" + integrity sha512-g0WNYR/J327DqtJPI70ubS19K1Fth/1wxt2jFqLsPmz5cGZVjCwuhiie+LfBde4/Mc9QR8G+L3wtmT5cyoBxAg== + dependencies: + ajv "^6.10.0" + debug "^4.3.1" + +"@truffle/debug-utils@^6.0.22": + version "6.0.57" + resolved "https://registry.yarnpkg.com/@truffle/debug-utils/-/debug-utils-6.0.57.tgz#4e9a1051221c5f467daa398b0ca638d8b6408a82" + integrity sha512-Q6oI7zLaeNLB69ixjwZk2UZEWBY6b2OD1sjLMGDKBGR7GaHYiw96GLR2PFgPH1uwEeLmV4N78LYaQCrDsHbNeA== + dependencies: + "@truffle/codec" "^0.17.3" + "@trufflesuite/chromafi" "^3.0.0" + bn.js "^5.1.3" + chalk "^2.4.2" + debug "^4.3.1" + highlightjs-solidity "^2.0.6" + +"@truffle/error@^0.1.0": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@truffle/error/-/error-0.1.1.tgz#e52026ac8ca7180d83443dca73c03e07ace2a301" + integrity sha512-sE7c9IHIGdbK4YayH4BC8i8qMjoAOeg6nUXUDZZp8wlU21/EMpaG+CLx+KqcIPyR+GSWIW3Dm0PXkr2nlggFDA== + +"@truffle/error@^0.2.2": + version "0.2.2" + resolved "https://registry.yarnpkg.com/@truffle/error/-/error-0.2.2.tgz#1b4c4237c14dda792f20bd4f19ff4e4585b47796" + integrity sha512-TqbzJ0O8DHh34cu8gDujnYl4dUl6o2DE4PR6iokbybvnIm/L2xl6+Gv1VC+YJS45xfH83Yo3/Zyg/9Oq8/xZWg== + +"@truffle/interface-adapter@^0.5.16": + version "0.5.37" + resolved "https://registry.yarnpkg.com/@truffle/interface-adapter/-/interface-adapter-0.5.37.tgz#95d249c1912d2baaa63c54e8a138d3f476a1181a" + integrity sha512-lPH9MDgU+7sNDlJSClwyOwPCfuOimqsCx0HfGkznL3mcFRymc1pukAR1k17zn7ErHqBwJjiKAZ6Ri72KkS+IWw== + dependencies: + bn.js "^5.1.3" + ethers "^4.0.32" + web3 "1.10.0" + +"@trufflesuite/bigint-buffer@1.1.10": + version "1.1.10" + resolved "https://registry.yarnpkg.com/@trufflesuite/bigint-buffer/-/bigint-buffer-1.1.10.tgz#a1d9ca22d3cad1a138b78baaf15543637a3e1692" + integrity sha512-pYIQC5EcMmID74t26GCC67946mgTJFiLXOT/BYozgrd4UEY2JHEGLhWi9cMiQCt5BSqFEvKkCHNnoj82SRjiEw== + dependencies: + node-gyp-build "4.4.0" + +"@trufflesuite/bigint-buffer@1.1.9": + version "1.1.9" + resolved "https://registry.yarnpkg.com/@trufflesuite/bigint-buffer/-/bigint-buffer-1.1.9.tgz#e2604d76e1e4747b74376d68f1312f9944d0d75d" + integrity sha512-bdM5cEGCOhDSwminryHJbRmXc1x7dPKg6Pqns3qyTwFlxsqUgxE29lsERS3PlIW1HTjoIGMUqsk1zQQwST1Yxw== + dependencies: + node-gyp-build "4.3.0" + +"@trufflesuite/chromafi@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@trufflesuite/chromafi/-/chromafi-3.0.0.tgz#f6956408c1af6a38a6ed1657783ce59504a1eb8b" + integrity sha512-oqWcOqn8nT1bwlPPfidfzS55vqcIDdpfzo3HbU9EnUmcSTX+I8z0UyUFI3tZQjByVJulbzxHxUGS3ZJPwK/GPQ== + dependencies: + camelcase "^4.1.0" + chalk "^2.3.2" + cheerio "^1.0.0-rc.2" + detect-indent "^5.0.0" + highlight.js "^10.4.1" + lodash.merge "^4.6.2" + strip-ansi "^4.0.0" + strip-indent "^2.0.0" + +"@tsconfig/node10@^1.0.7": + version "1.0.9" + resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.9.tgz#df4907fc07a886922637b15e02d4cebc4c0021b2" + integrity sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA== + +"@tsconfig/node12@^1.0.7": + version "1.0.11" + resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.11.tgz#ee3def1f27d9ed66dac6e46a295cffb0152e058d" + integrity sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag== + +"@tsconfig/node14@^1.0.0": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.3.tgz#e4386316284f00b98435bf40f72f75a09dabf6c1" + integrity sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow== + +"@tsconfig/node16@^1.0.2": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.4.tgz#0b92dcc0cc1c81f6f306a381f28e31b1a56536e9" + integrity sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA== + +"@typechain/ethers-v5@^10.0.0": + version "10.2.1" + resolved "https://registry.yarnpkg.com/@typechain/ethers-v5/-/ethers-v5-10.2.1.tgz#50241e6957683281ecfa03fb5a6724d8a3ce2391" + integrity sha512-n3tQmCZjRE6IU4h6lqUGiQ1j866n5MTCBJreNEHHVWXa2u9GJTaeYyU1/k+1qLutkyw+sS6VAN+AbeiTqsxd/A== + dependencies: + lodash "^4.17.15" + ts-essentials "^7.0.1" + +"@typechain/ethers-v5@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@typechain/ethers-v5/-/ethers-v5-7.2.0.tgz#d559cffe0efe6bdbc20e644b817f6fa8add5e8f8" + integrity sha512-jfcmlTvaaJjng63QsT49MT6R1HFhtO/TBMWbyzPFSzMmVIqb2tL6prnKBs4ZJrSvmgIXWy+ttSjpaxCTq8D/Tw== + dependencies: + lodash "^4.17.15" + ts-essentials "^7.0.1" + +"@typechain/hardhat@^2.3.1": + version "2.3.1" + resolved "https://registry.yarnpkg.com/@typechain/hardhat/-/hardhat-2.3.1.tgz#1e8a6e3795e115a5d5348526282b5c597fab0b78" + integrity sha512-BQV8OKQi0KAzLXCdsPO0pZBNQQ6ra8A2ucC26uFX/kquRBtJu1yEyWnVSmtr07b5hyRoJRpzUeINLnyqz4/MAw== + dependencies: + fs-extra "^9.1.0" + +"@types/abstract-leveldown@*": + version "7.2.5" + resolved "https://registry.yarnpkg.com/@types/abstract-leveldown/-/abstract-leveldown-7.2.5.tgz#db2cf364c159fb1f12be6cd3549f56387eaf8d73" + integrity sha512-/2B0nQF4UdupuxeKTJA2+Rj1D+uDemo6P4kMwKCpbfpnzeVaWSELTsAw4Lxn3VJD6APtRrZOCuYo+4nHUQfTfg== + +"@types/bignumber.js@^5.0.0": + version "5.0.0" + resolved "https://registry.yarnpkg.com/@types/bignumber.js/-/bignumber.js-5.0.0.tgz#d9f1a378509f3010a3255e9cc822ad0eeb4ab969" + integrity sha512-0DH7aPGCClywOFaxxjE6UwpN2kQYe9LwuDQMv+zYA97j5GkOMo8e66LYT+a8JYU7jfmUFRZLa9KycxHDsKXJCA== + dependencies: + bignumber.js "*" + +"@types/bn.js@^4.11.3": + version "4.11.6" + resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-4.11.6.tgz#c306c70d9358aaea33cd4eda092a742b9505967c" + integrity sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg== + dependencies: + "@types/node" "*" + +"@types/bn.js@^5.1.0", "@types/bn.js@^5.1.1": + version "5.1.5" + resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-5.1.5.tgz#2e0dacdcce2c0f16b905d20ff87aedbc6f7b4bf0" + integrity sha512-V46N0zwKRF5Q00AZ6hWtN0T8gGmDUaUzLWQvHFo5yThtVwK/VCenFY3wXVbOvNfajEpsTfQM4IN9k/d6gUVX3A== + dependencies: + "@types/node" "*" + +"@types/cacheable-request@^6.0.1", "@types/cacheable-request@^6.0.2": + version "6.0.3" + resolved "https://registry.yarnpkg.com/@types/cacheable-request/-/cacheable-request-6.0.3.tgz#a430b3260466ca7b5ca5bfd735693b36e7a9d183" + integrity sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw== + dependencies: + "@types/http-cache-semantics" "*" + "@types/keyv" "^3.1.4" + "@types/node" "*" + "@types/responselike" "^1.0.0" + +"@types/chai-as-promised@^7.1.5": + version "7.1.8" + resolved "https://registry.yarnpkg.com/@types/chai-as-promised/-/chai-as-promised-7.1.8.tgz#f2b3d82d53c59626b5d6bbc087667ccb4b677fe9" + integrity sha512-ThlRVIJhr69FLlh6IctTXFkmhtP3NpMZ2QGq69StYLyKZFp/HOp1VdKZj7RvfNWYYcJ1xlbLGLLWj1UvP5u/Gw== + dependencies: + "@types/chai" "*" + +"@types/chai-string@^1.4.2": + version "1.4.5" + resolved "https://registry.yarnpkg.com/@types/chai-string/-/chai-string-1.4.5.tgz#988ff37526386e9c354219b163d7ecf81bab8d2d" + integrity sha512-IecXRMSnpUvRnTztdpSdjcmcW7EdNme65bfDCQMi7XrSEPGmyDYYTEfc5fcactWDA6ioSm8o7NUqg9QxjBCCEw== + dependencies: + "@types/chai" "*" + +"@types/chai@*", "@types/chai@^4.2.0", "@types/chai@^4.3.1": + version "4.3.9" + resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.3.9.tgz#144d762491967db8c6dea38e03d2206c2623feec" + integrity sha512-69TtiDzu0bcmKQv3yg1Zx409/Kd7r0b5F1PfpYJfSHzLGtB53547V4u+9iqKYsTu/O2ai6KTb0TInNpvuQ3qmg== + +"@types/concat-stream@^1.6.0": + version "1.6.1" + resolved "https://registry.yarnpkg.com/@types/concat-stream/-/concat-stream-1.6.1.tgz#24bcfc101ecf68e886aaedce60dfd74b632a1b74" + integrity sha512-eHE4cQPoj6ngxBZMvVf6Hw7Mh4jMW4U9lpGmS5GBPB9RYxlFg+CHaVN7ErNY4W9XfLIEn20b4VDYaIrbq0q4uA== + dependencies: + "@types/node" "*" + +"@types/form-data@0.0.33": + version "0.0.33" + resolved "https://registry.yarnpkg.com/@types/form-data/-/form-data-0.0.33.tgz#c9ac85b2a5fd18435b8c85d9ecb50e6d6c893ff8" + integrity sha512-8BSvG1kGm83cyJITQMZSulnl6QV8jqAGreJsc5tPu1Jq0vTSOiY/k24Wx82JRpWwZSqrala6sd5rWi6aNXvqcw== + dependencies: + "@types/node" "*" + +"@types/glob@^7.1.1": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.2.0.tgz#bc1b5bf3aa92f25bd5dd39f35c57361bdce5b2eb" + integrity sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA== + dependencies: + "@types/minimatch" "*" + "@types/node" "*" + +"@types/http-cache-semantics@*": + version "4.0.4" + resolved "https://registry.yarnpkg.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz#b979ebad3919799c979b17c72621c0bc0a31c6c4" + integrity sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA== + +"@types/json-schema@^7.0.7": + version "7.0.15" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" + integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== + +"@types/json5@^0.0.29": + version "0.0.29" + resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" + integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== + +"@types/keyv@^3.1.4": + version "3.1.4" + resolved "https://registry.yarnpkg.com/@types/keyv/-/keyv-3.1.4.tgz#3ccdb1c6751b0c7e52300bcdacd5bcbf8faa75b6" + integrity sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg== + dependencies: + "@types/node" "*" + +"@types/level-errors@*": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@types/level-errors/-/level-errors-3.0.2.tgz#f33ec813c50780b547463da9ad8acac89ee457d9" + integrity sha512-gyZHbcQ2X5hNXf/9KS2qGEmgDe9EN2WDM3rJ5Ele467C0nA1sLhtmv1bZiPMDYfAYCfPWft0uQIaTvXbASSTRA== + +"@types/levelup@^4.3.0": + version "4.3.3" + resolved "https://registry.yarnpkg.com/@types/levelup/-/levelup-4.3.3.tgz#4dc2b77db079b1cf855562ad52321aa4241b8ef4" + integrity sha512-K+OTIjJcZHVlZQN1HmU64VtrC0jC3dXWQozuEIR9zVvltIk90zaGPM2AgT+fIkChpzHhFE3YnvFLCbLtzAmexA== + dependencies: + "@types/abstract-leveldown" "*" + "@types/level-errors" "*" + "@types/node" "*" + +"@types/lru-cache@5.1.1", "@types/lru-cache@^5.1.0": + version "5.1.1" + resolved "https://registry.yarnpkg.com/@types/lru-cache/-/lru-cache-5.1.1.tgz#c48c2e27b65d2a153b19bfc1a317e30872e01eef" + integrity sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw== + +"@types/minimatch@*": + version "5.1.2" + resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-5.1.2.tgz#07508b45797cb81ec3f273011b054cd0755eddca" + integrity sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA== + +"@types/mkdirp@^0.5.2": + version "0.5.2" + resolved "https://registry.yarnpkg.com/@types/mkdirp/-/mkdirp-0.5.2.tgz#503aacfe5cc2703d5484326b1b27efa67a339c1f" + integrity sha512-U5icWpv7YnZYGsN4/cmh3WD2onMY0aJIiTE6+51TwJCttdHvtCYmkBNOobHlXwrJRL0nkH9jH4kD+1FAdMN4Tg== + dependencies: + "@types/node" "*" + +"@types/mocha@^9.1.1": + version "9.1.1" + resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-9.1.1.tgz#e7c4f1001eefa4b8afbd1eee27a237fee3bf29c4" + integrity sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw== + +"@types/node-fetch@^2.6.1": + version "2.6.9" + resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.6.9.tgz#15f529d247f1ede1824f7e7acdaa192d5f28071e" + integrity sha512-bQVlnMLFJ2d35DkPNjEPmd9ueO/rh5EiaZt2bhqiSarPjZIuIV6bPQVqcrEyvNo+AfTrRGVazle1tl597w3gfA== + dependencies: + "@types/node" "*" + form-data "^4.0.0" + +"@types/node@*": + version "20.8.10" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.8.10.tgz#a5448b895c753ae929c26ce85cab557c6d4a365e" + integrity sha512-TlgT8JntpcbmKUFzjhsyhGfP2fsiz1Mv56im6enJ905xG1DAYesxJaeSbGqQmAw8OWPdhyJGhGSQGKRNJ45u9w== + dependencies: + undici-types "~5.26.4" + +"@types/node@11.11.6": + version "11.11.6" + resolved "https://registry.yarnpkg.com/@types/node/-/node-11.11.6.tgz#df929d1bb2eee5afdda598a41930fe50b43eaa6a" + integrity sha512-Exw4yUWMBXM3X+8oqzJNRqZSwUAaS4+7NdvHqQuFi/d+synz++xmX3QIf+BFqneW8N31R8Ky+sikfZUXq07ggQ== + +"@types/node@^10.0.3": + version "10.17.60" + resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.60.tgz#35f3d6213daed95da7f0f73e75bcc6980e90597b" + integrity sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw== + +"@types/node@^12.12.6", "@types/node@^12.20.54": + version "12.20.55" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.55.tgz#c329cbd434c42164f846b909bd6f85b5537f6240" + integrity sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ== + +"@types/node@^8.0.0": + version "8.10.66" + resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.66.tgz#dd035d409df322acc83dff62a602f12a5783bbb3" + integrity sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw== + +"@types/pbkdf2@^3.0.0": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@types/pbkdf2/-/pbkdf2-3.1.2.tgz#2dc43808e9985a2c69ff02e2d2027bd4fe33e8dc" + integrity sha512-uRwJqmiXmh9++aSu1VNEn3iIxWOhd8AHXNSdlaLfdAAdSTY9jYVeGWnzejM3dvrkbqE3/hyQkQQ29IFATEGlew== + dependencies: + "@types/node" "*" + +"@types/prettier@^2.1.1": + version "2.7.3" + resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.7.3.tgz#3e51a17e291d01d17d3fc61422015a933af7a08f" + integrity sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA== + +"@types/qs@^6.2.31", "@types/qs@^6.9.7": + version "6.9.10" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.10.tgz#0af26845b5067e1c9a622658a51f60a3934d51e8" + integrity sha512-3Gnx08Ns1sEoCrWssEgTSJs/rsT2vhGP+Ja9cnnk9k4ALxinORlQneLXFeFKOTJMOeZUFD1s7w+w2AphTpvzZw== + +"@types/readable-stream@^2.3.13": + version "2.3.15" + resolved "https://registry.yarnpkg.com/@types/readable-stream/-/readable-stream-2.3.15.tgz#3d79c9ceb1b6a57d5f6e6976f489b9b5384321ae" + integrity sha512-oM5JSKQCcICF1wvGgmecmHldZ48OZamtMxcGGVICOJA8o8cahXC1zEVAif8iwoc5j8etxFaRFnf095+CDsuoFQ== + dependencies: + "@types/node" "*" + safe-buffer "~5.1.1" + +"@types/responselike@^1.0.0": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@types/responselike/-/responselike-1.0.3.tgz#cc29706f0a397cfe6df89debfe4bf5cea159db50" + integrity sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw== + dependencies: + "@types/node" "*" + +"@types/secp256k1@^4.0.1": + version "4.0.6" + resolved "https://registry.yarnpkg.com/@types/secp256k1/-/secp256k1-4.0.6.tgz#d60ba2349a51c2cbc5e816dcd831a42029d376bf" + integrity sha512-hHxJU6PAEUn0TP4S/ZOzuTUvJWuZ6eIKeNKb5RBpODvSl6hp1Wrw4s7ATY50rklRCScUDpHzVA/DQdSjJ3UoYQ== + dependencies: + "@types/node" "*" + +"@types/seedrandom@3.0.1": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@types/seedrandom/-/seedrandom-3.0.1.tgz#1254750a4fec4aff2ebec088ccd0bb02e91fedb4" + integrity sha512-giB9gzDeiCeloIXDgzFBCgjj1k4WxcDrZtGl6h1IqmUPlxF+Nx8Ve+96QCyDZ/HseB/uvDsKbpib9hU5cU53pw== + +"@typescript-eslint/eslint-plugin@^4.33.0": + version "4.33.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.33.0.tgz#c24dc7c8069c7706bc40d99f6fa87edcb2005276" + integrity sha512-aINiAxGVdOl1eJyVjaWn/YcVAq4Gi/Yo35qHGCnqbWVz61g39D0h23veY/MA0rFFGfxK7TySg2uwDeNv+JgVpg== + dependencies: + "@typescript-eslint/experimental-utils" "4.33.0" + "@typescript-eslint/scope-manager" "4.33.0" + debug "^4.3.1" + functional-red-black-tree "^1.0.1" + ignore "^5.1.8" + regexpp "^3.1.0" + semver "^7.3.5" + tsutils "^3.21.0" + +"@typescript-eslint/experimental-utils@4.33.0": + version "4.33.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.33.0.tgz#6f2a786a4209fa2222989e9380b5331b2810f7fd" + integrity sha512-zeQjOoES5JFjTnAhI5QY7ZviczMzDptls15GFsI6jyUOq0kOf9+WonkhtlIhh0RgHRnqj5gdNxW5j1EvAyYg6Q== + dependencies: + "@types/json-schema" "^7.0.7" + "@typescript-eslint/scope-manager" "4.33.0" + "@typescript-eslint/types" "4.33.0" + "@typescript-eslint/typescript-estree" "4.33.0" + eslint-scope "^5.1.1" + eslint-utils "^3.0.0" + +"@typescript-eslint/parser@^4.33.0": + version "4.33.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.33.0.tgz#dfe797570d9694e560528d18eecad86c8c744899" + integrity sha512-ZohdsbXadjGBSK0/r+d87X0SBmKzOq4/S5nzK6SBgJspFo9/CUDJ7hjayuze+JK7CZQLDMroqytp7pOcFKTxZA== + dependencies: + "@typescript-eslint/scope-manager" "4.33.0" + "@typescript-eslint/types" "4.33.0" + "@typescript-eslint/typescript-estree" "4.33.0" + debug "^4.3.1" + +"@typescript-eslint/scope-manager@4.33.0": + version "4.33.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.33.0.tgz#d38e49280d983e8772e29121cf8c6e9221f280a3" + integrity sha512-5IfJHpgTsTZuONKbODctL4kKuQje/bzBRkwHE8UOZ4f89Zeddg+EGZs8PD8NcN4LdM3ygHWYB3ukPAYjvl/qbQ== + dependencies: + "@typescript-eslint/types" "4.33.0" + "@typescript-eslint/visitor-keys" "4.33.0" + +"@typescript-eslint/types@4.33.0": + version "4.33.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.33.0.tgz#a1e59036a3b53ae8430ceebf2a919dc7f9af6d72" + integrity sha512-zKp7CjQzLQImXEpLt2BUw1tvOMPfNoTAfb8l51evhYbOEEzdWyQNmHWWGPR6hwKJDAi+1VXSBmnhL9kyVTTOuQ== + +"@typescript-eslint/typescript-estree@4.33.0": + version "4.33.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.33.0.tgz#0dfb51c2908f68c5c08d82aefeaf166a17c24609" + integrity sha512-rkWRY1MPFzjwnEVHsxGemDzqqddw2QbTJlICPD9p9I9LfsO8fdmfQPOX3uKfUaGRDFJbfrtm/sXhVXN4E+bzCA== + dependencies: + "@typescript-eslint/types" "4.33.0" + "@typescript-eslint/visitor-keys" "4.33.0" + debug "^4.3.1" + globby "^11.0.3" + is-glob "^4.0.1" + semver "^7.3.5" + tsutils "^3.21.0" + +"@typescript-eslint/visitor-keys@4.33.0": + version "4.33.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.33.0.tgz#2a22f77a41604289b7a186586e9ec48ca92ef1dd" + integrity sha512-uqi/2aSz9g2ftcHWf8uLPJA70rUv6yuMW5Bohw+bwcuzaxQIHaKFZCKGoGXIrc9vkTJ3+0txM73K0Hq3d5wgIg== + dependencies: + "@typescript-eslint/types" "4.33.0" + eslint-visitor-keys "^2.0.0" + +"@uniswap/lib@^4.0.1-alpha": + version "4.0.1-alpha" + resolved "https://registry.yarnpkg.com/@uniswap/lib/-/lib-4.0.1-alpha.tgz#2881008e55f075344675b3bca93f020b028fbd02" + integrity sha512-f6UIliwBbRsgVLxIaBANF6w09tYqc6Y/qXdsrbEmXHyFA7ILiKrIwRFXe1yOg8M3cksgVsO9N7yuL2DdCGQKBA== + +"@uniswap/sdk-core@^4", "@uniswap/sdk-core@^4.0.9": + version "4.0.9" + resolved "https://registry.yarnpkg.com/@uniswap/sdk-core/-/sdk-core-4.0.9.tgz#7aef87de6d944307ce9bd57d1e1adfdcb2fed3ee" + integrity sha512-/0K+u3ZWokpj9VyRuGwrwx7jy31auJdsw5UbKnvHqUSfejrp6XhmMPNOElPgL6jiUhAN1NhVHfjX01tNHFxeLA== + dependencies: + "@ethersproject/address" "^5.0.2" + big.js "^5.2.2" + decimal.js-light "^2.5.0" + jsbi "^3.1.4" + tiny-invariant "^1.1.0" + toformat "^2.0.0" + +"@uniswap/swap-router-contracts@^1.2.1": + version "1.3.1" + resolved "https://registry.yarnpkg.com/@uniswap/swap-router-contracts/-/swap-router-contracts-1.3.1.tgz#0ebbb93eb578625618ed9489872de381f9c66fb4" + integrity sha512-mh/YNbwKb7Mut96VuEtL+Z5bRe0xVIbjjiryn+iMMrK2sFKhR4duk/86mEz0UO5gSx4pQIw9G5276P5heY/7Rg== + dependencies: + "@openzeppelin/contracts" "3.4.2-solc-0.7" + "@uniswap/v2-core" "^1.0.1" + "@uniswap/v3-core" "^1.0.0" + "@uniswap/v3-periphery" "^1.4.4" + dotenv "^14.2.0" + hardhat-watcher "^2.1.1" + +"@uniswap/v2-core@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@uniswap/v2-core/-/v2-core-1.0.1.tgz#af8f508bf183204779938969e2e54043e147d425" + integrity sha512-MtybtkUPSyysqLY2U210NBDeCHX+ltHt3oADGdjqoThZaFRDKwM6k1Nb3F0A3hk5hwuQvytFWhrWHOEq6nVJ8Q== + +"@uniswap/v3-core@1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@uniswap/v3-core/-/v3-core-1.0.0.tgz#6c24adacc4c25dceee0ba3ca142b35adbd7e359d" + integrity sha512-kSC4djMGKMHj7sLMYVnn61k9nu+lHjMIxgg9CDQT+s2QYLoA56GbSK9Oxr+qJXzzygbkrmuY6cwgP6cW2JXPFA== + +"@uniswap/v3-core@^1.0.0", "@uniswap/v3-core@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@uniswap/v3-core/-/v3-core-1.0.1.tgz#b6d2bdc6ba3c3fbd610bdc502395d86cd35264a0" + integrity sha512-7pVk4hEm00j9tc71Y9+ssYpO6ytkeI0y7WE9P6UcmNzhxPePwyAxImuhVsTqWK9YFvzgtvzJHi64pBl4jUzKMQ== + +"@uniswap/v3-periphery@^1.0.1", "@uniswap/v3-periphery@^1.1.1", "@uniswap/v3-periphery@^1.4.4": + version "1.4.4" + resolved "https://registry.yarnpkg.com/@uniswap/v3-periphery/-/v3-periphery-1.4.4.tgz#d2756c23b69718173c5874f37fd4ad57d2f021b7" + integrity sha512-S4+m+wh8HbWSO3DKk4LwUCPZJTpCugIsHrWR86m/OrUyvSqGDTXKFfc2sMuGXCZrD1ZqO3rhQsKgdWg3Hbb2Kw== + dependencies: + "@openzeppelin/contracts" "3.4.2-solc-0.7" + "@uniswap/lib" "^4.0.1-alpha" + "@uniswap/v2-core" "^1.0.1" + "@uniswap/v3-core" "^1.0.0" + base64-sol "1.0.1" + +"@uniswap/v3-sdk@^3.10.0": + version "3.10.0" + resolved "https://registry.yarnpkg.com/@uniswap/v3-sdk/-/v3-sdk-3.10.0.tgz#962c9e598250ced00702d944783c2d9ee3fa12f6" + integrity sha512-sbmSA1O+Ct960r66Ie/c1rOmVadpwRu8nQ79pGICv0pZJdnFIQ/SReG3F+iC2C2UNNjNP6aC2WDUggXrjyrgnA== + dependencies: + "@ethersproject/abi" "^5.0.12" + "@ethersproject/solidity" "^5.0.9" + "@uniswap/sdk-core" "^4" + "@uniswap/swap-router-contracts" "^1.2.1" + "@uniswap/v3-periphery" "^1.1.1" + "@uniswap/v3-staker" "1.0.0" + tiny-invariant "^1.1.0" + tiny-warning "^1.0.3" + +"@uniswap/v3-staker@1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@uniswap/v3-staker/-/v3-staker-1.0.0.tgz#9a6915ec980852479dfc903f50baf822ff8fa66e" + integrity sha512-JV0Qc46Px5alvg6YWd+UIaGH9lDuYG/Js7ngxPit1SPaIP30AlVer1UYB7BRYeUVVxE+byUyIeN5jeQ7LLDjIw== + dependencies: + "@openzeppelin/contracts" "3.4.1-solc-0.7-2" + "@uniswap/v3-core" "1.0.0" + "@uniswap/v3-periphery" "^1.0.1" + +abbrev@1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== + +abbrev@1.0.x: + version "1.0.9" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.0.9.tgz#91b4792588a7738c25f35dd6f63752a2f8776135" + integrity sha512-LEyx4aLEC3x6T0UguF6YILf+ntvmOaWsVfENmIW0E9H09vKlLDGelMjjSm0jkDHALj8A8quZ/HapKNigzwge+Q== + +abortcontroller-polyfill@^1.7.3, abortcontroller-polyfill@^1.7.5: + version "1.7.5" + resolved "https://registry.yarnpkg.com/abortcontroller-polyfill/-/abortcontroller-polyfill-1.7.5.tgz#6738495f4e901fbb57b6c0611d0c75f76c485bed" + integrity sha512-JMJ5soJWP18htbbxJjG7bG6yuI6pRhgJ0scHHTfkUjf6wjP912xZWvM+A4sJK3gqd9E8fcPbDnOefbA9Th/FIQ== + +abstract-level@^1.0.0, abstract-level@^1.0.2, abstract-level@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/abstract-level/-/abstract-level-1.0.3.tgz#78a67d3d84da55ee15201486ab44c09560070741" + integrity sha512-t6jv+xHy+VYwc4xqZMn2Pa9DjcdzvzZmQGRjTFc8spIbRGHgBrEKbPq+rYXc7CCo0lxgYvSgKVg9qZAhpVQSjA== + dependencies: + buffer "^6.0.3" + catering "^2.1.0" + is-buffer "^2.0.5" + level-supports "^4.0.0" + level-transcoder "^1.0.1" + module-error "^1.0.1" + queue-microtask "^1.2.3" + +abstract-leveldown@^6.2.1: + version "6.3.0" + resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-6.3.0.tgz#d25221d1e6612f820c35963ba4bd739928f6026a" + integrity sha512-TU5nlYgta8YrBMNpc9FwQzRbiXsj49gsALsXadbGHt9CROPzX5fB0rWDR5mtdpOOKa5XqRFpbj1QroPAoPzVjQ== + dependencies: + buffer "^5.5.0" + immediate "^3.2.3" + level-concat-iterator "~2.0.0" + level-supports "~1.0.0" + xtend "~4.0.0" + +abstract-leveldown@^7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-7.2.0.tgz#08d19d4e26fb5be426f7a57004851b39e1795a2e" + integrity sha512-DnhQwcFEaYsvYDnACLZhMmCWd3rkOeEvglpa4q5i/5Jlm3UIsWaxVzuXvDLFCSCWRO3yy2/+V/G7FusFgejnfQ== + dependencies: + buffer "^6.0.3" + catering "^2.0.0" + is-buffer "^2.0.5" + level-concat-iterator "^3.0.0" + level-supports "^2.0.1" + queue-microtask "^1.2.3" + +abstract-leveldown@~6.2.1: + version "6.2.3" + resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-6.2.3.tgz#036543d87e3710f2528e47040bc3261b77a9a8eb" + integrity sha512-BsLm5vFMRUrrLeCcRc+G0t2qOaTzpoJQLOubq2XM72eNpjF5UdU5o/5NvlNhx95XHcAvcl8OMXr4mlg/fRgUXQ== + dependencies: + buffer "^5.5.0" + immediate "^3.2.3" + level-concat-iterator "~2.0.0" + level-supports "~1.0.0" + xtend "~4.0.0" + +accepts@~1.3.8: + version "1.3.8" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" + integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== + dependencies: + mime-types "~2.1.34" + negotiator "0.6.3" + +acorn-jsx@^5.3.1: + version "5.3.2" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" + integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== + +acorn-walk@^8.1.1: + version "8.3.0" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.3.0.tgz#2097665af50fd0cf7a2dfccd2b9368964e66540f" + integrity sha512-FS7hV565M5l1R08MXqo8odwMTB02C2UqzB17RVgu9EyuYFBqJZ3/ZY97sQD5FewVu1UyDFc1yztUDrAwT0EypA== + +acorn@^7.4.0: + version "7.4.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" + integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== + +acorn@^8.4.1: + version "8.11.2" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.2.tgz#ca0d78b51895be5390a5903c5b3bdcdaf78ae40b" + integrity sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w== + +address@^1.0.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/address/-/address-1.2.2.tgz#2b5248dac5485a6390532c6a517fda2e3faac89e" + integrity sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA== + +adm-zip@^0.4.16: + version "0.4.16" + resolved "https://registry.yarnpkg.com/adm-zip/-/adm-zip-0.4.16.tgz#cf4c508fdffab02c269cbc7f471a875f05570365" + integrity sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg== + +aes-js@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-3.0.0.tgz#e21df10ad6c2053295bcbb8dab40b09dbea87e4d" + integrity sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw== + +agent-base@6: + version "6.0.2" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" + integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== + dependencies: + debug "4" + +aggregate-error@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" + integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== + dependencies: + clean-stack "^2.0.0" + indent-string "^4.0.0" + +ajv@^6.10.0, ajv@^6.12.3, ajv@^6.12.4, ajv@^6.12.6: + version "6.12.6" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +ajv@^8.0.1: + version "8.12.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.12.0.tgz#d1a0527323e22f53562c567c00991577dfbe19d1" + integrity sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA== + dependencies: + fast-deep-equal "^3.1.1" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + uri-js "^4.2.2" + +amdefine@>=0.0.4: + version "1.0.1" + resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" + integrity sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg== + +ansi-colors@4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" + integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== + +ansi-colors@^4.1.1: + version "4.1.3" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.3.tgz#37611340eb2243e70cc604cad35d63270d48781b" + integrity sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw== + +ansi-escapes@^4.3.0: + version "4.3.2" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" + integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== + dependencies: + type-fest "^0.21.3" + +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + integrity sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA== + +ansi-regex@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.1.tgz#123d6479e92ad45ad897d4054e3c7ca7db4944e1" + integrity sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw== + +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +ansi-styles@^4.0.0, ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +antlr4@^4.11.0: + version "4.13.1" + resolved "https://registry.yarnpkg.com/antlr4/-/antlr4-4.13.1.tgz#1e0a1830a08faeb86217cb2e6c34716004e4253d" + integrity sha512-kiXTspaRYvnIArgE97z5YVVf/cDVQABr3abFRR6mE7yesLMkgu4ujuyV/sgxafQ8wgve0DJQUJ38Z8tkgA2izA== + +antlr4ts@^0.5.0-alpha.4: + version "0.5.0-alpha.4" + resolved "https://registry.yarnpkg.com/antlr4ts/-/antlr4ts-0.5.0-alpha.4.tgz#71702865a87478ed0b40c0709f422cf14d51652a" + integrity sha512-WPQDt1B74OfPv/IMS2ekXAKkTZIHl88uMetg6q3OTqgFxZ/dxDXI0EWLyZid/1Pe6hTftyg5N7gel5wNAGxXyQ== + +anymatch@~3.1.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== + +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== + +array-back@^3.0.1, array-back@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/array-back/-/array-back-3.1.0.tgz#b8859d7a508871c9a7b2cf42f99428f65e96bfb0" + integrity sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q== + +array-back@^4.0.1, array-back@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/array-back/-/array-back-4.0.2.tgz#8004e999a6274586beeb27342168652fdb89fa1e" + integrity sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg== + +array-buffer-byte-length@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz#fabe8bc193fea865f317fe7807085ee0dee5aead" + integrity sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A== + dependencies: + call-bind "^1.0.2" + is-array-buffer "^3.0.1" + +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== + +array-includes@^3.1.7: + version "3.1.7" + resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.7.tgz#8cd2e01b26f7a3086cbc87271593fe921c62abda" + integrity sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + get-intrinsic "^1.2.1" + is-string "^1.0.7" + +array-union@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" + integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== + +array-uniq@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" + integrity sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q== + +array.prototype.findlast@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/array.prototype.findlast/-/array.prototype.findlast-1.2.3.tgz#4e4b375de5adf4897fed155e2d2771564865cc3b" + integrity sha512-kcBubumjciBg4JKp5KTKtI7ec7tRefPk88yjkWJwaVKYd9QfTaxcsOxoMNKd7iBr447zCfDV0z1kOF47umv42g== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + es-shim-unscopables "^1.0.0" + get-intrinsic "^1.2.1" + +array.prototype.findlastindex@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.3.tgz#b37598438f97b579166940814e2c0493a4f50207" + integrity sha512-LzLoiOMAxvy+Gd3BAq3B7VeIgPdo+Q8hthvKtXybMvRV0jrXfJM/t8mw7nNlpEcVlVUnCnM2KSX4XU5HmpodOA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + es-shim-unscopables "^1.0.0" + get-intrinsic "^1.2.1" + +array.prototype.flat@^1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz#1476217df8cff17d72ee8f3ba06738db5b387d18" + integrity sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + es-shim-unscopables "^1.0.0" + +array.prototype.flatmap@^1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz#c9a7c6831db8e719d6ce639190146c24bbd3e527" + integrity sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + es-shim-unscopables "^1.0.0" + +arraybuffer.prototype.slice@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.2.tgz#98bd561953e3e74bb34938e77647179dfe6e9f12" + integrity sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw== + dependencies: + array-buffer-byte-length "^1.0.0" + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + get-intrinsic "^1.2.1" + is-array-buffer "^3.0.2" + is-shared-array-buffer "^1.0.2" + +asap@~2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" + integrity sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA== + +asn1@~0.2.3: + version "0.2.6" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.6.tgz#0d3a7bb6e64e02a90c0303b31f292868ea09a08d" + integrity sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ== + dependencies: + safer-buffer "~2.1.0" + +assert-plus@1.0.0, assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + integrity sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw== + +assertion-error@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" + integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw== + +ast-parents@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/ast-parents/-/ast-parents-0.0.1.tgz#508fd0f05d0c48775d9eccda2e174423261e8dd3" + integrity sha512-XHusKxKz3zoYk1ic8Un640joHbFMhbqneyoZfoKnEGtf2ey9Uh/IdpcQplODdO/kENaMIWsD0nJm4+wX3UNLHA== + +astral-regex@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" + integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== + +async-eventemitter@^0.2.4: + version "0.2.4" + resolved "https://registry.yarnpkg.com/async-eventemitter/-/async-eventemitter-0.2.4.tgz#f5e7c8ca7d3e46aab9ec40a292baf686a0bafaca" + integrity sha512-pd20BwL7Yt1zwDFy+8MX8F1+WCT8aQeKj0kQnTrH9WaeRETlRamVhD0JtRPmrV4GfOJ2F9CvdQkZeZhnh2TuHw== + dependencies: + async "^2.4.0" + +async-limiter@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" + integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== + +async@1.x: + version "1.5.2" + resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" + integrity sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w== + +async@^2.4.0: + version "2.6.4" + resolved "https://registry.yarnpkg.com/async/-/async-2.6.4.tgz#706b7ff6084664cd7eae713f6f965433b5504221" + integrity sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA== + dependencies: + lodash "^4.17.14" + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== + +at-least-node@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" + integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== + +available-typed-arrays@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" + integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== + +aws-sign2@~0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" + integrity sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA== + +aws4@^1.8.0: + version "1.12.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.12.0.tgz#ce1c9d143389679e253b314241ea9aa5cec980d3" + integrity sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg== + +axios@^0.21.1: + 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" + +axios@^1.5.0, axios@^1.5.1: + version "1.6.0" + resolved "https://registry.yarnpkg.com/axios/-/axios-1.6.0.tgz#f1e5292f26b2fd5c2e66876adc5b06cdbd7d2102" + integrity sha512-EZ1DYihju9pwVB+jg67ogm+Tmqc6JmhamRN6I4Zt8DfZu5lbcQGw3ozH9lFejSJgs/ibaef3A9PMXPLeefFGJg== + dependencies: + follow-redirects "^1.15.0" + form-data "^4.0.0" + proxy-from-env "^1.1.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== + +base-x@^3.0.2, base-x@^3.0.8: + version "3.0.9" + resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.9.tgz#6349aaabb58526332de9f60995e548a53fe21320" + integrity sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ== + dependencies: + safe-buffer "^5.0.1" + +base64-js@^1.3.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== + +base64-sol@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/base64-sol/-/base64-sol-1.0.1.tgz#91317aa341f0bc763811783c5729f1c2574600f6" + integrity sha512-ld3cCNMeXt4uJXmLZBHFGMvVpK9KsLVEhPpFRXnvSVAqABKbuNZg/+dsq3NuM+wxFLb/UrVkz7m1ciWmkMfTbg== + +bcrypt-pbkdf@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" + integrity sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w== + dependencies: + tweetnacl "^0.14.3" + +bech32@1.1.4, bech32@^1.1.3: + version "1.1.4" + resolved "https://registry.yarnpkg.com/bech32/-/bech32-1.1.4.tgz#e38c9f37bf179b8eb16ae3a772b40c356d4832e9" + integrity sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ== + +big-integer@1.6.36: + version "1.6.36" + resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.36.tgz#78631076265d4ae3555c04f85e7d9d2f3a071a36" + integrity sha512-t70bfa7HYEA1D9idDbmuv7YbsbVkQ+Hp+8KFSul4aE5e/i1bjCNIRYJZlA8Q8p0r9T8cF/RVvwUgRA//FydEyg== + +big.js@^5.2.2: + version "5.2.2" + resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" + integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== + +big.js@^6.0.3: + version "6.2.1" + resolved "https://registry.yarnpkg.com/big.js/-/big.js-6.2.1.tgz#7205ce763efb17c2e41f26f121c420c6a7c2744f" + integrity sha512-bCtHMwL9LeDIozFn+oNhhFoq+yQ3BNdnsLSASUxLciOb1vgvpHsIO1dsENiGMgbb4SkP5TrzWzRiLddn8ahVOQ== + +bigint-crypto-utils@^3.0.23: + version "3.3.0" + resolved "https://registry.yarnpkg.com/bigint-crypto-utils/-/bigint-crypto-utils-3.3.0.tgz#72ad00ae91062cf07f2b1def9594006c279c1d77" + integrity sha512-jOTSb+drvEDxEq6OuUybOAv/xxoh3cuYRUIPyu8sSHQNKM303UQ2R1DAo45o1AkcIXw6fzbaFI1+xGGdaXs2lg== + +bignumber.js@*, bignumber.js@^9.0.0, bignumber.js@^9.0.1, bignumber.js@^9.1.2: + version "9.1.2" + resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.1.2.tgz#b7c4242259c008903b13707983b5f4bbd31eda0c" + integrity sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug== + +bignumber.js@^7.2.1: + version "7.2.1" + resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-7.2.1.tgz#80c048759d826800807c4bfd521e50edbba57a5f" + integrity sha512-S4XzBk5sMB+Rcb/LNcpzXr57VRTxgAvaAEDAl1AwRx27j00hT84O6OkteE7u8UB3NuaaygCRrEpqox4uDOrbdQ== + +binary-extensions@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" + integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== + +bip39@3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/bip39/-/bip39-3.0.4.tgz#5b11fed966840b5e1b8539f0f54ab6392969b2a0" + integrity sha512-YZKQlb752TrUWqHWj7XAwCSjYEgGAk+/Aas3V7NyjQeZYsztO8JnQUaCWhcnL4T+jL8nvB8typ2jRPzTlgugNw== + dependencies: + "@types/node" "11.11.6" + create-hash "^1.1.0" + pbkdf2 "^3.0.9" + randombytes "^2.0.1" + +blakejs@^1.1.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/blakejs/-/blakejs-1.2.1.tgz#5057e4206eadb4a97f7c0b6e197a505042fc3814" + integrity sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ== + +bluebird@^3.4.7, bluebird@^3.5.0, bluebird@^3.5.2: + version "3.7.2" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" + integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== + +bn.js@4.11.6: + version "4.11.6" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.6.tgz#53344adb14617a13f6e8dd2ce28905d1c0ba3215" + integrity sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA== + +bn.js@^4.0.0, bn.js@^4.11.0, bn.js@^4.11.1, bn.js@^4.11.6, bn.js@^4.11.8, bn.js@^4.11.9: + version "4.12.0" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" + integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== + +bn.js@^5.1.2, bn.js@^5.1.3, bn.js@^5.2.0, bn.js@^5.2.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70" + integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ== + +body-parser@1.20.1: + version "1.20.1" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.1.tgz#b1812a8912c195cd371a3ee5e66faa2338a5c668" + integrity sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw== + dependencies: + bytes "3.1.2" + content-type "~1.0.4" + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + http-errors "2.0.0" + iconv-lite "0.4.24" + on-finished "2.4.1" + qs "6.11.0" + raw-body "2.5.1" + type-is "~1.6.18" + unpipe "1.0.0" + +body-parser@^1.16.0: + version "1.20.2" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.2.tgz#6feb0e21c4724d06de7ff38da36dad4f57a747fd" + integrity sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA== + dependencies: + bytes "3.1.2" + content-type "~1.0.5" + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + http-errors "2.0.0" + iconv-lite "0.4.24" + on-finished "2.4.1" + qs "6.11.0" + raw-body "2.5.2" + type-is "~1.6.18" + unpipe "1.0.0" + +boolbase@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" + integrity sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww== + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +brace-expansion@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" + integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== + dependencies: + balanced-match "^1.0.0" + +braces@^3.0.2, braces@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +brorand@^1.0.1, brorand@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" + integrity sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w== + +browser-level@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/browser-level/-/browser-level-1.0.1.tgz#36e8c3183d0fe1c405239792faaab5f315871011" + integrity sha512-XECYKJ+Dbzw0lbydyQuJzwNXtOpbMSq737qxJN11sIRTErOMShvDpbzTlgju7orJKvx4epULolZAuJGLzCmWRQ== + dependencies: + abstract-level "^1.0.2" + catering "^2.1.1" + module-error "^1.0.2" + run-parallel-limit "^1.1.0" + +browser-stdout@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" + integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== + +browserify-aes@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" + integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA== + dependencies: + buffer-xor "^1.0.3" + cipher-base "^1.0.0" + create-hash "^1.1.0" + evp_bytestokey "^1.0.3" + inherits "^2.0.1" + safe-buffer "^5.0.1" + +bs58@^4.0.0, bs58@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a" + integrity sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw== + dependencies: + base-x "^3.0.2" + +bs58check@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/bs58check/-/bs58check-2.1.2.tgz#53b018291228d82a5aa08e7d796fdafda54aebfc" + integrity sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA== + dependencies: + bs58 "^4.0.0" + create-hash "^1.1.0" + safe-buffer "^5.1.2" + +buffer-from@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== + +buffer-to-arraybuffer@^0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/buffer-to-arraybuffer/-/buffer-to-arraybuffer-0.0.5.tgz#6064a40fa76eb43c723aba9ef8f6e1216d10511a" + integrity sha512-3dthu5CYiVB1DEJp61FtApNnNndTckcqe4pFcLdvHtrpG+kcyekCJKg4MRiDcFW7A6AODnXB9U4dwQiCW5kzJQ== + +buffer-xor@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" + integrity sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ== + +buffer-xor@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-2.0.2.tgz#34f7c64f04c777a1f8aac5e661273bb9dd320289" + integrity sha512-eHslX0bin3GB+Lx2p7lEYRShRewuNZL3fUl4qlVJGGiwoPGftmt8JQgk2Y9Ji5/01TnVDo33E5b5O3vUB1HdqQ== + dependencies: + safe-buffer "^5.1.1" + +buffer@6.0.3, buffer@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" + integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.2.1" + +buffer@^5.0.5, buffer@^5.5.0, buffer@^5.6.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" + integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.1.13" + +bufferutil@4.0.5: + version "4.0.5" + resolved "https://registry.yarnpkg.com/bufferutil/-/bufferutil-4.0.5.tgz#da9ea8166911cc276bf677b8aed2d02d31f59028" + integrity sha512-HTm14iMQKK2FjFLRTM5lAVcyaUzOnqbPtesFIvREgXpJHdQm8bWS+GkQgIkfaBYRHuCnea7w8UVNfwiAQhlr9A== + dependencies: + node-gyp-build "^4.3.0" + +bufferutil@^4.0.1: + version "4.0.8" + resolved "https://registry.yarnpkg.com/bufferutil/-/bufferutil-4.0.8.tgz#1de6a71092d65d7766c4d8a522b261a6e787e8ea" + integrity sha512-4T53u4PdgsXqKaIctwF8ifXlRTTmEPJ8iEPWFdGZvcf7sbwYo6FKFEX9eNNAnzFZ7EzJAQ3CJeOtCRA4rDp7Pw== + dependencies: + node-gyp-build "^4.3.0" + +bytes@3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" + integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== + +cacheable-lookup@^5.0.3: + version "5.0.4" + resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz#5a6b865b2c44357be3d5ebc2a467b032719a7005" + integrity sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA== + +cacheable-lookup@^6.0.4: + version "6.1.0" + resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-6.1.0.tgz#0330a543471c61faa4e9035db583aad753b36385" + integrity sha512-KJ/Dmo1lDDhmW2XDPMo+9oiy/CeqosPguPCrgcVzKyZrL6pM1gU2GmPY/xo6OQPTUaA/c0kwHuywB4E6nmT9ww== + +cacheable-request@^7.0.2: + version "7.0.4" + resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-7.0.4.tgz#7a33ebf08613178b403635be7b899d3e69bbe817" + integrity sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg== + dependencies: + clone-response "^1.0.2" + get-stream "^5.1.0" + http-cache-semantics "^4.0.0" + keyv "^4.0.0" + lowercase-keys "^2.0.0" + normalize-url "^6.0.1" + responselike "^2.0.0" + +call-bind@^1.0.0, call-bind@^1.0.2, call-bind@^1.0.4, call-bind@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.5.tgz#6fa2b7845ce0ea49bf4d8b9ef64727a2c2e2e513" + integrity sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ== + dependencies: + function-bind "^1.1.2" + get-intrinsic "^1.2.1" + set-function-length "^1.1.1" + +callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + +camel-case@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-3.0.0.tgz#ca3c3688a4e9cf3a4cda777dc4dcbc713249cf73" + integrity sha512-+MbKztAYHXPr1jNTSKQF52VpcFjwY5RkR7fxksV8Doo4KAYc5Fl4UJRgthBbTmEx8C54DqahhbLJkDwjI3PI/w== + dependencies: + no-case "^2.2.0" + upper-case "^1.1.1" + +camelcase@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a" + integrity sha512-4nhGqUkc4BqbBBB4Q6zLuD7lzzrHYrjKGeYaEji/3tFR5VdJu9v+LilhGIVe8wxEJPPOeWo7eg8dwY13TZ1BNg== + +camelcase@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" + integrity sha512-FxAv7HpHrXbh3aPo4o2qxHay2lkLY3x5Mw3KeE4KQE8ysVfziWeRZDwcjauvwBSGEC/nXUPzZy8zeh4HokqOnw== + +camelcase@^6.0.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" + integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== + +case@^1.6.3: + version "1.6.3" + resolved "https://registry.yarnpkg.com/case/-/case-1.6.3.tgz#0a4386e3e9825351ca2e6216c60467ff5f1ea1c9" + integrity sha512-mzDSXIPaFwVDvZAHqZ9VlbyF4yyXRuX6IvB06WvPYkqJVO24kX1PPhv9bfpKNFZyxYFmmgo03HUiD8iklmJYRQ== + +caseless@^0.12.0, caseless@~0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + integrity sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw== + +catering@^2.0.0, catering@^2.1.0, catering@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/catering/-/catering-2.1.1.tgz#66acba06ed5ee28d5286133982a927de9a04b510" + integrity sha512-K7Qy8O9p76sL3/3m7/zLKbRkyOlSZAgzEaLhyj2mXS8PsCud2Eo4hAb8aLtZqHh0QGqLcb9dlJSu6lHRVENm1w== + +cbor@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/cbor/-/cbor-5.2.0.tgz#4cca67783ccd6de7b50ab4ed62636712f287a67c" + integrity sha512-5IMhi9e1QU76ppa5/ajP1BmMWZ2FHkhAhjeVKQ/EFCgYSEaeVaoGtL7cxJskf9oCCk+XjzaIdc3IuU/dbA/o2A== + dependencies: + bignumber.js "^9.0.1" + nofilter "^1.0.4" + +cbor@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/cbor/-/cbor-8.1.0.tgz#cfc56437e770b73417a2ecbfc9caf6b771af60d5" + integrity sha512-DwGjNW9omn6EwP70aXsn7FQJx5kO12tX0bZkaTjzdVFM6/7nhA4t0EENocKGx6D2Bch9PE2KzCUf5SceBdeijg== + dependencies: + nofilter "^3.1.0" + +chai-as-promised@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/chai-as-promised/-/chai-as-promised-7.1.1.tgz#08645d825deb8696ee61725dbf590c012eb00ca0" + integrity sha512-azL6xMoi+uxu6z4rhWQ1jbdUhOMhis2PvscD/xjLqNMkv3BPPp2JyyuTHOrf9BOosGpNQ11v6BKv/g57RXbiaA== + dependencies: + check-error "^1.0.2" + +chai-string@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/chai-string/-/chai-string-1.5.0.tgz#0bdb2d8a5f1dbe90bc78ec493c1c1c180dd4d3d2" + integrity sha512-sydDC3S3pNAQMYwJrs6dQX0oBQ6KfIPuOZ78n7rocW0eJJlsHPh2t3kwW7xfwYA/1Bf6/arGtSUo16rxR2JFlw== + +chai@^4.2.0, chai@^4.3.6: + version "4.3.10" + resolved "https://registry.yarnpkg.com/chai/-/chai-4.3.10.tgz#d784cec635e3b7e2ffb66446a63b4e33bd390384" + integrity sha512-0UXG04VuVbruMUYbJ6JctvH0YnC/4q3/AkT18q4NaITo91CUm0liMS9VqzT9vZhVQ/1eqPanMWjBM+Juhfb/9g== + dependencies: + assertion-error "^1.1.0" + check-error "^1.0.3" + deep-eql "^4.1.3" + get-func-name "^2.0.2" + loupe "^2.3.6" + pathval "^1.1.1" + type-detect "^4.0.8" + +chalk@^2.3.2, chalk@^2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +change-case@3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/change-case/-/change-case-3.0.2.tgz#fd48746cce02f03f0a672577d1d3a8dc2eceb037" + integrity sha512-Mww+SLF6MZ0U6kdg11algyKd5BARbyM4TbFBepwowYSR5ClfQGCGtxNXgykpN0uF/bstWeaGDT4JWaDh8zWAHA== + dependencies: + camel-case "^3.0.0" + constant-case "^2.0.0" + dot-case "^2.1.0" + header-case "^1.0.0" + is-lower-case "^1.1.0" + is-upper-case "^1.1.0" + lower-case "^1.1.1" + lower-case-first "^1.0.0" + no-case "^2.3.2" + param-case "^2.1.0" + pascal-case "^2.0.0" + path-case "^2.1.0" + sentence-case "^2.1.0" + snake-case "^2.1.0" + swap-case "^1.1.0" + title-case "^2.1.0" + upper-case "^1.1.1" + upper-case-first "^1.1.0" + +"charenc@>= 0.0.1": + version "0.0.2" + resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667" + integrity sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA== + +check-error@^1.0.2, check-error@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.3.tgz#a6502e4312a7ee969f646e83bb3ddd56281bd694" + integrity sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg== + dependencies: + get-func-name "^2.0.2" + +cheerio-select@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cheerio-select/-/cheerio-select-2.1.0.tgz#4d8673286b8126ca2a8e42740d5e3c4884ae21b4" + integrity sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g== + dependencies: + boolbase "^1.0.0" + css-select "^5.1.0" + css-what "^6.1.0" + domelementtype "^2.3.0" + domhandler "^5.0.3" + domutils "^3.0.1" + +cheerio@^1.0.0-rc.2: + version "1.0.0-rc.12" + resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-1.0.0-rc.12.tgz#788bf7466506b1c6bf5fae51d24a2c4d62e47683" + integrity sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q== + dependencies: + cheerio-select "^2.1.0" + dom-serializer "^2.0.0" + domhandler "^5.0.3" + domutils "^3.0.1" + htmlparser2 "^8.0.1" + parse5 "^7.0.0" + parse5-htmlparser2-tree-adapter "^7.0.0" + +chokidar@3.5.3, chokidar@^3.4.0, chokidar@^3.5.2, chokidar@^3.5.3: + version "3.5.3" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" + integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + +chownr@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" + integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== + +ci-info@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" + integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== + +cids@^0.7.1: + version "0.7.5" + resolved "https://registry.yarnpkg.com/cids/-/cids-0.7.5.tgz#60a08138a99bfb69b6be4ceb63bfef7a396b28b2" + integrity sha512-zT7mPeghoWAu+ppn8+BS1tQ5qGmbMfB4AregnQjA/qHY3GC1m1ptI9GkWNlgeu38r7CuRdXB47uY2XgAYt6QVA== + dependencies: + buffer "^5.5.0" + class-is "^1.1.0" + multibase "~0.6.0" + multicodec "^1.0.0" + multihashes "~0.4.15" + +cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" + integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +class-is@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/class-is/-/class-is-1.1.0.tgz#9d3c0fba0440d211d843cec3dedfa48055005825" + integrity sha512-rhjH9AG1fvabIDoGRVH587413LPjTZgmDF9fOFCbFJQV4yuocX1mHxxvXI4g3cGwbVY9wAYIoKlg1N79frJKQw== + +classic-level@^1.2.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/classic-level/-/classic-level-1.3.0.tgz#5e36680e01dc6b271775c093f2150844c5edd5c8" + integrity sha512-iwFAJQYtqRTRM0F6L8h4JCt00ZSGdOyqh7yVrhhjrOpFhmBjNlRUey64MCiyo6UmQHMJ+No3c81nujPv+n9yrg== + dependencies: + abstract-level "^1.0.2" + catering "^2.1.0" + module-error "^1.0.1" + napi-macros "^2.2.2" + node-gyp-build "^4.3.0" + +clean-stack@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" + integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== + +cli-table3@^0.5.0: + version "0.5.1" + resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.5.1.tgz#0252372d94dfc40dbd8df06005f48f31f656f202" + integrity sha512-7Qg2Jrep1S/+Q3EceiZtQcDPWxhAvBw+ERf1162v4sikJrvojMHFqXt8QIVha8UlH9rgU0BeWPytZ9/TzYqlUw== + dependencies: + object-assign "^4.1.0" + string-width "^2.1.1" + optionalDependencies: + colors "^1.1.2" + +cliui@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" + integrity sha512-0yayqDxWQbqk3ojkYqUKqaAQ6AfNKeKWRNA8kR0WXzAsdHpP4BIaOmMAG87JGuO6qcobyW4GjxHd9PmhEd+T9w== + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + wrap-ansi "^2.0.0" + +cliui@^7.0.2: + version "7.0.4" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" + integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^7.0.0" + +clone-response@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.3.tgz#af2032aa47816399cf5f0a1d0db902f517abb8c3" + integrity sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA== + dependencies: + mimic-response "^1.0.0" + +code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + integrity sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA== + +color-convert@^1.9.0: + version "1.9.3" + 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== + +colors@1.4.0, colors@^1.1.2: + version "1.4.0" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" + integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== + +combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6: + version "1.0.8" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + +command-exists@^1.2.8: + version "1.2.9" + resolved "https://registry.yarnpkg.com/command-exists/-/command-exists-1.2.9.tgz#c50725af3808c8ab0260fd60b01fbfa25b954f69" + integrity sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w== + +command-line-args@^5.1.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/command-line-args/-/command-line-args-5.2.1.tgz#c44c32e437a57d7c51157696893c5909e9cec42e" + integrity sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg== + dependencies: + array-back "^3.1.0" + find-replace "^3.0.0" + lodash.camelcase "^4.3.0" + typical "^4.0.0" + +command-line-usage@^6.1.0: + version "6.1.3" + resolved "https://registry.yarnpkg.com/command-line-usage/-/command-line-usage-6.1.3.tgz#428fa5acde6a838779dfa30e44686f4b6761d957" + integrity sha512-sH5ZSPr+7UStsloltmDh7Ce5fb8XPlHyoPzTpyyMuYCtervL65+ubVZ6Q61cFtFl62UyJlc8/JwERRbAFPUqgw== + dependencies: + array-back "^4.0.2" + chalk "^2.4.2" + table-layout "^1.0.2" + typical "^5.2.0" + +commander@3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/commander/-/commander-3.0.2.tgz#6837c3fb677ad9933d1cfba42dd14d5117d6b39e" + integrity sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow== + +commander@^10.0.0: + version "10.0.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-10.0.1.tgz#881ee46b4f77d1c1dccc5823433aa39b022cbe06" + integrity sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug== + +commander@^8.1.0: + version "8.3.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66" + integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww== + +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== + +concat-stream@^1.6.0, concat-stream@^1.6.2: + version "1.6.2" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" + integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== + dependencies: + buffer-from "^1.0.0" + inherits "^2.0.3" + readable-stream "^2.2.2" + typedarray "^0.0.6" + +constant-case@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/constant-case/-/constant-case-2.0.0.tgz#4175764d389d3fa9c8ecd29186ed6005243b6a46" + integrity sha512-eS0N9WwmjTqrOmR3o83F5vW8Z+9R1HnVz3xmzT2PMFug9ly+Au/fxRWlEBSb6LcZwspSsEn9Xs1uw9YgzAg1EQ== + dependencies: + snake-case "^2.1.0" + upper-case "^1.1.1" + +content-disposition@0.5.4: + version "0.5.4" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" + integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== + dependencies: + safe-buffer "5.2.1" + +content-hash@^2.5.2: + version "2.5.2" + resolved "https://registry.yarnpkg.com/content-hash/-/content-hash-2.5.2.tgz#bbc2655e7c21f14fd3bfc7b7d4bfe6e454c9e211" + integrity sha512-FvIQKy0S1JaWV10sMsA7TRx8bpU+pqPkhbsfvOJAdjRXvYxEckAwQWGwtRjiaJfh+E0DvcWUGqcdjwMGFjsSdw== + dependencies: + cids "^0.7.1" + multicodec "^0.5.5" + multihashes "^0.4.15" + +content-type@~1.0.4, content-type@~1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918" + integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== + +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== + +cookie@0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" + integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== + +cookie@^0.4.1: + version "0.4.2" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432" + integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA== + +core-js-pure@^3.0.1: + version "3.33.2" + resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.33.2.tgz#644830db2507ef84d068a70980ccd99c275f5fa6" + integrity sha512-a8zeCdyVk7uF2elKIGz67AjcXOxjRbwOLz8SbklEso1V+2DoW4OkAMZN9S9GBgvZIaqQi/OemFX4OiSoQEmg1Q== + +core-util-is@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + integrity sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ== + +core-util-is@~1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" + integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== + +cors@^2.8.1: + version "2.8.5" + resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29" + integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g== + dependencies: + object-assign "^4" + vary "^1" + +cosmiconfig@^8.0.0: + version "8.3.6" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-8.3.6.tgz#060a2b871d66dba6c8538ea1118ba1ac16f5fae3" + integrity sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA== + dependencies: + import-fresh "^3.3.0" + js-yaml "^4.1.0" + parse-json "^5.2.0" + path-type "^4.0.0" + +crc-32@^1.2.0: + version "1.2.2" + resolved "https://registry.yarnpkg.com/crc-32/-/crc-32-1.2.2.tgz#3cad35a934b8bf71f25ca524b6da51fb7eace2ff" + integrity sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ== + +create-hash@^1.1.0, create-hash@^1.1.2, create-hash@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" + integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== + dependencies: + cipher-base "^1.0.1" + inherits "^2.0.1" + md5.js "^1.3.4" + ripemd160 "^2.0.1" + sha.js "^2.4.0" + +create-hmac@^1.1.4, create-hmac@^1.1.7: + version "1.1.7" + resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" + integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== + dependencies: + cipher-base "^1.0.3" + create-hash "^1.1.0" + inherits "^2.0.1" + ripemd160 "^2.0.0" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +create-require@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" + integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== + +cross-fetch@^3.1.4: + version "3.1.8" + resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.8.tgz#0327eba65fd68a7d119f8fb2bf9334a1a7956f82" + integrity sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg== + dependencies: + node-fetch "^2.6.12" + +cross-fetch@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-4.0.0.tgz#f037aef1580bb3a1a35164ea2a848ba81b445983" + integrity sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g== + dependencies: + node-fetch "^2.6.12" + +cross-spawn@^7.0.2: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +"crypt@>= 0.0.1": + version "0.0.2" + resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b" + integrity sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow== + +crypto-addr-codec@^0.1.7: + version "0.1.8" + resolved "https://registry.yarnpkg.com/crypto-addr-codec/-/crypto-addr-codec-0.1.8.tgz#45c4b24e2ebce8e24a54536ee0ca25b65787b016" + integrity sha512-GqAK90iLLgP3FvhNmHbpT3wR6dEdaM8hZyZtLX29SPardh3OA13RFLHDR6sntGCgRWOfiHqW6sIyohpNqOtV/g== + dependencies: + base-x "^3.0.8" + big-integer "1.6.36" + blakejs "^1.1.0" + bs58 "^4.0.1" + ripemd160-min "0.0.6" + safe-buffer "^5.2.0" + sha3 "^2.1.1" + +css-select@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-5.1.0.tgz#b8ebd6554c3637ccc76688804ad3f6a6fdaea8a6" + integrity sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg== + dependencies: + boolbase "^1.0.0" + css-what "^6.1.0" + domhandler "^5.0.2" + domutils "^3.0.1" + nth-check "^2.0.1" + +css-what@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-6.1.0.tgz#fb5effcf76f1ddea2c81bdfaa4de44e79bac70f4" + integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw== + +d@1, d@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a" + integrity sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA== + dependencies: + es5-ext "^0.10.50" + type "^1.0.1" + +dashdash@^1.12.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + integrity sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g== + dependencies: + assert-plus "^1.0.0" + +death@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/death/-/death-1.1.0.tgz#01aa9c401edd92750514470b8266390c66c67318" + integrity sha512-vsV6S4KVHvTGxbEcij7hkWRv0It+sGGWVOM67dQde/o5Xjnr+KmLjxWJii2uEObIrt1CcM9w0Yaovx+iOlIL+w== + +debug@2.6.9, debug@^2.2.0: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@4, debug@4.3.4, debug@^4.0.1, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.3, debug@^4.3.4: + version "4.3.4" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + +debug@^3.1.0, debug@^3.2.7: + version "3.2.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" + integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== + dependencies: + ms "^2.1.1" + +decamelize@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + integrity sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA== + +decamelize@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" + integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== + +decimal.js-light@^2.5.0: + version "2.5.1" + resolved "https://registry.yarnpkg.com/decimal.js-light/-/decimal.js-light-2.5.1.tgz#134fd32508f19e208f4fb2f8dac0d2626a867934" + integrity sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg== + +decode-uri-component@^0.2.0: + version "0.2.2" + resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.2.tgz#e69dbe25d37941171dd540e024c444cd5188e1e9" + integrity sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ== + +decompress-response@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" + integrity sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA== + dependencies: + mimic-response "^1.0.0" + +decompress-response@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc" + integrity sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ== + dependencies: + mimic-response "^3.1.0" + +deep-eql@^4.1.3: + version "4.1.3" + resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-4.1.3.tgz#7c7775513092f7df98d8df9996dd085eb668cc6d" + integrity sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw== + dependencies: + type-detect "^4.0.0" + +deep-extend@~0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== + +deep-is@^0.1.3, deep-is@~0.1.3: + version "0.1.4" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" + integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== + +defer-to-connect@^2.0.0, defer-to-connect@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-2.0.1.tgz#8016bdb4143e4632b77a3449c6236277de520587" + integrity sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg== + +deferred-leveldown@~5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/deferred-leveldown/-/deferred-leveldown-5.3.0.tgz#27a997ad95408b61161aa69bd489b86c71b78058" + integrity sha512-a59VOT+oDy7vtAbLRCZwWgxu2BaCfd5Hk7wxJd48ei7I+nsg8Orlb9CLG0PMZienk9BSUKgeAqkO2+Lw+1+Ukw== + dependencies: + abstract-leveldown "~6.2.1" + inherits "^2.0.3" + +define-data-property@^1.0.1, define-data-property@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.1.tgz#c35f7cd0ab09883480d12ac5cb213715587800b3" + integrity sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ== + dependencies: + get-intrinsic "^1.2.1" + gopd "^1.0.1" + has-property-descriptors "^1.0.0" + +define-properties@^1.1.3, define-properties@^1.1.4, define-properties@^1.2.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.1.tgz#10781cc616eb951a80a034bafcaa7377f6af2b6c" + integrity sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg== + dependencies: + define-data-property "^1.0.1" + has-property-descriptors "^1.0.0" + object-keys "^1.1.1" + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== + +depd@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" + integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== + +destroy@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" + integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== + +detect-indent@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-5.0.0.tgz#3871cc0a6a002e8c3e5b3cf7f336264675f06b9d" + integrity sha512-rlpvsxUtM0PQvy9iZe640/IWwWYyBsTApREbA1pHOpmOUIl9MkP/U4z7vTtg4Oaojvqhxt7sdufnT0EzGaR31g== + +detect-port@^1.3.0: + version "1.5.1" + resolved "https://registry.yarnpkg.com/detect-port/-/detect-port-1.5.1.tgz#451ca9b6eaf20451acb0799b8ab40dff7718727b" + integrity sha512-aBzdj76lueB6uUst5iAs7+0H/oOjqI5D16XUWxlWMIMROhcM0rfsNVk93zTngq1dDNpoXRr++Sus7ETAExppAQ== + dependencies: + address "^1.0.1" + debug "4" + +diff@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" + integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== + +diff@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" + integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== + +difflib@^0.2.4: + version "0.2.4" + resolved "https://registry.yarnpkg.com/difflib/-/difflib-0.2.4.tgz#b5e30361a6db023176d562892db85940a718f47e" + integrity sha512-9YVwmMb0wQHQNr5J9m6BSj6fk4pfGITGQOOs+D9Fl+INODWFOfvhIU1hNv6GgR1RBoC/9NJcwu77zShxV0kT7w== + dependencies: + heap ">= 0.2.0" + +dir-glob@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" + integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== + dependencies: + path-type "^4.0.0" + +doctrine@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" + integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw== + dependencies: + esutils "^2.0.2" + +doctrine@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" + integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== + dependencies: + esutils "^2.0.2" + +dom-serializer@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-2.0.0.tgz#e41b802e1eedf9f6cae183ce5e622d789d7d8e53" + integrity sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg== + dependencies: + domelementtype "^2.3.0" + domhandler "^5.0.2" + entities "^4.2.0" + +dom-walk@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.2.tgz#0c548bef048f4d1f2a97249002236060daa3fd84" + integrity sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w== + +domelementtype@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d" + integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw== + +domhandler@^5.0.2, domhandler@^5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-5.0.3.tgz#cc385f7f751f1d1fc650c21374804254538c7d31" + integrity sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w== + dependencies: + domelementtype "^2.3.0" + +domutils@^3.0.1: + version "3.1.0" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-3.1.0.tgz#c47f551278d3dc4b0b1ab8cbb42d751a6f0d824e" + integrity sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA== + dependencies: + dom-serializer "^2.0.0" + domelementtype "^2.3.0" + domhandler "^5.0.3" + +dot-case@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/dot-case/-/dot-case-2.1.1.tgz#34dcf37f50a8e93c2b3bca8bb7fb9155c7da3bee" + integrity sha512-HnM6ZlFqcajLsyudHq7LeeLDr2rFAVYtDv/hV5qchQEidSck8j9OPUsXY9KwJv/lHMtYlX4DjRQqwFYa+0r8Ug== + dependencies: + no-case "^2.2.0" + +dotenv@^14.2.0: + version "14.3.2" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-14.3.2.tgz#7c30b3a5f777c79a3429cb2db358eef6751e8369" + integrity sha512-vwEppIphpFdvaMCaHfCEv9IgwcxMljMw2TnAQBB4VWPvzXQLTb82jwmdOKzlEVUL3gNFT4l4TPKO+Bn+sqcrVQ== + +dotenv@^16.0.1: + version "16.3.1" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.3.1.tgz#369034de7d7e5b120972693352a3bf112172cc3e" + integrity sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ== + +ecc-jsbn@~0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" + integrity sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw== + dependencies: + jsbn "~0.1.0" + safer-buffer "^2.1.0" + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== + +elliptic@6.5.4, elliptic@^6.4.0, elliptic@^6.5.2, elliptic@^6.5.4: + version "6.5.4" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb" + integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ== + dependencies: + bn.js "^4.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" + +emittery@0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.10.0.tgz#bb373c660a9d421bb44706ec4967ed50c02a8026" + integrity sha512-AGvFfs+d0JKCJQ4o01ASQLGPmSCxgfU9RFXvzPvZdjKK8oscynksuJhWrSTSw7j7Ep/sZct5b5ZhYCi8S/t0HQ== + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +encode-utf8@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/encode-utf8/-/encode-utf8-1.0.3.tgz#f30fdd31da07fb596f281beb2f6b027851994cda" + integrity sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw== + +encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== + +encoding-down@^6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/encoding-down/-/encoding-down-6.3.0.tgz#b1c4eb0e1728c146ecaef8e32963c549e76d082b" + integrity sha512-QKrV0iKR6MZVJV08QY0wp1e7vF6QbhnbQhb07bwpEyuz4uZiZgPlEGdkCROuFkUwdxlFaiPIhjyarH1ee/3vhw== + dependencies: + abstract-leveldown "^6.2.1" + inherits "^2.0.3" + level-codec "^9.0.0" + level-errors "^2.0.0" + +end-of-stream@^1.1.0: + version "1.4.4" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" + integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== + dependencies: + once "^1.4.0" + +enquirer@^2.3.0, enquirer@^2.3.5, enquirer@^2.3.6: + version "2.4.1" + resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.4.1.tgz#93334b3fbd74fc7097b224ab4a8fb7e40bf4ae56" + integrity sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ== + dependencies: + ansi-colors "^4.1.1" + strip-ansi "^6.0.1" + +entities@^4.2.0, entities@^4.4.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48" + integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw== + +env-paths@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2" + integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A== + +errno@~0.1.1: + version "0.1.8" + resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.8.tgz#8bb3e9c7d463be4976ff888f76b4809ebc2e811f" + integrity sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A== + dependencies: + prr "~1.0.1" + +error-ex@^1.2.0, error-ex@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + +es-abstract@^1.22.1: + version "1.22.3" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.22.3.tgz#48e79f5573198de6dee3589195727f4f74bc4f32" + integrity sha512-eiiY8HQeYfYH2Con2berK+To6GrK2RxbPawDkGq4UiCQQfZHb6wX9qQqkbpPqaxQFcl8d9QzZqo0tGE0VcrdwA== + dependencies: + array-buffer-byte-length "^1.0.0" + arraybuffer.prototype.slice "^1.0.2" + available-typed-arrays "^1.0.5" + call-bind "^1.0.5" + es-set-tostringtag "^2.0.1" + es-to-primitive "^1.2.1" + function.prototype.name "^1.1.6" + get-intrinsic "^1.2.2" + get-symbol-description "^1.0.0" + globalthis "^1.0.3" + gopd "^1.0.1" + has-property-descriptors "^1.0.0" + has-proto "^1.0.1" + has-symbols "^1.0.3" + hasown "^2.0.0" + internal-slot "^1.0.5" + is-array-buffer "^3.0.2" + is-callable "^1.2.7" + is-negative-zero "^2.0.2" + is-regex "^1.1.4" + is-shared-array-buffer "^1.0.2" + is-string "^1.0.7" + is-typed-array "^1.1.12" + is-weakref "^1.0.2" + object-inspect "^1.13.1" + object-keys "^1.1.1" + object.assign "^4.1.4" + regexp.prototype.flags "^1.5.1" + safe-array-concat "^1.0.1" + safe-regex-test "^1.0.0" + string.prototype.trim "^1.2.8" + string.prototype.trimend "^1.0.7" + string.prototype.trimstart "^1.0.7" + typed-array-buffer "^1.0.0" + typed-array-byte-length "^1.0.0" + typed-array-byte-offset "^1.0.0" + typed-array-length "^1.0.4" + unbox-primitive "^1.0.2" + which-typed-array "^1.1.13" + +es-set-tostringtag@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/es-set-tostringtag/-/es-set-tostringtag-2.0.2.tgz#11f7cc9f63376930a5f20be4915834f4bc74f9c9" + integrity sha512-BuDyupZt65P9D2D2vA/zqcI3G5xRsklm5N3xCwuiy+/vKy8i0ifdsQP1sLgO4tZDSCaQUSnmC48khknGMV3D2Q== + dependencies: + get-intrinsic "^1.2.2" + has-tostringtag "^1.0.0" + hasown "^2.0.0" + +es-shim-unscopables@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz#1f6942e71ecc7835ed1c8a83006d8771a63a3763" + integrity sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw== + dependencies: + hasown "^2.0.0" + +es-to-primitive@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" + integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== + dependencies: + is-callable "^1.1.4" + is-date-object "^1.0.1" + is-symbol "^1.0.2" + +es5-ext@^0.10.35, es5-ext@^0.10.50: + version "0.10.62" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.62.tgz#5e6adc19a6da524bf3d1e02bbc8960e5eb49a9a5" + integrity sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA== + dependencies: + es6-iterator "^2.0.3" + es6-symbol "^3.1.3" + next-tick "^1.1.0" + +es6-iterator@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" + integrity sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g== + dependencies: + d "1" + es5-ext "^0.10.35" + es6-symbol "^3.1.1" + +es6-promise@^4.2.8: + version "4.2.8" + resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a" + integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w== + +es6-symbol@^3.1.1, es6-symbol@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.3.tgz#bad5d3c1bcdac28269f4cb331e431c78ac705d18" + integrity sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA== + dependencies: + d "^1.0.1" + ext "^1.1.2" + +escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== + +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== + +escape-string-regexp@4.0.0, escape-string-regexp@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + +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== + +escodegen@1.8.x: + version "1.8.1" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.8.1.tgz#5a5b53af4693110bebb0867aa3430dd3b70a1018" + integrity sha512-yhi5S+mNTOuRvyW4gWlg5W1byMaQGWWSYHXsuFZ7GBo7tpyOwi2EdzMP/QWxh9hwkD2m+wDVHJsxhRIj+v/b/A== + dependencies: + esprima "^2.7.1" + estraverse "^1.9.1" + esutils "^2.0.2" + optionator "^0.8.1" + optionalDependencies: + source-map "~0.2.0" + +eslint-config-prettier@^8.5.0: + version "8.10.0" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.10.0.tgz#3a06a662130807e2502fc3ff8b4143d8a0658e11" + integrity sha512-SM8AMJdeQqRYT9O9zguiruQZaN7+z+E4eAP9oiLNGKMtomwaB1E9dcgUD6ZAn/eQAb52USbvezbiljfZUhbJcg== + +eslint-config-standard@^16.0.3: + version "16.0.3" + resolved "https://registry.yarnpkg.com/eslint-config-standard/-/eslint-config-standard-16.0.3.tgz#6c8761e544e96c531ff92642eeb87842b8488516" + integrity sha512-x4fmJL5hGqNJKGHSjnLdgA6U6h1YW/G2dW9fA+cyVur4SK6lyue8+UgNKWlZtUDTXvgKDD/Oa3GQjmB5kjtVvg== + +eslint-import-resolver-node@^0.3.9: + version "0.3.9" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz#d4eaac52b8a2e7c3cd1903eb00f7e053356118ac" + integrity sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g== + dependencies: + debug "^3.2.7" + is-core-module "^2.13.0" + resolve "^1.22.4" + +eslint-module-utils@^2.8.0: + version "2.8.0" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz#e439fee65fc33f6bba630ff621efc38ec0375c49" + integrity sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw== + dependencies: + debug "^3.2.7" + +eslint-plugin-es@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz#75a7cdfdccddc0589934aeeb384175f221c57893" + integrity sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ== + dependencies: + eslint-utils "^2.0.0" + regexpp "^3.0.0" + +eslint-plugin-import@^2.26.0: + version "2.29.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.29.0.tgz#8133232e4329ee344f2f612885ac3073b0b7e155" + integrity sha512-QPOO5NO6Odv5lpoTkddtutccQjysJuFxoPS7fAHO+9m9udNHvTCPSAMW9zGAYj8lAIdr40I8yPCdUYrncXtrwg== + dependencies: + array-includes "^3.1.7" + array.prototype.findlastindex "^1.2.3" + array.prototype.flat "^1.3.2" + array.prototype.flatmap "^1.3.2" + debug "^3.2.7" + doctrine "^2.1.0" + eslint-import-resolver-node "^0.3.9" + eslint-module-utils "^2.8.0" + hasown "^2.0.0" + is-core-module "^2.13.1" + is-glob "^4.0.3" + minimatch "^3.1.2" + object.fromentries "^2.0.7" + object.groupby "^1.0.1" + object.values "^1.1.7" + semver "^6.3.1" + tsconfig-paths "^3.14.2" + +eslint-plugin-node@^11.1.0: + version "11.1.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz#c95544416ee4ada26740a30474eefc5402dc671d" + integrity sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g== + dependencies: + eslint-plugin-es "^3.0.0" + eslint-utils "^2.0.0" + ignore "^5.1.1" + minimatch "^3.0.4" + resolve "^1.10.1" + semver "^6.1.0" + +eslint-plugin-prettier@^3.4.1: + version "3.4.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-3.4.1.tgz#e9ddb200efb6f3d05ffe83b1665a716af4a387e5" + integrity sha512-htg25EUYUeIhKHXjOinK4BgCcDwtLHjqaxCDsMy5nbnUMkKFvIhMVCp+5GFUXQ4Nr8lBsPqtGAqBenbpFqAA2g== + dependencies: + prettier-linter-helpers "^1.0.0" + +eslint-plugin-promise@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-5.2.0.tgz#a596acc32981627eb36d9d75f9666ac1a4564971" + integrity sha512-SftLb1pUG01QYq2A/hGAWfDRXqYD82zE7j7TopDOyNdU+7SvvoXREls/+PRTY17vUXzXnZA/zfnyKgRH6x4JJw== + +eslint-scope@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" + integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== + dependencies: + esrecurse "^4.3.0" + estraverse "^4.1.1" + +eslint-utils@^2.0.0, eslint-utils@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27" + integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg== + dependencies: + eslint-visitor-keys "^1.1.0" + +eslint-utils@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-3.0.0.tgz#8aebaface7345bb33559db0a1f13a1d2d48c3672" + integrity sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA== + dependencies: + eslint-visitor-keys "^2.0.0" + +eslint-visitor-keys@^1.1.0, eslint-visitor-keys@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" + integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== + +eslint-visitor-keys@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303" + integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== + +eslint@^7.32.0: + version "7.32.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.32.0.tgz#c6d328a14be3fb08c8d1d21e12c02fdb7a2a812d" + integrity sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA== + dependencies: + "@babel/code-frame" "7.12.11" + "@eslint/eslintrc" "^0.4.3" + "@humanwhocodes/config-array" "^0.5.0" + ajv "^6.10.0" + chalk "^4.0.0" + cross-spawn "^7.0.2" + debug "^4.0.1" + doctrine "^3.0.0" + enquirer "^2.3.5" + escape-string-regexp "^4.0.0" + eslint-scope "^5.1.1" + eslint-utils "^2.1.0" + eslint-visitor-keys "^2.0.0" + espree "^7.3.1" + esquery "^1.4.0" + esutils "^2.0.2" + fast-deep-equal "^3.1.3" + file-entry-cache "^6.0.1" + functional-red-black-tree "^1.0.1" + glob-parent "^5.1.2" + globals "^13.6.0" + ignore "^4.0.6" + import-fresh "^3.0.0" + imurmurhash "^0.1.4" + is-glob "^4.0.0" + js-yaml "^3.13.1" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.4.1" + lodash.merge "^4.6.2" + minimatch "^3.0.4" + natural-compare "^1.4.0" + optionator "^0.9.1" + progress "^2.0.0" + regexpp "^3.1.0" + semver "^7.2.1" + strip-ansi "^6.0.0" + strip-json-comments "^3.1.0" + table "^6.0.9" + text-table "^0.2.0" + v8-compile-cache "^2.0.3" + +espree@^7.3.0, espree@^7.3.1: + version "7.3.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-7.3.1.tgz#f2df330b752c6f55019f8bd89b7660039c1bbbb6" + integrity sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g== + dependencies: + acorn "^7.4.0" + acorn-jsx "^5.3.1" + eslint-visitor-keys "^1.3.0" + +esprima@2.7.x, esprima@^2.7.1: + version "2.7.3" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581" + integrity sha512-OarPfz0lFCiW4/AV2Oy1Rp9qu0iusTKqykwTspGCZtPxmF81JR4MmIebvF1F9+UOKth2ZubLQ4XGGaU+hSn99A== + +esprima@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + +esquery@^1.4.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.5.0.tgz#6ce17738de8577694edd7361c57182ac8cb0db0b" + integrity sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg== + dependencies: + estraverse "^5.1.0" + +esrecurse@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== + dependencies: + estraverse "^5.2.0" + +estraverse@^1.9.1: + version "1.9.3" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-1.9.3.tgz#af67f2dc922582415950926091a4005d29c9bb44" + integrity sha512-25w1fMXQrGdoquWnScXZGckOv+Wes+JDnuN/+7ex3SauFRS72r2lFDec0EKPt2YD1wUJ/IrfEex+9yp4hfSOJA== + +estraverse@^4.1.1: + version "4.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" + integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== + +estraverse@^5.1.0, estraverse@^5.2.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" + integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== + +esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== + +eth-ens-namehash@2.0.8, eth-ens-namehash@^2.0.0, eth-ens-namehash@^2.0.8: + version "2.0.8" + resolved "https://registry.yarnpkg.com/eth-ens-namehash/-/eth-ens-namehash-2.0.8.tgz#229ac46eca86d52e0c991e7cb2aef83ff0f68bcf" + integrity sha512-VWEI1+KJfz4Km//dadyvBBoBeSQ0MHTXPvr8UIXiLW6IanxvAV+DmlZAijZwAyggqGUfwQBeHf7tc9wzc1piSw== + dependencies: + idna-uts46-hx "^2.3.1" + js-sha3 "^0.5.7" + +eth-gas-reporter@^0.2.25: + version "0.2.27" + resolved "https://registry.yarnpkg.com/eth-gas-reporter/-/eth-gas-reporter-0.2.27.tgz#928de8548a674ed64c7ba0bf5795e63079150d4e" + integrity sha512-femhvoAM7wL0GcI8ozTdxfuBtBFJ9qsyIAsmKVjlWAHUbdnnXHt+lKzz/kmldM5lA9jLuNHGwuIxorNpLbR1Zw== + dependencies: + "@solidity-parser/parser" "^0.14.0" + axios "^1.5.1" + cli-table3 "^0.5.0" + colors "1.4.0" + ethereum-cryptography "^1.0.3" + ethers "^5.7.2" + fs-readdir-recursive "^1.1.0" + lodash "^4.17.14" + markdown-table "^1.1.3" + mocha "^10.2.0" + req-cwd "^2.0.0" + sha1 "^1.1.1" + sync-request "^6.0.0" + +eth-lib@0.2.8: + version "0.2.8" + resolved "https://registry.yarnpkg.com/eth-lib/-/eth-lib-0.2.8.tgz#b194058bef4b220ad12ea497431d6cb6aa0623c8" + integrity sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw== + dependencies: + bn.js "^4.11.6" + elliptic "^6.4.0" + xhr-request-promise "^0.1.2" + +eth-lib@^0.1.26: + version "0.1.29" + resolved "https://registry.yarnpkg.com/eth-lib/-/eth-lib-0.1.29.tgz#0c11f5060d42da9f931eab6199084734f4dbd1d9" + integrity sha512-bfttrr3/7gG4E02HoWTDUcDDslN003OlOoBxk9virpAZQ1ja/jDgwkWB8QfJF7ojuEowrqy+lzp9VcJG7/k5bQ== + dependencies: + bn.js "^4.11.6" + elliptic "^6.4.0" + nano-json-stream-parser "^0.1.2" + servify "^0.1.12" + ws "^3.0.0" + xhr-request-promise "^0.1.2" + +ethereum-bloom-filters@^1.0.6: + version "1.0.10" + resolved "https://registry.yarnpkg.com/ethereum-bloom-filters/-/ethereum-bloom-filters-1.0.10.tgz#3ca07f4aed698e75bd134584850260246a5fed8a" + integrity sha512-rxJ5OFN3RwjQxDcFP2Z5+Q9ho4eIdEmSc2ht0fCu8Se9nbXjZ7/031uXoUYJ87KHCOdVeiUuwSnoS7hmYAGVHA== + dependencies: + js-sha3 "^0.8.0" + +ethereum-cryptography@0.1.3, ethereum-cryptography@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz#8d6143cfc3d74bf79bbd8edecdf29e4ae20dd191" + integrity sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ== + dependencies: + "@types/pbkdf2" "^3.0.0" + "@types/secp256k1" "^4.0.1" + blakejs "^1.1.0" + browserify-aes "^1.2.0" + bs58check "^2.1.2" + create-hash "^1.2.0" + create-hmac "^1.1.7" + hash.js "^1.1.7" + keccak "^3.0.0" + pbkdf2 "^3.0.17" + randombytes "^2.1.0" + safe-buffer "^5.1.2" + scrypt-js "^3.0.0" + secp256k1 "^4.0.1" + setimmediate "^1.0.5" + +ethereum-cryptography@^1.0.3: + version "1.2.0" + resolved "https://registry.yarnpkg.com/ethereum-cryptography/-/ethereum-cryptography-1.2.0.tgz#5ccfa183e85fdaf9f9b299a79430c044268c9b3a" + integrity sha512-6yFQC9b5ug6/17CQpCyE3k9eKBMdhyVjzUy1WkiuY/E4vj/SXDBbCw8QEIaXqf0Mf2SnY6RmpDcwlUmBSS0EJw== + dependencies: + "@noble/hashes" "1.2.0" + "@noble/secp256k1" "1.7.1" + "@scure/bip32" "1.1.5" + "@scure/bip39" "1.1.1" + +ethereum-cryptography@^2.0.0, ethereum-cryptography@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ethereum-cryptography/-/ethereum-cryptography-2.1.2.tgz#18fa7108622e56481157a5cb7c01c0c6a672eb67" + integrity sha512-Z5Ba0T0ImZ8fqXrJbpHcbpAvIswRte2wGNR/KePnu8GbbvgJ47lMxT/ZZPG6i9Jaht4azPDop4HaM00J0J59ug== + dependencies: + "@noble/curves" "1.1.0" + "@noble/hashes" "1.3.1" + "@scure/bip32" "1.3.1" + "@scure/bip39" "1.2.1" + +ethereum-ens@^0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/ethereum-ens/-/ethereum-ens-0.8.0.tgz#6d0f79acaa61fdbc87d2821779c4e550243d4c57" + integrity sha512-a8cBTF4AWw1Q1Y37V1LSCS9pRY4Mh3f8vCg5cbXCCEJ3eno1hbI/+Ccv9SZLISYpqQhaglP3Bxb/34lS4Qf7Bg== + dependencies: + bluebird "^3.4.7" + eth-ens-namehash "^2.0.0" + js-sha3 "^0.5.7" + pako "^1.0.4" + underscore "^1.8.3" + web3 "^1.0.0-beta.34" + +ethereum-waffle@^4.0.10: + version "4.0.10" + resolved "https://registry.yarnpkg.com/ethereum-waffle/-/ethereum-waffle-4.0.10.tgz#f1ef1564c0155236f1a66c6eae362a5d67c9f64c" + integrity sha512-iw9z1otq7qNkGDNcMoeNeLIATF9yKl1M8AIeu42ElfNBplq0e+5PeasQmm8ybY/elkZ1XyRO0JBQxQdVRb8bqQ== + dependencies: + "@ethereum-waffle/chai" "4.0.10" + "@ethereum-waffle/compiler" "4.0.3" + "@ethereum-waffle/mock-contract" "4.0.4" + "@ethereum-waffle/provider" "4.0.5" + solc "0.8.15" + typechain "^8.0.0" + +ethereumjs-abi@0.6.8, ethereumjs-abi@^0.6.8: + version "0.6.8" + resolved "https://registry.yarnpkg.com/ethereumjs-abi/-/ethereumjs-abi-0.6.8.tgz#71bc152db099f70e62f108b7cdfca1b362c6fcae" + integrity sha512-Tx0r/iXI6r+lRsdvkFDlut0N08jWMnKRZ6Gkq+Nmw75lZe4e6o3EkSnkaBP5NF6+m5PTGAr9JP43N3LyeoglsA== + dependencies: + bn.js "^4.11.8" + ethereumjs-util "^6.0.0" + +ethereumjs-util@7.1.3: + version "7.1.3" + resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-7.1.3.tgz#b55d7b64dde3e3e45749e4c41288238edec32d23" + integrity sha512-y+82tEbyASO0K0X1/SRhbJJoAlfcvq8JbrG4a5cjrOks7HS/36efU/0j2flxCPOUM++HFahk33kr/ZxyC4vNuw== + dependencies: + "@types/bn.js" "^5.1.0" + bn.js "^5.1.2" + create-hash "^1.1.2" + ethereum-cryptography "^0.1.3" + rlp "^2.2.4" + +ethereumjs-util@^6.0.0, ethereumjs-util@^6.2.1: + version "6.2.1" + resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz#fcb4e4dd5ceacb9d2305426ab1a5cd93e3163b69" + integrity sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw== + dependencies: + "@types/bn.js" "^4.11.3" + bn.js "^4.11.0" + create-hash "^1.1.2" + elliptic "^6.5.2" + ethereum-cryptography "^0.1.3" + ethjs-util "0.1.6" + rlp "^2.2.3" + +ethereumjs-util@^7.1.0, ethereumjs-util@^7.1.1, ethereumjs-util@^7.1.2, ethereumjs-util@^7.1.3, ethereumjs-util@^7.1.4, ethereumjs-util@^7.1.5: + version "7.1.5" + resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz#9ecf04861e4fbbeed7465ece5f23317ad1129181" + integrity sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg== + dependencies: + "@types/bn.js" "^5.1.0" + bn.js "^5.1.2" + create-hash "^1.1.2" + ethereum-cryptography "^0.1.3" + rlp "^2.2.4" + +ethers@^4.0.0-beta.1, ethers@^4.0.32: + version "4.0.49" + resolved "https://registry.yarnpkg.com/ethers/-/ethers-4.0.49.tgz#0eb0e9161a0c8b4761be547396bbe2fb121a8894" + integrity sha512-kPltTvWiyu+OktYy1IStSO16i2e7cS9D9OxZ81q2UUaiNPVrm/RTcbxamCXF9VUSKzJIdJV68EAIhTEVBalRWg== + dependencies: + aes-js "3.0.0" + bn.js "^4.11.9" + elliptic "6.5.4" + hash.js "1.1.3" + js-sha3 "0.5.7" + scrypt-js "2.0.4" + setimmediate "1.0.4" + uuid "2.0.1" + xmlhttprequest "1.8.0" + +ethers@^5.0.13, ethers@^5.7.0, ethers@^5.7.1, ethers@^5.7.2: + version "5.7.2" + resolved "https://registry.yarnpkg.com/ethers/-/ethers-5.7.2.tgz#3a7deeabbb8c030d4126b24f84e525466145872e" + integrity sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg== + dependencies: + "@ethersproject/abi" "5.7.0" + "@ethersproject/abstract-provider" "5.7.0" + "@ethersproject/abstract-signer" "5.7.0" + "@ethersproject/address" "5.7.0" + "@ethersproject/base64" "5.7.0" + "@ethersproject/basex" "5.7.0" + "@ethersproject/bignumber" "5.7.0" + "@ethersproject/bytes" "5.7.0" + "@ethersproject/constants" "5.7.0" + "@ethersproject/contracts" "5.7.0" + "@ethersproject/hash" "5.7.0" + "@ethersproject/hdnode" "5.7.0" + "@ethersproject/json-wallets" "5.7.0" + "@ethersproject/keccak256" "5.7.0" + "@ethersproject/logger" "5.7.0" + "@ethersproject/networks" "5.7.1" + "@ethersproject/pbkdf2" "5.7.0" + "@ethersproject/properties" "5.7.0" + "@ethersproject/providers" "5.7.2" + "@ethersproject/random" "5.7.0" + "@ethersproject/rlp" "5.7.0" + "@ethersproject/sha2" "5.7.0" + "@ethersproject/signing-key" "5.7.0" + "@ethersproject/solidity" "5.7.0" + "@ethersproject/strings" "5.7.0" + "@ethersproject/transactions" "5.7.0" + "@ethersproject/units" "5.7.0" + "@ethersproject/wallet" "5.7.0" + "@ethersproject/web" "5.7.1" + "@ethersproject/wordlists" "5.7.0" + +ethjs-unit@0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/ethjs-unit/-/ethjs-unit-0.1.6.tgz#c665921e476e87bce2a9d588a6fe0405b2c41699" + integrity sha512-/Sn9Y0oKl0uqQuvgFk/zQgR7aw1g36qX/jzSQ5lSwlO0GigPymk4eGQfeNTD03w1dPOqfz8V77Cy43jH56pagw== + dependencies: + bn.js "4.11.6" + number-to-bn "1.7.0" + +ethjs-util@0.1.6, ethjs-util@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/ethjs-util/-/ethjs-util-0.1.6.tgz#f308b62f185f9fe6237132fb2a9818866a5cd536" + integrity sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w== + dependencies: + is-hex-prefixed "1.0.0" + strip-hex-prefix "1.0.0" + +eventemitter3@4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.4.tgz#b5463ace635a083d018bdc7c917b4c5f10a85384" + integrity sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ== + +evp_bytestokey@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" + integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA== + dependencies: + md5.js "^1.3.4" + safe-buffer "^5.1.1" + +express@^4.14.0: + version "4.18.2" + resolved "https://registry.yarnpkg.com/express/-/express-4.18.2.tgz#3fabe08296e930c796c19e3c516979386ba9fd59" + integrity sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ== + dependencies: + accepts "~1.3.8" + array-flatten "1.1.1" + body-parser "1.20.1" + content-disposition "0.5.4" + content-type "~1.0.4" + cookie "0.5.0" + cookie-signature "1.0.6" + debug "2.6.9" + depd "2.0.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "1.2.0" + fresh "0.5.2" + http-errors "2.0.0" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "2.4.1" + parseurl "~1.3.3" + path-to-regexp "0.1.7" + proxy-addr "~2.0.7" + qs "6.11.0" + range-parser "~1.2.1" + safe-buffer "5.2.1" + send "0.18.0" + serve-static "1.15.0" + setprototypeof "1.2.0" + statuses "2.0.1" + type-is "~1.6.18" + utils-merge "1.0.1" + vary "~1.1.2" + +ext@^1.1.2: + version "1.7.0" + resolved "https://registry.yarnpkg.com/ext/-/ext-1.7.0.tgz#0ea4383c0103d60e70be99e9a7f11027a33c4f5f" + integrity sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw== + dependencies: + type "^2.7.2" + +extend@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== + +extsprintf@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" + integrity sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g== + +extsprintf@^1.2.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.1.tgz#8d172c064867f235c0c84a596806d279bf4bcc07" + integrity sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA== + +fast-check@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/fast-check/-/fast-check-3.1.1.tgz#72c5ae7022a4e86504762e773adfb8a5b0b01252" + integrity sha512-3vtXinVyuUKCKFKYcwXhGE6NtGWkqF8Yh3rvMZNzmwz8EPrgoc/v4pDdLHyLnCyCI5MZpZZkDEwFyXyEONOxpA== + dependencies: + pure-rand "^5.0.1" + +fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + +fast-diff@^1.1.2, fast-diff@^1.2.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.3.0.tgz#ece407fa550a64d638536cd727e129c61616e0f0" + integrity sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw== + +fast-glob@^3.0.3, fast-glob@^3.2.9: + version "3.3.2" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129" + integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.2" + merge2 "^1.3.0" + micromatch "^4.0.4" + +fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== + +fastq@^1.6.0: + version "1.15.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.15.0.tgz#d04d07c6a2a68fe4599fea8d2e103a937fae6b3a" + integrity sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw== + dependencies: + reusify "^1.0.4" + +file-entry-cache@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" + integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== + dependencies: + flat-cache "^3.0.4" + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +finalhandler@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32" + integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "2.4.1" + parseurl "~1.3.3" + statuses "2.0.1" + unpipe "~1.0.0" + +find-replace@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/find-replace/-/find-replace-3.0.0.tgz#3e7e23d3b05167a76f770c9fbd5258b0def68c38" + integrity sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ== + dependencies: + array-back "^3.0.1" + +find-up@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== + dependencies: + locate-path "^6.0.0" + path-exists "^4.0.0" + +find-up@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" + integrity sha512-jvElSjyuo4EMQGoTwo1uJU5pQMwTW5lS1x05zzfJuTIyLR3zwO27LYrxNg+dlvKpGOuGy/MzBdXh80g0ve5+HA== + dependencies: + path-exists "^2.0.0" + pinkie-promise "^2.0.0" + +find-up@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" + integrity sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ== + dependencies: + locate-path "^2.0.0" + +flat-cache@^3.0.4: + version "3.1.1" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.1.1.tgz#a02a15fdec25a8f844ff7cc658f03dd99eb4609b" + integrity sha512-/qM2b3LUIaIgviBQovTLvijfyOQXPtSRnRK26ksj2J7rzPIecePUIpJsZ4T02Qg+xiAEKIs5K8dsHEd+VaKa/Q== + dependencies: + flatted "^3.2.9" + keyv "^4.5.3" + rimraf "^3.0.2" + +flat@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" + integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== + +flatted@^3.2.9: + version "3.2.9" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.9.tgz#7eb4c67ca1ba34232ca9d2d93e9886e611ad7daf" + integrity sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ== + +fmix@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/fmix/-/fmix-0.1.0.tgz#c7bbf124dec42c9d191cfb947d0a9778dd986c0c" + integrity sha512-Y6hyofImk9JdzU8k5INtTXX1cu8LDlePWDFU5sftm9H+zKCr5SGrVjdhkvsim646cw5zD0nADj8oHyXMZmCZ9w== + dependencies: + imul "^1.0.0" + +follow-redirects@^1.12.1, follow-redirects@^1.14.0, follow-redirects@^1.15.0: + version "1.15.3" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.3.tgz#fe2f3ef2690afce7e82ed0b44db08165b207123a" + integrity sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q== + +for-each@^0.3.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" + integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw== + dependencies: + is-callable "^1.1.3" + +forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + integrity sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw== + +form-data-encoder@1.7.1: + version "1.7.1" + resolved "https://registry.yarnpkg.com/form-data-encoder/-/form-data-encoder-1.7.1.tgz#ac80660e4f87ee0d3d3c3638b7da8278ddb8ec96" + integrity sha512-EFRDrsMm/kyqbTQocNvRXMLjc7Es2Vk+IQFx/YW7hkUH1eBl4J1fqiP34l74Yt0pFLCNpc06fkbVk00008mzjg== + +form-data@^2.2.0: + version "2.5.1" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.5.1.tgz#f2cbec57b5e59e23716e128fe44d4e5dd23895f4" + integrity sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.6" + mime-types "^2.1.12" + +form-data@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" + integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + +form-data@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" + integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.6" + mime-types "^2.1.12" + +forwarded@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" + integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== + +fp-ts@1.19.3: + version "1.19.3" + resolved "https://registry.yarnpkg.com/fp-ts/-/fp-ts-1.19.3.tgz#261a60d1088fbff01f91256f91d21d0caaaaa96f" + integrity sha512-H5KQDspykdHuztLTg+ajGN0Z2qUjcEf3Ybxc6hLt0k7/zPkn29XnKnxlBPyW2XIddWrGaJBzBl4VLYOtk39yZg== + +fp-ts@^1.0.0: + version "1.19.5" + resolved "https://registry.yarnpkg.com/fp-ts/-/fp-ts-1.19.5.tgz#3da865e585dfa1fdfd51785417357ac50afc520a" + integrity sha512-wDNqTimnzs8QqpldiId9OavWK2NptormjXnRJTQecNjzwfyp6P/8s/zG8e4h3ja3oqkKaY72UlTjQYt/1yXf9A== + +fresh@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== + +fs-extra@^0.30.0: + version "0.30.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-0.30.0.tgz#f233ffcc08d4da7d432daa449776989db1df93f0" + integrity sha512-UvSPKyhMn6LEd/WpUaV9C9t3zATuqoqfWc3QdPhPLb58prN9tqYPlPWi8Krxi44loBoUzlobqZ3+8tGpxxSzwA== + dependencies: + graceful-fs "^4.1.2" + jsonfile "^2.1.0" + klaw "^1.0.0" + path-is-absolute "^1.0.0" + rimraf "^2.2.8" + +fs-extra@^10.0.0: + version "10.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.1.0.tgz#02873cfbc4084dde127eaa5f9905eef2325d1abf" + integrity sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" + +fs-extra@^4.0.2: + version "4.0.3" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-4.0.3.tgz#0d852122e5bc5beb453fb028e9c0c9bf36340c94" + integrity sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg== + dependencies: + graceful-fs "^4.1.2" + jsonfile "^4.0.0" + universalify "^0.1.0" + +fs-extra@^7.0.0, fs-extra@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9" + integrity sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw== + dependencies: + graceful-fs "^4.1.2" + jsonfile "^4.0.0" + universalify "^0.1.0" + +fs-extra@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" + integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^4.0.0" + universalify "^0.1.0" + +fs-extra@^9.1.0: + version "9.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" + integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== + dependencies: + at-least-node "^1.0.0" + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" + +fs-minipass@^1.2.7: + version "1.2.7" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.7.tgz#ccff8570841e7fe4265693da88936c55aed7f7c7" + integrity sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA== + dependencies: + minipass "^2.6.0" + +fs-readdir-recursive@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz#e32fc030a2ccee44a6b5371308da54be0b397d27" + integrity sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA== + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== + +fsevents@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== + +function-bind@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" + integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== + +function.prototype.name@^1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.6.tgz#cdf315b7d90ee77a4c6ee216c3c3362da07533fd" + integrity sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + functions-have-names "^1.2.3" + +functional-red-black-tree@^1.0.1, functional-red-black-tree@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" + integrity sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g== + +functions-have-names@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" + integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== + +ganache@7.4.3: + version "7.4.3" + resolved "https://registry.yarnpkg.com/ganache/-/ganache-7.4.3.tgz#e995f1250697264efbb34d4241c374a2b0271415" + integrity sha512-RpEDUiCkqbouyE7+NMXG26ynZ+7sGiODU84Kz+FVoXUnQ4qQM4M8wif3Y4qUCt+D/eM1RVeGq0my62FPD6Y1KA== + dependencies: + "@trufflesuite/bigint-buffer" "1.1.10" + "@types/bn.js" "^5.1.0" + "@types/lru-cache" "5.1.1" + "@types/seedrandom" "3.0.1" + emittery "0.10.0" + keccak "3.0.2" + leveldown "6.1.0" + secp256k1 "4.0.3" + optionalDependencies: + bufferutil "4.0.5" + utf-8-validate "5.0.7" + +get-caller-file@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" + integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w== + +get-caller-file@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +get-func-name@^2.0.1, get-func-name@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.2.tgz#0d7cf20cd13fda808669ffa88f4ffc7a3943fc41" + integrity sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ== + +get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@^1.2.0, get-intrinsic@^1.2.1, get-intrinsic@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.2.tgz#281b7622971123e1ef4b3c90fd7539306da93f3b" + integrity sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA== + dependencies: + function-bind "^1.1.2" + has-proto "^1.0.1" + has-symbols "^1.0.3" + hasown "^2.0.0" + +get-port@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/get-port/-/get-port-3.2.0.tgz#dd7ce7de187c06c8bf353796ac71e099f0980ebc" + integrity sha512-x5UJKlgeUiNT8nyo/AcnwLnZuZNcSjSw0kogRB+Whd1fjjFq4B1hySFxSFWWSn4mIBzg3sRNUDFYc4g5gjPoLg== + +get-stream@^5.1.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" + integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== + dependencies: + pump "^3.0.0" + +get-stream@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" + integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== + +get-symbol-description@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz#7fdb81c900101fbd564dd5f1a30af5aadc1e58d6" + integrity sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.1" + +getpass@^0.1.1: + version "0.1.7" + resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" + integrity sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng== + dependencies: + assert-plus "^1.0.0" + +ghost-testrpc@^0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/ghost-testrpc/-/ghost-testrpc-0.0.2.tgz#c4de9557b1d1ae7b2d20bbe474a91378ca90ce92" + integrity sha512-i08dAEgJ2g8z5buJIrCTduwPIhih3DP+hOCTyyryikfV8T0bNvHnGXO67i0DD1H4GBDETTclPy9njZbfluQYrQ== + dependencies: + chalk "^2.4.2" + node-emoji "^1.10.0" + +glob-parent@^5.1.2, glob-parent@~5.1.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" + +glob@7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" + integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@^5.0.15: + version "5.0.15" + resolved "https://registry.yarnpkg.com/glob/-/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1" + integrity sha512-c9IPMazfRITpmAAKi22dK1VKxGDX9ehhqfABDriL/lzO92xcUKEJPQHrVA/2YHSNFB4iFlykVmWvwo48nr3OxA== + dependencies: + inflight "^1.0.4" + inherits "2" + minimatch "2 || 3" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@^7.0.0, glob@^7.1.3: + version "7.2.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.1.1" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@^8.0.3: + version "8.1.0" + resolved "https://registry.yarnpkg.com/glob/-/glob-8.1.0.tgz#d388f656593ef708ee3e34640fdfb99a9fd1c33e" + integrity sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^5.0.1" + once "^1.3.0" + +global-modules@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-2.0.0.tgz#997605ad2345f27f51539bea26574421215c7780" + integrity sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A== + dependencies: + global-prefix "^3.0.0" + +global-prefix@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-3.0.0.tgz#fc85f73064df69f50421f47f883fe5b913ba9b97" + integrity sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg== + dependencies: + ini "^1.3.5" + kind-of "^6.0.2" + which "^1.3.1" + +global@~4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/global/-/global-4.4.0.tgz#3e7b105179006a323ed71aafca3e9c57a5cc6406" + integrity sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w== + dependencies: + min-document "^2.19.0" + process "^0.11.10" + +globals@^13.6.0, globals@^13.9.0: + version "13.23.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.23.0.tgz#ef31673c926a0976e1f61dab4dca57e0c0a8af02" + integrity sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA== + dependencies: + type-fest "^0.20.2" + +globalthis@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.3.tgz#5852882a52b80dc301b0660273e1ed082f0b6ccf" + integrity sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA== + dependencies: + define-properties "^1.1.3" + +globby@^10.0.1: + version "10.0.2" + resolved "https://registry.yarnpkg.com/globby/-/globby-10.0.2.tgz#277593e745acaa4646c3ab411289ec47a0392543" + integrity sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg== + dependencies: + "@types/glob" "^7.1.1" + array-union "^2.1.0" + dir-glob "^3.0.1" + fast-glob "^3.0.3" + glob "^7.1.3" + ignore "^5.1.1" + merge2 "^1.2.3" + slash "^3.0.0" + +globby@^11.0.3: + version "11.1.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" + integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== + dependencies: + array-union "^2.1.0" + dir-glob "^3.0.1" + fast-glob "^3.2.9" + ignore "^5.2.0" + merge2 "^1.4.1" + slash "^3.0.0" + +gopd@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" + integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== + dependencies: + get-intrinsic "^1.1.3" + +got@12.1.0: + version "12.1.0" + resolved "https://registry.yarnpkg.com/got/-/got-12.1.0.tgz#099f3815305c682be4fd6b0ee0726d8e4c6b0af4" + integrity sha512-hBv2ty9QN2RdbJJMK3hesmSkFTjVIHyIDDbssCKnSmq62edGgImJWD10Eb1k77TiV1bxloxqcFAVK8+9pkhOig== + dependencies: + "@sindresorhus/is" "^4.6.0" + "@szmarczak/http-timer" "^5.0.1" + "@types/cacheable-request" "^6.0.2" + "@types/responselike" "^1.0.0" + cacheable-lookup "^6.0.4" + cacheable-request "^7.0.2" + decompress-response "^6.0.0" + form-data-encoder "1.7.1" + get-stream "^6.0.1" + http2-wrapper "^2.1.10" + lowercase-keys "^3.0.0" + p-cancelable "^3.0.0" + responselike "^2.0.0" + +got@^11.8.5: + version "11.8.6" + resolved "https://registry.yarnpkg.com/got/-/got-11.8.6.tgz#276e827ead8772eddbcfc97170590b841823233a" + integrity sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g== + dependencies: + "@sindresorhus/is" "^4.0.0" + "@szmarczak/http-timer" "^4.0.5" + "@types/cacheable-request" "^6.0.1" + "@types/responselike" "^1.0.0" + cacheable-lookup "^5.0.3" + cacheable-request "^7.0.2" + decompress-response "^6.0.0" + http2-wrapper "^1.0.0-beta.5.2" + lowercase-keys "^2.0.0" + p-cancelable "^2.0.0" + responselike "^2.0.0" + +graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@^4.2.0: + version "4.2.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" + integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== + +handlebars@^4.0.1, handlebars@^4.7.7: + version "4.7.8" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.8.tgz#41c42c18b1be2365439188c77c6afae71c0cd9e9" + integrity sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ== + dependencies: + minimist "^1.2.5" + neo-async "^2.6.2" + source-map "^0.6.1" + wordwrap "^1.0.0" + optionalDependencies: + uglify-js "^3.1.4" + +har-schema@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" + integrity sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q== + +har-validator@~5.1.3: + version "5.1.5" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.5.tgz#1f0803b9f8cb20c0fa13822df1ecddb36bde1efd" + integrity sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w== + dependencies: + ajv "^6.12.3" + har-schema "^2.0.0" + +hardhat-dependency-compiler@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/hardhat-dependency-compiler/-/hardhat-dependency-compiler-1.1.3.tgz#1e49e23f68878bd713f860c66648a711bc4a4a79" + integrity sha512-bCDqsOxGST6WkbMvj4lPchYWidNSSBm5CFnkyAex1T11cGmr9otZTGl81W6f9pmrtBXbKCvr3OSuNJ6Q394sAw== + +hardhat-deploy@^0.11.26: + version "0.11.43" + resolved "https://registry.yarnpkg.com/hardhat-deploy/-/hardhat-deploy-0.11.43.tgz#b22ff15b3ea201b72ba0f17f4b2e182cc950e73e" + integrity sha512-D760CjDtinwjOCpKOvdyRtIJYLQIYXmhfgkFe+AkxlYM9bPZ/T4tZ/xIB2tR89ZT+z0hF1YuZFBXIL3/G/9T5g== + dependencies: + "@ethersproject/abi" "^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/contracts" "^5.7.0" + "@ethersproject/providers" "^5.7.2" + "@ethersproject/solidity" "^5.7.0" + "@ethersproject/transactions" "^5.7.0" + "@ethersproject/wallet" "^5.7.0" + "@types/qs" "^6.9.7" + axios "^0.21.1" + chalk "^4.1.2" + chokidar "^3.5.2" + debug "^4.3.2" + enquirer "^2.3.6" + ethers "^5.7.0" + form-data "^4.0.0" + fs-extra "^10.0.0" + match-all "^1.2.6" + murmur-128 "^0.2.1" + qs "^6.9.4" + zksync-web3 "^0.14.3" + +hardhat-gas-reporter@^1.0.8: + version "1.0.9" + resolved "https://registry.yarnpkg.com/hardhat-gas-reporter/-/hardhat-gas-reporter-1.0.9.tgz#9a2afb354bc3b6346aab55b1c02ca556d0e16450" + integrity sha512-INN26G3EW43adGKBNzYWOlI3+rlLnasXTwW79YNnUhXPDa+yHESgt639dJEs37gCjhkbNKcRRJnomXEuMFBXJg== + dependencies: + array-uniq "1.0.3" + eth-gas-reporter "^0.2.25" + sha1 "^1.1.1" + +hardhat-watcher@^2.1.1: + version "2.5.0" + resolved "https://registry.yarnpkg.com/hardhat-watcher/-/hardhat-watcher-2.5.0.tgz#3ee76c3cb5b99f2875b78d176207745aa484ed4a" + integrity sha512-Su2qcSMIo2YO2PrmJ0/tdkf+6pSt8zf9+4URR5edMVti6+ShI8T3xhPrwugdyTOFuyj8lKHrcTZNKUFYowYiyA== + dependencies: + chokidar "^3.5.3" + +hardhat@^2.9.7: + version "2.19.0" + resolved "https://registry.yarnpkg.com/hardhat/-/hardhat-2.19.0.tgz#1e08658863550ba351788ea128e544ff80584a31" + integrity sha512-kMpwovOEfrFRQXEopCP+JTcKVwSYVj8rnXE0LynxDqnh06yvyKCQknmXL6IVYTHQL6Csysc/yNbCHQbjSeJGpA== + dependencies: + "@ethersproject/abi" "^5.1.2" + "@metamask/eth-sig-util" "^4.0.0" + "@nomicfoundation/ethereumjs-block" "5.0.2" + "@nomicfoundation/ethereumjs-blockchain" "7.0.2" + "@nomicfoundation/ethereumjs-common" "4.0.2" + "@nomicfoundation/ethereumjs-evm" "2.0.2" + "@nomicfoundation/ethereumjs-rlp" "5.0.2" + "@nomicfoundation/ethereumjs-statemanager" "2.0.2" + "@nomicfoundation/ethereumjs-trie" "6.0.2" + "@nomicfoundation/ethereumjs-tx" "5.0.2" + "@nomicfoundation/ethereumjs-util" "9.0.2" + "@nomicfoundation/ethereumjs-vm" "7.0.2" + "@nomicfoundation/solidity-analyzer" "^0.1.0" + "@sentry/node" "^5.18.1" + "@types/bn.js" "^5.1.0" + "@types/lru-cache" "^5.1.0" + adm-zip "^0.4.16" + aggregate-error "^3.0.0" + ansi-escapes "^4.3.0" + chalk "^2.4.2" + chokidar "^3.4.0" + ci-info "^2.0.0" + debug "^4.1.1" + enquirer "^2.3.0" + env-paths "^2.2.0" + ethereum-cryptography "^1.0.3" + ethereumjs-abi "^0.6.8" + find-up "^2.1.0" + fp-ts "1.19.3" + fs-extra "^7.0.1" + glob "7.2.0" + immutable "^4.0.0-rc.12" + io-ts "1.10.4" + keccak "^3.0.2" + lodash "^4.17.11" + mnemonist "^0.38.0" + mocha "^10.0.0" + p-map "^4.0.0" + raw-body "^2.4.1" + resolve "1.17.0" + semver "^6.3.0" + solc "0.7.3" + source-map-support "^0.5.13" + stacktrace-parser "^0.1.10" + tsort "0.0.1" + undici "^5.14.0" + uuid "^8.3.2" + ws "^7.4.6" + +has-bigints@^1.0.1, has-bigints@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa" + integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ== + +has-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" + integrity sha512-DyYHfIYwAJmjAjSSPKANxI8bFY9YtFrgkAfinBojQ8YJTOuOuav64tMUJv584SES4xl74PmuaevIyaLESHdTAA== + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +has-property-descriptors@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz#52ba30b6c5ec87fd89fa574bc1c39125c6f65340" + integrity sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg== + dependencies: + get-intrinsic "^1.2.2" + +has-proto@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.1.tgz#1885c1305538958aff469fef37937c22795408e0" + integrity sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg== + +has-symbols@^1.0.2, has-symbols@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" + integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== + +has-tostringtag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" + integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== + dependencies: + has-symbols "^1.0.2" + +hash-base@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.1.0.tgz#55c381d9e06e1d2997a883b4a3fddfe7f0d3af33" + integrity sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA== + dependencies: + inherits "^2.0.4" + readable-stream "^3.6.0" + safe-buffer "^5.2.0" + +hash.js@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.3.tgz#340dedbe6290187151c1ea1d777a3448935df846" + integrity sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA== + dependencies: + inherits "^2.0.3" + minimalistic-assert "^1.0.0" + +hash.js@1.1.7, hash.js@^1.0.0, hash.js@^1.0.3, hash.js@^1.1.7: + version "1.1.7" + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" + integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== + dependencies: + inherits "^2.0.3" + minimalistic-assert "^1.0.1" + +hasown@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.0.tgz#f4c513d454a57b7c7e1650778de226b11700546c" + integrity sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA== + dependencies: + function-bind "^1.1.2" + +he@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" + integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== + +header-case@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/header-case/-/header-case-1.0.1.tgz#9535973197c144b09613cd65d317ef19963bd02d" + integrity sha512-i0q9mkOeSuhXw6bGgiQCCBgY/jlZuV/7dZXyZ9c6LcBrqwvT8eT719E9uxE5LiZftdl+z81Ugbg/VvXV4OJOeQ== + dependencies: + no-case "^2.2.0" + upper-case "^1.1.3" + +"heap@>= 0.2.0": + version "0.2.7" + resolved "https://registry.yarnpkg.com/heap/-/heap-0.2.7.tgz#1e6adf711d3f27ce35a81fe3b7bd576c2260a8fc" + integrity sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg== + +highlight.js@^10.4.1: + version "10.7.3" + resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-10.7.3.tgz#697272e3991356e40c3cac566a74eef681756531" + integrity sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A== + +highlightjs-solidity@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/highlightjs-solidity/-/highlightjs-solidity-2.0.6.tgz#e7a702a2b05e0a97f185e6ba39fd4846ad23a990" + integrity sha512-DySXWfQghjm2l6a/flF+cteroJqD4gI8GSdL4PtvxZSsAHie8m3yVe2JFoRg03ROKT6hp2Lc/BxXkqerNmtQYg== + +hmac-drbg@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" + integrity sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg== + dependencies: + hash.js "^1.0.3" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.1" + +hosted-git-info@^2.1.4, hosted-git-info@^2.6.0: + version "2.8.9" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" + integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== + +htmlparser2@^8.0.1: + version "8.0.2" + resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-8.0.2.tgz#f002151705b383e62433b5cf466f5b716edaec21" + integrity sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA== + dependencies: + domelementtype "^2.3.0" + domhandler "^5.0.3" + domutils "^3.0.1" + entities "^4.4.0" + +http-basic@^8.1.1: + version "8.1.3" + resolved "https://registry.yarnpkg.com/http-basic/-/http-basic-8.1.3.tgz#a7cabee7526869b9b710136970805b1004261bbf" + integrity sha512-/EcDMwJZh3mABI2NhGfHOGOeOZITqfkEO4p/xK+l3NpyncIHUQBoMvCSF/b5GqvKtySC2srL/GGG3+EtlqlmCw== + dependencies: + caseless "^0.12.0" + concat-stream "^1.6.2" + http-response-object "^3.0.1" + parse-cache-control "^1.0.1" + +http-cache-semantics@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz#abe02fcb2985460bf0323be664436ec3476a6d5a" + integrity sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ== + +http-errors@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" + integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== + dependencies: + depd "2.0.0" + inherits "2.0.4" + setprototypeof "1.2.0" + statuses "2.0.1" + toidentifier "1.0.1" + +http-https@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/http-https/-/http-https-1.0.0.tgz#2f908dd5f1db4068c058cd6e6d4ce392c913389b" + integrity sha512-o0PWwVCSp3O0wS6FvNr6xfBCHgt0m1tvPLFOCc2iFDKTRAXhB7m8klDf7ErowFH8POa6dVdGatKU5I1YYwzUyg== + +http-response-object@^3.0.1: + version "3.0.2" + resolved "https://registry.yarnpkg.com/http-response-object/-/http-response-object-3.0.2.tgz#7f435bb210454e4360d074ef1f989d5ea8aa9810" + integrity sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA== + dependencies: + "@types/node" "^10.0.3" + +http-signature@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" + integrity sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ== + dependencies: + assert-plus "^1.0.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + +http2-wrapper@^1.0.0-beta.5.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/http2-wrapper/-/http2-wrapper-1.0.3.tgz#b8f55e0c1f25d4ebd08b3b0c2c079f9590800b3d" + integrity sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg== + dependencies: + quick-lru "^5.1.1" + resolve-alpn "^1.0.0" + +http2-wrapper@^2.1.10: + version "2.2.0" + resolved "https://registry.yarnpkg.com/http2-wrapper/-/http2-wrapper-2.2.0.tgz#b80ad199d216b7d3680195077bd7b9060fa9d7f3" + integrity sha512-kZB0wxMo0sh1PehyjJUWRFEd99KC5TLjZ2cULC4f9iqJBAmKQQXEICjxl5iPJRwP40dpeHFqqhm7tYCvODpqpQ== + dependencies: + quick-lru "^5.1.1" + resolve-alpn "^1.2.0" + +https-proxy-agent@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" + integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== + dependencies: + agent-base "6" + debug "4" + +husky@^8.0.3: + version "8.0.3" + resolved "https://registry.yarnpkg.com/husky/-/husky-8.0.3.tgz#4936d7212e46d1dea28fef29bb3a108872cd9184" + integrity sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg== + +iconv-lite@0.4.24: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +idna-uts46-hx@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/idna-uts46-hx/-/idna-uts46-hx-2.3.1.tgz#a1dc5c4df37eee522bf66d969cc980e00e8711f9" + integrity sha512-PWoF9Keq6laYdIRwwCdhTPl60xRqAloYNMQLiyUnG42VjT53oW07BXIRM+NK7eQjzXjAk2gUvX9caRxlnF9TAA== + dependencies: + punycode "2.1.0" + +ieee754@^1.1.13, ieee754@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== + +ignore@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" + integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== + +ignore@^5.1.1, ignore@^5.1.8, ignore@^5.2.0, ignore@^5.2.4: + version "5.2.4" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" + integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== + +immediate@^3.2.3: + version "3.3.0" + resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.3.0.tgz#1aef225517836bcdf7f2a2de2600c79ff0269266" + integrity sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q== + +immediate@~3.2.3: + version "3.2.3" + resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.2.3.tgz#d140fa8f614659bd6541233097ddaac25cdd991c" + integrity sha512-RrGCXRm/fRVqMIhqXrGEX9rRADavPiDFSoMb/k64i9XMk8uH4r/Omi5Ctierj6XzNecwDbO4WuFbDD1zmpl3Tg== + +immutable@^4.0.0-rc.12: + version "4.3.4" + resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.3.4.tgz#2e07b33837b4bb7662f288c244d1ced1ef65a78f" + integrity sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA== + +import-fresh@^3.0.0, import-fresh@^3.2.1, import-fresh@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" + integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + +imul@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/imul/-/imul-1.0.1.tgz#9d5867161e8b3de96c2c38d5dc7cb102f35e2ac9" + integrity sha512-WFAgfwPLAjU66EKt6vRdTlKj4nAgIDQzh29JonLa4Bqtl6D8JrIMvWjCnx7xEjVNmP3U0fM5o8ZObk7d0f62bA== + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== + +indent-string@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" + integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +ini@^1.3.5: + version "1.3.8" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" + integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== + +internal-slot@^1.0.5: + version "1.0.6" + resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.6.tgz#37e756098c4911c5e912b8edbf71ed3aa116f930" + integrity sha512-Xj6dv+PsbtwyPpEflsejS+oIZxmMlV44zAhG479uYu89MsjcYOhCFnNyKrkJrihbsiasQyY0afoCl/9BLR65bg== + dependencies: + get-intrinsic "^1.2.2" + hasown "^2.0.0" + side-channel "^1.0.4" + +interpret@^1.0.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e" + integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA== + +invert-kv@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" + integrity sha512-xgs2NH9AE66ucSq4cNG1nhSFghr5l6tdL15Pk+jl46bmmBapgoaY/AacXyaDznAqmGL99TiLSQgO/XazFSKYeQ== + +io-ts@1.10.4: + version "1.10.4" + resolved "https://registry.yarnpkg.com/io-ts/-/io-ts-1.10.4.tgz#cd5401b138de88e4f920adbcb7026e2d1967e6e2" + integrity sha512-b23PteSnYXSONJ6JQXRAlvJhuw8KOtkqa87W4wDtvMrud/DTJd5X+NpOOI+O/zZwVq6v0VLAaJ+1EDViKEuN9g== + dependencies: + fp-ts "^1.0.0" + +ipaddr.js@1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" + integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== + +is-arguments@^1.0.4: + version "1.1.1" + resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b" + integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-array-buffer@^3.0.1, is-array-buffer@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/is-array-buffer/-/is-array-buffer-3.0.2.tgz#f2653ced8412081638ecb0ebbd0c41c6e0aecbbe" + integrity sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.2.0" + is-typed-array "^1.1.10" + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== + +is-bigint@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3" + integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg== + dependencies: + has-bigints "^1.0.1" + +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + +is-boolean-object@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719" + integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-buffer@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.5.tgz#ebc252e400d22ff8d77fa09888821a24a658c191" + integrity sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ== + +is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7: + version "1.2.7" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" + integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== + +is-core-module@^2.13.0, is-core-module@^2.13.1: + version "2.13.1" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.1.tgz#ad0d7532c6fea9da1ebdc82742d74525c6273384" + integrity sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw== + dependencies: + hasown "^2.0.0" + +is-date-object@^1.0.1: + version "1.0.5" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" + integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== + dependencies: + has-tostringtag "^1.0.0" + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== + +is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + integrity sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw== + dependencies: + number-is-nan "^1.0.0" + +is-fullwidth-code-point@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + integrity sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w== + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-function@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-function/-/is-function-1.0.2.tgz#4f097f30abf6efadac9833b17ca5dc03f8144e08" + integrity sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ== + +is-generator-function@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.10.tgz#f1558baf1ac17e0deea7c0415c438351ff2b3c72" + integrity sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A== + dependencies: + has-tostringtag "^1.0.0" + +is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + +is-hex-prefixed@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz#7d8d37e6ad77e5d127148913c573e082d777f554" + integrity sha512-WvtOiug1VFrE9v1Cydwm+FnXd3+w9GaeVUss5W4v/SLy3UW00vP+6iNF2SdnfiBoLy4bTqVdkftNGTUeOFVsbA== + +is-lower-case@^1.1.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/is-lower-case/-/is-lower-case-1.1.3.tgz#7e147be4768dc466db3bfb21cc60b31e6ad69393" + integrity sha512-+5A1e/WJpLLXZEDlgz4G//WYSHyQBD32qa4Jd3Lw06qQlv3fJHnp3YIHjTQSGzHMgzmVKz2ZP3rBxTHkPw/lxA== + dependencies: + lower-case "^1.1.0" + +is-negative-zero@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150" + integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA== + +is-number-object@^1.0.4: + version "1.0.7" + resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.7.tgz#59d50ada4c45251784e9904f5246c742f07a42fc" + integrity sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ== + dependencies: + has-tostringtag "^1.0.0" + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-plain-obj@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" + integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== + +is-regex@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" + integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-shared-array-buffer@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz#8f259c573b60b6a32d4058a1a07430c0a7344c79" + integrity sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA== + dependencies: + call-bind "^1.0.2" + +is-string@^1.0.5, is-string@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" + integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg== + dependencies: + has-tostringtag "^1.0.0" + +is-symbol@^1.0.2, is-symbol@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c" + integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== + dependencies: + has-symbols "^1.0.2" + +is-typed-array@^1.1.10, is-typed-array@^1.1.12, is-typed-array@^1.1.3, is-typed-array@^1.1.9: + version "1.1.12" + resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.12.tgz#d0bab5686ef4a76f7a73097b95470ab199c57d4a" + integrity sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg== + dependencies: + which-typed-array "^1.1.11" + +is-typedarray@^1.0.0, is-typedarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + integrity sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA== + +is-unicode-supported@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" + integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== + +is-upper-case@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/is-upper-case/-/is-upper-case-1.1.2.tgz#8d0b1fa7e7933a1e58483600ec7d9661cbaf756f" + integrity sha512-GQYSJMgfeAmVwh9ixyk888l7OIhNAGKtY6QA+IrWlu9MDTCaXmeozOZ2S9Knj7bQwBO/H6J2kb+pbyTUiMNbsw== + dependencies: + upper-case "^1.1.0" + +is-url@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/is-url/-/is-url-1.2.4.tgz#04a4df46d28c4cff3d73d01ff06abeb318a1aa52" + integrity sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww== + +is-utf8@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" + integrity sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q== + +is-weakref@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2" + integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ== + dependencies: + call-bind "^1.0.2" + +isarray@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" + integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== + +isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== + +isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + integrity sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g== + +js-sdsl@^4.1.4: + version "4.4.2" + resolved "https://registry.yarnpkg.com/js-sdsl/-/js-sdsl-4.4.2.tgz#2e3c031b1f47d3aca8b775532e3ebb0818e7f847" + integrity sha512-dwXFwByc/ajSV6m5bcKAPwe4yDDF6D614pxmIi5odytzxRlwqF6nwoiCek80Ixc7Cvma5awClxrzFtxCQvcM8w== + +js-sha3@0.5.7, js-sha3@^0.5.7: + version "0.5.7" + resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.5.7.tgz#0d4ffd8002d5333aabaf4a23eed2f6374c9f28e7" + integrity sha512-GII20kjaPX0zJ8wzkTbNDYMY7msuZcTWk8S5UOh6806Jq/wz1J8/bnr8uGU0DAUmYDjj2Mr4X1cW8v/GLYnR+g== + +js-sha3@0.8.0, js-sha3@^0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840" + integrity sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q== + +js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-yaml@3.x, js-yaml@^3.13.1: + version "3.14.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" + integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +js-yaml@4.1.0, js-yaml@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" + +jsbi@^3.1.4: + version "3.2.5" + resolved "https://registry.yarnpkg.com/jsbi/-/jsbi-3.2.5.tgz#b37bb90e0e5c2814c1c2a1bcd8c729888a2e37d6" + integrity sha512-aBE4n43IPvjaddScbvWRA2YlTzKEynHzu7MqOyTipdHucf/VxS63ViCjxYRg86M8Rxwbt/GfzHl1kKERkt45fQ== + +jsbn@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + integrity sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg== + +json-bigint@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/json-bigint/-/json-bigint-1.0.0.tgz#ae547823ac0cad8398667f8cd9ef4730f5b01ff1" + integrity sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ== + dependencies: + bignumber.js "^9.0.0" + +json-buffer@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" + integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== + +json-parse-even-better-errors@^2.3.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" + integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-schema-traverse@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" + integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== + +json-schema@0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5" + integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA== + +json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== + +json-stringify-safe@~5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA== + +json5@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.2.tgz#63d98d60f21b313b77c4d6da18bfa69d80e1d593" + integrity sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA== + dependencies: + minimist "^1.2.0" + +jsonfile@^2.1.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8" + integrity sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw== + optionalDependencies: + graceful-fs "^4.1.6" + +jsonfile@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" + integrity sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg== + optionalDependencies: + graceful-fs "^4.1.6" + +jsonfile@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" + integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== + dependencies: + universalify "^2.0.0" + optionalDependencies: + graceful-fs "^4.1.6" + +jsonschema@^1.2.4: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jsonschema/-/jsonschema-1.4.1.tgz#cc4c3f0077fb4542982973d8a083b6b34f482dab" + integrity sha512-S6cATIPVv1z0IlxdN+zUk5EPjkGCdnhN4wVSBlvoUO1tOLJootbo9CquNJmbIh4yikWHiUedhRYrNPn1arpEmQ== + +jsprim@^1.2.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.2.tgz#712c65533a15c878ba59e9ed5f0e26d5b77c5feb" + integrity sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw== + dependencies: + assert-plus "1.0.0" + extsprintf "1.3.0" + json-schema "0.4.0" + verror "1.10.0" + +keccak@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/keccak/-/keccak-3.0.1.tgz#ae30a0e94dbe43414f741375cff6d64c8bea0bff" + integrity sha512-epq90L9jlFWCW7+pQa6JOnKn2Xgl2mtI664seYR6MHskvI9agt7AnDqmAlp9TqU4/caMYbA08Hi5DMZAl5zdkA== + dependencies: + node-addon-api "^2.0.0" + node-gyp-build "^4.2.0" + +keccak@3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/keccak/-/keccak-3.0.2.tgz#4c2c6e8c54e04f2670ee49fa734eb9da152206e0" + integrity sha512-PyKKjkH53wDMLGrvmRGSNWgmSxZOUqbnXwKL9tmgbFYA1iAYqW21kfR7mZXV0MlESiefxQQE9X9fTa3X+2MPDQ== + dependencies: + node-addon-api "^2.0.0" + node-gyp-build "^4.2.0" + readable-stream "^3.6.0" + +keccak@^3.0.0, keccak@^3.0.2: + version "3.0.4" + resolved "https://registry.yarnpkg.com/keccak/-/keccak-3.0.4.tgz#edc09b89e633c0549da444432ecf062ffadee86d" + integrity sha512-3vKuW0jV8J3XNTzvfyicFR5qvxrSAGl7KIhvgOu5cmWwM7tZRj3fMbj/pfIf4be7aznbc+prBWGjywox/g2Y6Q== + dependencies: + node-addon-api "^2.0.0" + node-gyp-build "^4.2.0" + readable-stream "^3.6.0" + +keyv@^4.0.0, keyv@^4.5.3: + version "4.5.4" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93" + integrity sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw== + dependencies: + json-buffer "3.0.1" + +kind-of@^6.0.2: + version "6.0.3" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" + integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== + +klaw@^1.0.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/klaw/-/klaw-1.3.1.tgz#4088433b46b3b1ba259d78785d8e96f73ba02439" + integrity sha512-TED5xi9gGQjGpNnvRWknrwAB1eL5GciPfVFOt3Vk1OJCVDQbzuSfrF3hkUQKlsgKrG1F+0t5W0m+Fje1jIt8rw== + optionalDependencies: + graceful-fs "^4.1.9" + +lcid@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" + integrity sha512-YiGkH6EnGrDGqLMITnGjXtGmNtjoXw9SVUzcaos8RBi7Ps0VBylkq+vOcY9QE5poLasPCR849ucFUkl0UzUyOw== + dependencies: + invert-kv "^1.0.0" + +level-codec@^9.0.0: + version "9.0.2" + resolved "https://registry.yarnpkg.com/level-codec/-/level-codec-9.0.2.tgz#fd60df8c64786a80d44e63423096ffead63d8cbc" + integrity sha512-UyIwNb1lJBChJnGfjmO0OR+ezh2iVu1Kas3nvBS/BzGnx79dv6g7unpKIDNPMhfdTEGoc7mC8uAu51XEtX+FHQ== + dependencies: + buffer "^5.6.0" + +level-concat-iterator@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/level-concat-iterator/-/level-concat-iterator-3.1.0.tgz#5235b1f744bc34847ed65a50548aa88d22e881cf" + integrity sha512-BWRCMHBxbIqPxJ8vHOvKUsaO0v1sLYZtjN3K2iZJsRBYtp+ONsY6Jfi6hy9K3+zolgQRryhIn2NRZjZnWJ9NmQ== + dependencies: + catering "^2.1.0" + +level-concat-iterator@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/level-concat-iterator/-/level-concat-iterator-2.0.1.tgz#1d1009cf108340252cb38c51f9727311193e6263" + integrity sha512-OTKKOqeav2QWcERMJR7IS9CUo1sHnke2C0gkSmcR7QuEtFNLLzHQAvnMw8ykvEcv0Qtkg0p7FOwP1v9e5Smdcw== + +level-errors@^2.0.0, level-errors@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/level-errors/-/level-errors-2.0.1.tgz#2132a677bf4e679ce029f517c2f17432800c05c8" + integrity sha512-UVprBJXite4gPS+3VznfgDSU8PTRuVX0NXwoWW50KLxd2yw4Y1t2JUR5In1itQnudZqRMT9DlAM3Q//9NCjCFw== + dependencies: + errno "~0.1.1" + +level-iterator-stream@~4.0.0: + version "4.0.2" + resolved "https://registry.yarnpkg.com/level-iterator-stream/-/level-iterator-stream-4.0.2.tgz#7ceba69b713b0d7e22fcc0d1f128ccdc8a24f79c" + integrity sha512-ZSthfEqzGSOMWoUGhTXdX9jv26d32XJuHz/5YnuHZzH6wldfWMOVwI9TBtKcya4BKTyTt3XVA0A3cF3q5CY30Q== + dependencies: + inherits "^2.0.4" + readable-stream "^3.4.0" + xtend "^4.0.2" + +level-mem@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/level-mem/-/level-mem-5.0.1.tgz#c345126b74f5b8aa376dc77d36813a177ef8251d" + integrity sha512-qd+qUJHXsGSFoHTziptAKXoLX87QjR7v2KMbqncDXPxQuCdsQlzmyX+gwrEHhlzn08vkf8TyipYyMmiC6Gobzg== + dependencies: + level-packager "^5.0.3" + memdown "^5.0.0" + +level-packager@^5.0.3: + version "5.1.1" + resolved "https://registry.yarnpkg.com/level-packager/-/level-packager-5.1.1.tgz#323ec842d6babe7336f70299c14df2e329c18939" + integrity sha512-HMwMaQPlTC1IlcwT3+swhqf/NUO+ZhXVz6TY1zZIIZlIR0YSn8GtAAWmIvKjNY16ZkEg/JcpAuQskxsXqC0yOQ== + dependencies: + encoding-down "^6.3.0" + levelup "^4.3.2" + +level-supports@^2.0.1: + version "2.1.0" + resolved "https://registry.yarnpkg.com/level-supports/-/level-supports-2.1.0.tgz#9af908d853597ecd592293b2fad124375be79c5f" + integrity sha512-E486g1NCjW5cF78KGPrMDRBYzPuueMZ6VBXHT6gC7A8UYWGiM14fGgp+s/L1oFfDWSPV/+SFkYCmZ0SiESkRKA== + +level-supports@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/level-supports/-/level-supports-4.0.1.tgz#431546f9d81f10ff0fea0e74533a0e875c08c66a" + integrity sha512-PbXpve8rKeNcZ9C1mUicC9auIYFyGpkV9/i6g76tLgANwWhtG2v7I4xNBUlkn3lE2/dZF3Pi0ygYGtLc4RXXdA== + +level-supports@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/level-supports/-/level-supports-1.0.1.tgz#2f530a596834c7301622521988e2c36bb77d122d" + integrity sha512-rXM7GYnW8gsl1vedTJIbzOrRv85c/2uCMpiiCzO2fndd06U/kUXEEU9evYn4zFggBOg36IsBW8LzqIpETwwQzg== + dependencies: + xtend "^4.0.2" + +level-transcoder@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/level-transcoder/-/level-transcoder-1.0.1.tgz#f8cef5990c4f1283d4c86d949e73631b0bc8ba9c" + integrity sha512-t7bFwFtsQeD8cl8NIoQ2iwxA0CL/9IFw7/9gAjOonH0PWTTiRfY7Hq+Ejbsxh86tXobDQ6IOiddjNYIfOBs06w== + dependencies: + buffer "^6.0.3" + module-error "^1.0.1" + +level-ws@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/level-ws/-/level-ws-2.0.0.tgz#207a07bcd0164a0ec5d62c304b4615c54436d339" + integrity sha512-1iv7VXx0G9ec1isqQZ7y5LmoZo/ewAsyDHNA8EFDW5hqH2Kqovm33nSFkSdnLLAK+I5FlT+lo5Cw9itGe+CpQA== + dependencies: + inherits "^2.0.3" + readable-stream "^3.1.0" + xtend "^4.0.1" + +level@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/level/-/level-8.0.0.tgz#41b4c515dabe28212a3e881b61c161ffead14394" + integrity sha512-ypf0jjAk2BWI33yzEaaotpq7fkOPALKAgDBxggO6Q9HGX2MRXn0wbP1Jn/tJv1gtL867+YOjOB49WaUF3UoJNQ== + dependencies: + browser-level "^1.0.1" + classic-level "^1.2.0" + +leveldown@6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/leveldown/-/leveldown-6.1.0.tgz#7ab1297706f70c657d1a72b31b40323aa612b9ee" + integrity sha512-8C7oJDT44JXxh04aSSsfcMI8YiaGRhOFI9/pMEL7nWJLVsWajDPTRxsSHTM2WcTVY5nXM+SuRHzPPi0GbnDX+w== + dependencies: + abstract-leveldown "^7.2.0" + napi-macros "~2.0.0" + node-gyp-build "^4.3.0" + +levelup@^4.3.2: + version "4.4.0" + resolved "https://registry.yarnpkg.com/levelup/-/levelup-4.4.0.tgz#f89da3a228c38deb49c48f88a70fb71f01cafed6" + integrity sha512-94++VFO3qN95cM/d6eBXvd894oJE0w3cInq9USsyQzzoJxmiYzPAocNcuGCPGGjoXqDVJcr3C1jzt1TSjyaiLQ== + dependencies: + deferred-leveldown "~5.3.0" + level-errors "~2.0.0" + level-iterator-stream "~4.0.0" + level-supports "~1.0.0" + xtend "~4.0.0" + +levn@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" + integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== + dependencies: + prelude-ls "^1.2.1" + type-check "~0.4.0" + +levn@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" + integrity sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA== + dependencies: + prelude-ls "~1.1.2" + type-check "~0.3.2" + +lines-and-columns@^1.1.6: + version "1.2.4" + resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" + integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== + +load-json-file@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" + integrity sha512-cy7ZdNRXdablkXYNI049pthVeXFurRyb9+hA/dZzerZ0pGTx42z+y+ssxBaVV2l70t1muq5IdKhn4UtcoGUY9A== + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + pinkie-promise "^2.0.0" + strip-bom "^2.0.0" + +locate-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" + integrity sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA== + dependencies: + p-locate "^2.0.0" + path-exists "^3.0.0" + +locate-path@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== + dependencies: + p-locate "^5.0.0" + +lodash.assign@^4.0.3, lodash.assign@^4.0.6: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-4.2.0.tgz#0d99f3ccd7a6d261d19bdaeb9245005d285808e7" + integrity sha512-hFuH8TY+Yji7Eja3mGiuAxBqLagejScbG8GbG0j6o9vzn0YL14My+ktnqtZgFTosKymC9/44wP6s7xyuLfnClw== + +lodash.camelcase@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" + integrity sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA== + +lodash.merge@^4.6.2: + version "4.6.2" + resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" + integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== + +lodash.truncate@^4.4.2: + version "4.4.2" + resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193" + integrity sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw== + +lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.21: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + +log-symbols@4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" + integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== + dependencies: + chalk "^4.1.0" + is-unicode-supported "^0.1.0" + +loupe@^2.3.6: + version "2.3.7" + resolved "https://registry.yarnpkg.com/loupe/-/loupe-2.3.7.tgz#6e69b7d4db7d3ab436328013d37d1c8c3540c697" + integrity sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA== + dependencies: + get-func-name "^2.0.1" + +lower-case-first@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/lower-case-first/-/lower-case-first-1.0.2.tgz#e5da7c26f29a7073be02d52bac9980e5922adfa1" + integrity sha512-UuxaYakO7XeONbKrZf5FEgkantPf5DUqDayzP5VXZrtRPdH86s4kN47I8B3TW10S4QKiE3ziHNf3kRN//okHjA== + dependencies: + lower-case "^1.1.2" + +lower-case@^1.1.0, lower-case@^1.1.1, lower-case@^1.1.2: + version "1.1.4" + resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-1.1.4.tgz#9a2cabd1b9e8e0ae993a4bf7d5875c39c42e8eac" + integrity sha512-2Fgx1Ycm599x+WGpIYwJOvsjmXFzTSc34IwDWALRA/8AopUKAVPwfJ+h5+f85BCp0PWmmJcWzEpxOpoXycMpdA== + +lowercase-keys@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" + integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== + +lowercase-keys@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-3.0.0.tgz#c5e7d442e37ead247ae9db117a9d0a467c89d4f2" + integrity sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ== + +lru-cache@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" + integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== + dependencies: + yallist "^3.0.2" + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +lru_map@^0.3.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/lru_map/-/lru_map-0.3.3.tgz#b5c8351b9464cbd750335a79650a0ec0e56118dd" + integrity sha512-Pn9cox5CsMYngeDbmChANltQl+5pi6XmTrraMSzhPmMBbmgcxmqWry0U3PGapCU1yB4/LqCcom7qhHZiF/jGfQ== + +ltgt@~2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ltgt/-/ltgt-2.2.1.tgz#f35ca91c493f7b73da0e07495304f17b31f87ee5" + integrity sha512-AI2r85+4MquTw9ZYqabu4nMwy9Oftlfa/e/52t9IjtfG+mGBbTNdAoZ3RQKLHR6r0wQnwZnPIEh/Ya6XTWAKNA== + +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== + +markdown-table@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/markdown-table/-/markdown-table-1.1.3.tgz#9fcb69bcfdb8717bfd0398c6ec2d93036ef8de60" + integrity sha512-1RUZVgQlpJSPWYbFSpmudq5nHY1doEIv89gBtF0s4gW1GF2XorxcA/70M5vq7rLv0a6mhOUccRsqkwhwLCIQ2Q== + +match-all@^1.2.6: + version "1.2.6" + resolved "https://registry.yarnpkg.com/match-all/-/match-all-1.2.6.tgz#66d276ad6b49655551e63d3a6ee53e8be0566f8d" + integrity sha512-0EESkXiTkWzrQQntBu2uzKvLu6vVkUGz40nGPbSZuegcfE5UuSzNjLaIu76zJWuaT/2I3Z/8M06OlUOZLGwLlQ== + +mcl-wasm@^0.7.1: + version "0.7.9" + resolved "https://registry.yarnpkg.com/mcl-wasm/-/mcl-wasm-0.7.9.tgz#c1588ce90042a8700c3b60e40efb339fc07ab87f" + integrity sha512-iJIUcQWA88IJB/5L15GnJVnSQJmf/YaxxV6zRavv83HILHaJQb6y0iFyDMdDO0gN8X37tdxmAOrH/P8B6RB8sQ== + +md5.js@^1.3.4: + version "1.3.5" + resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" + integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== + +memdown@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/memdown/-/memdown-5.1.0.tgz#608e91a9f10f37f5b5fe767667a8674129a833cb" + integrity sha512-B3J+UizMRAlEArDjWHTMmadet+UKwHd3UjMgGBkZcKAxAYVPS9o0Yeiha4qvz7iGiL2Sb3igUft6p7nbFWctpw== + dependencies: + abstract-leveldown "~6.2.1" + functional-red-black-tree "~1.0.1" + immediate "~3.2.3" + inherits "~2.0.1" + ltgt "~2.2.0" + safe-buffer "~5.2.0" + +memory-level@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/memory-level/-/memory-level-1.0.0.tgz#7323c3fd368f9af2f71c3cd76ba403a17ac41692" + integrity sha512-UXzwewuWeHBz5krr7EvehKcmLFNoXxGcvuYhC41tRnkrTbJohtS7kVn9akmgirtRygg+f7Yjsfi8Uu5SGSQ4Og== + dependencies: + abstract-level "^1.0.0" + functional-red-black-tree "^1.0.1" + module-error "^1.0.1" + +memorystream@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/memorystream/-/memorystream-0.3.1.tgz#86d7090b30ce455d63fbae12dda51a47ddcaf9b2" + integrity sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw== + +merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w== + +merge2@^1.2.3, merge2@^1.3.0, merge2@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== + +merkle-patricia-tree@^4.2.2, merkle-patricia-tree@^4.2.4: + version "4.2.4" + resolved "https://registry.yarnpkg.com/merkle-patricia-tree/-/merkle-patricia-tree-4.2.4.tgz#ff988d045e2bf3dfa2239f7fabe2d59618d57413" + integrity sha512-eHbf/BG6eGNsqqfbLED9rIqbsF4+sykEaBn6OLNs71tjclbMcMOk1tEPmJKcNcNCLkvbpY/lwyOlizWsqPNo8w== + dependencies: + "@types/levelup" "^4.3.0" + ethereumjs-util "^7.1.4" + level-mem "^5.0.1" + level-ws "^2.0.0" + readable-stream "^3.6.0" + semaphore-async-await "^1.5.1" + +methods@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== + +micro-ftch@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/micro-ftch/-/micro-ftch-0.3.1.tgz#6cb83388de4c1f279a034fb0cf96dfc050853c5f" + integrity sha512-/0LLxhzP0tfiR5hcQebtudP56gUurs2CLkGarnCiB/OqEyUFQ6U3paQi/tgLv0hBJYt2rnr9MNpxz4fiiugstg== + +micromatch@^4.0.4: + version "4.0.5" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" + integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== + dependencies: + braces "^3.0.2" + picomatch "^2.3.1" + +miller-rabin@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" + integrity sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA== + dependencies: + bn.js "^4.0.0" + brorand "^1.0.1" + +mime-db@1.52.0: + version "1.52.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + +mime-types@^2.1.12, mime-types@^2.1.16, mime-types@~2.1.19, mime-types@~2.1.24, mime-types@~2.1.34: + version "2.1.35" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== + dependencies: + mime-db "1.52.0" + +mime@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + +mimic-response@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" + integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== + +mimic-response@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9" + integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== + +min-document@^2.19.0: + version "2.19.0" + resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685" + integrity sha512-9Wy1B3m3f66bPPmU5hdA4DR4PB2OfDU/+GS3yAB7IQozE3tqXaVv2zOjgla7MEGSRv95+ILmOuvhLkOK6wJtCQ== + dependencies: + dom-walk "^0.1.0" + +minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== + +minimalistic-crypto-utils@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" + integrity sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg== + +"minimatch@2 || 3", minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +minimatch@5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.0.1.tgz#fb9022f7528125187c92bd9e9b6366be1cf3415b" + integrity sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g== + dependencies: + brace-expansion "^2.0.1" + +minimatch@^5.0.1: + version "5.1.6" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96" + integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g== + dependencies: + brace-expansion "^2.0.1" + +minimist@^1.2.0, minimist@^1.2.5, minimist@^1.2.6: + version "1.2.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" + integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== + +minipass@^2.6.0, minipass@^2.9.0: + version "2.9.0" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.9.0.tgz#e713762e7d3e32fed803115cf93e04bca9fcc9a6" + integrity sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg== + dependencies: + safe-buffer "^5.1.2" + yallist "^3.0.0" + +minizlib@^1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.3.3.tgz#2290de96818a34c29551c8a8d301216bd65a861d" + integrity sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q== + dependencies: + minipass "^2.9.0" + +mkdirp-promise@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/mkdirp-promise/-/mkdirp-promise-5.0.1.tgz#e9b8f68e552c68a9c1713b84883f7a1dd039b8a1" + integrity sha512-Hepn5kb1lJPtVW84RFT40YG1OddBNTOVUZR2bzQUHc+Z03en8/3uX0+060JDhcEzyO08HmipsN9DcnFMxhIL9w== + dependencies: + mkdirp "*" + +mkdirp@*: + version "3.0.1" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-3.0.1.tgz#e44e4c5607fb279c168241713cc6e0fea9adcb50" + integrity sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg== + +mkdirp@0.5.x, mkdirp@^0.5.1, mkdirp@^0.5.5: + version "0.5.6" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" + integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== + dependencies: + minimist "^1.2.6" + +mkdirp@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" + integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== + +mnemonist@^0.38.0: + version "0.38.5" + resolved "https://registry.yarnpkg.com/mnemonist/-/mnemonist-0.38.5.tgz#4adc7f4200491237fe0fa689ac0b86539685cade" + integrity sha512-bZTFT5rrPKtPJxj8KSV0WkPyNxl72vQepqqVUAW2ARUpUSF2qXMB6jZj7hW5/k7C1rtpzqbD/IIbJwLXUjCHeg== + dependencies: + obliterator "^2.0.0" + +mocha@10.2.0, mocha@^10.0.0, mocha@^10.2.0: + version "10.2.0" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.2.0.tgz#1fd4a7c32ba5ac372e03a17eef435bd00e5c68b8" + integrity sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg== + dependencies: + ansi-colors "4.1.1" + browser-stdout "1.3.1" + chokidar "3.5.3" + debug "4.3.4" + diff "5.0.0" + escape-string-regexp "4.0.0" + find-up "5.0.0" + glob "7.2.0" + he "1.2.0" + js-yaml "4.1.0" + log-symbols "4.1.0" + minimatch "5.0.1" + ms "2.1.3" + nanoid "3.3.3" + serialize-javascript "6.0.0" + strip-json-comments "3.1.1" + supports-color "8.1.1" + workerpool "6.2.1" + yargs "16.2.0" + yargs-parser "20.2.4" + yargs-unparser "2.0.0" + +mock-fs@^4.1.0: + version "4.14.0" + resolved "https://registry.yarnpkg.com/mock-fs/-/mock-fs-4.14.0.tgz#ce5124d2c601421255985e6e94da80a7357b1b18" + integrity sha512-qYvlv/exQ4+svI3UOvPUpLDF0OMX5euvUH0Ny4N5QyRyhNdgAgUrVH3iUINSzEPLvx0kbo/Bp28GJKIqvE7URw== + +module-error@^1.0.1, module-error@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/module-error/-/module-error-1.0.2.tgz#8d1a48897ca883f47a45816d4fb3e3c6ba404d86" + integrity sha512-0yuvsqSCv8LbaOKhnsQ/T5JhyFlCYLPXK3U2sgV10zoKQwzs/MyfuQUOZQ1V/6OCOJsK/TRgNVrPuPDqtdMFtA== + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +ms@2.1.3, ms@^2.1.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +multibase@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/multibase/-/multibase-0.7.0.tgz#1adfc1c50abe05eefeb5091ac0c2728d6b84581b" + integrity sha512-TW8q03O0f6PNFTQDvh3xxH03c8CjGaaYrjkl9UQPG6rz53TQzzxJVCIWVjzcbN/Q5Y53Zd0IBQBMVktVgNx4Fg== + dependencies: + base-x "^3.0.8" + buffer "^5.5.0" + +multibase@~0.6.0: + version "0.6.1" + resolved "https://registry.yarnpkg.com/multibase/-/multibase-0.6.1.tgz#b76df6298536cc17b9f6a6db53ec88f85f8cc12b" + integrity sha512-pFfAwyTjbbQgNc3G7D48JkJxWtoJoBMaR4xQUOuB8RnCgRqaYmWNFeJTTvrJ2w51bjLq2zTby6Rqj9TQ9elSUw== + dependencies: + base-x "^3.0.8" + buffer "^5.5.0" + +multicodec@^0.5.5: + version "0.5.7" + resolved "https://registry.yarnpkg.com/multicodec/-/multicodec-0.5.7.tgz#1fb3f9dd866a10a55d226e194abba2dcc1ee9ffd" + integrity sha512-PscoRxm3f+88fAtELwUnZxGDkduE2HD9Q6GHUOywQLjOGT/HAdhjLDYNZ1e7VR0s0TP0EwZ16LNUTFpoBGivOA== + dependencies: + varint "^5.0.0" + +multicodec@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/multicodec/-/multicodec-1.0.4.tgz#46ac064657c40380c28367c90304d8ed175a714f" + integrity sha512-NDd7FeS3QamVtbgfvu5h7fd1IlbaC4EQ0/pgU4zqE2vdHCmBGsUa0TiM8/TdSeG6BMPC92OOCf8F1ocE/Wkrrg== + dependencies: + buffer "^5.6.0" + varint "^5.0.0" + +multihashes@^0.4.15, multihashes@~0.4.15: + version "0.4.21" + resolved "https://registry.yarnpkg.com/multihashes/-/multihashes-0.4.21.tgz#dc02d525579f334a7909ade8a122dabb58ccfcb5" + integrity sha512-uVSvmeCWf36pU2nB4/1kzYZjsXD9vofZKpgudqkceYY5g2aZZXJ5r9lxuzoRLl1OAp28XljXsEJ/X/85ZsKmKw== + dependencies: + buffer "^5.5.0" + multibase "^0.7.0" + varint "^5.0.0" + +murmur-128@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/murmur-128/-/murmur-128-0.2.1.tgz#a9f6568781d2350ecb1bf80c14968cadbeaa4b4d" + integrity sha512-WseEgiRkI6aMFBbj8Cg9yBj/y+OdipwVC7zUo3W2W1JAJITwouUOtpqsmGSg67EQmwwSyod7hsVsWY5LsrfQVg== + dependencies: + encode-utf8 "^1.0.2" + fmix "^0.1.0" + imul "^1.0.0" + +nano-base32@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/nano-base32/-/nano-base32-1.0.1.tgz#ba548c879efcfb90da1c4d9e097db4a46c9255ef" + integrity sha512-sxEtoTqAPdjWVGv71Q17koMFGsOMSiHsIFEvzOM7cNp8BXB4AnEwmDabm5dorusJf/v1z7QxaZYxUorU9RKaAw== + +nano-json-stream-parser@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/nano-json-stream-parser/-/nano-json-stream-parser-0.1.2.tgz#0cc8f6d0e2b622b479c40d499c46d64b755c6f5f" + integrity sha512-9MqxMH/BSJC7dnLsEMPyfN5Dvoo49IsPFYMcHw3Bcfc2kN0lpHRBSzlMSVx4HGyJ7s9B31CyBTVehWJoQ8Ctew== + +nanoid@3.3.3: + version "3.3.3" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.3.tgz#fd8e8b7aa761fe807dba2d1b98fb7241bb724a25" + integrity sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w== + +napi-macros@^2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/napi-macros/-/napi-macros-2.2.2.tgz#817fef20c3e0e40a963fbf7b37d1600bd0201044" + integrity sha512-hmEVtAGYzVQpCKdbQea4skABsdXW4RUh5t5mJ2zzqowJS2OyXZTU1KhDVFhx+NlWZ4ap9mqR9TcDO3LTTttd+g== + +napi-macros@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/napi-macros/-/napi-macros-2.0.0.tgz#2b6bae421e7b96eb687aa6c77a7858640670001b" + integrity sha512-A0xLykHtARfueITVDernsAWdtIMbOJgKgcluwENp3AlsKN/PloyO10HtmoqnFAQAcxPkgZN7wdfPfEd0zNGxbg== + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== + +negotiator@0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" + integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== + +neo-async@^2.6.2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" + integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== + +next-tick@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.1.0.tgz#1836ee30ad56d67ef281b22bd199f709449b35eb" + integrity sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ== + +no-case@^2.2.0, no-case@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/no-case/-/no-case-2.3.2.tgz#60b813396be39b3f1288a4c1ed5d1e7d28b464ac" + integrity sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ== + dependencies: + lower-case "^1.1.1" + +node-addon-api@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-2.0.2.tgz#432cfa82962ce494b132e9d72a15b29f71ff5d32" + integrity sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA== + +node-emoji@^1.10.0: + version "1.11.0" + resolved "https://registry.yarnpkg.com/node-emoji/-/node-emoji-1.11.0.tgz#69a0150e6946e2f115e9d7ea4df7971e2628301c" + integrity sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A== + dependencies: + lodash "^4.17.21" + +node-fetch@^2.6.12, node-fetch@^2.6.7: + version "2.7.0" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" + integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== + dependencies: + whatwg-url "^5.0.0" + +node-gyp-build@4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.3.0.tgz#9f256b03e5826150be39c764bf51e993946d71a3" + integrity sha512-iWjXZvmboq0ja1pUGULQBexmxq8CV4xBhX7VDOTbL7ZR4FOowwY/VOtRxBN/yKxmdGoIp4j5ysNT4u3S2pDQ3Q== + +node-gyp-build@4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.4.0.tgz#42e99687ce87ddeaf3a10b99dc06abc11021f3f4" + integrity sha512-amJnQCcgtRVw9SvoebO3BKGESClrfXGCUTX9hSn1OuGQTQBOZmVd0Z0OlecpuRksKvbsUqALE8jls/ErClAPuQ== + +node-gyp-build@^4.2.0, node-gyp-build@^4.3.0: + version "4.6.1" + resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.6.1.tgz#24b6d075e5e391b8d5539d98c7fc5c210cac8a3e" + integrity sha512-24vnklJmyRS8ViBNI8KbtK/r/DmXQMRiOMXTNz2nrTnAYUwjmEEbnnpB/+kt+yWRv73bPsSPRFddrcIbAxSiMQ== + +nofilter@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/nofilter/-/nofilter-1.0.4.tgz#78d6f4b6a613e7ced8b015cec534625f7667006e" + integrity sha512-N8lidFp+fCz+TD51+haYdbDGrcBWwuHX40F5+z0qkUjMJ5Tp+rdSuAkMJ9N9eoolDlEVTf6u5icM+cNKkKW2mA== + +nofilter@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/nofilter/-/nofilter-3.1.0.tgz#c757ba68801d41ff930ba2ec55bab52ca184aa66" + integrity sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g== + +nopt@3.x: + version "3.0.6" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" + integrity sha512-4GUt3kSEYmk4ITxzB/b9vaIDfUVWN/Ml1Fwl11IlnIG2iaJ9O6WXZ9SrYM9NLI8OCBieN2Y8SWC2oJV0RQ7qYg== + dependencies: + abbrev "1" + +normalize-package-data@^2.3.2: + version "2.5.0" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" + integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== + dependencies: + hosted-git-info "^2.1.4" + resolve "^1.10.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + +normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +normalize-url@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a" + integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A== + +nth-check@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.1.1.tgz#c9eab428effce36cd6b92c924bdb000ef1f1ed1d" + integrity sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w== + dependencies: + boolbase "^1.0.0" + +number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + integrity sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ== + +number-to-bn@1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/number-to-bn/-/number-to-bn-1.7.0.tgz#bb3623592f7e5f9e0030b1977bd41a0c53fe1ea0" + integrity sha512-wsJ9gfSz1/s4ZsJN01lyonwuxA1tml6X1yBDnfpMglypcBRFZZkus26EdPSlqS5GJfYddVZa22p3VNb3z5m5Ig== + dependencies: + bn.js "4.11.6" + strip-hex-prefix "1.0.0" + +oauth-sign@~0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" + integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== + +object-assign@^4, object-assign@^4.1.0, object-assign@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== + +object-inspect@^1.13.1, object-inspect@^1.9.0: + version "1.13.1" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.1.tgz#b96c6109324ccfef6b12216a956ca4dc2ff94bc2" + integrity sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ== + +object-keys@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== + +object.assign@^4.1.4: + version "4.1.4" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.4.tgz#9673c7c7c351ab8c4d0b516f4343ebf4dfb7799f" + integrity sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + has-symbols "^1.0.3" + object-keys "^1.1.1" + +object.fromentries@^2.0.7: + version "2.0.7" + resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.7.tgz#71e95f441e9a0ea6baf682ecaaf37fa2a8d7e616" + integrity sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + +object.groupby@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object.groupby/-/object.groupby-1.0.1.tgz#d41d9f3c8d6c778d9cbac86b4ee9f5af103152ee" + integrity sha512-HqaQtqLnp/8Bn4GL16cj+CUYbnpe1bh0TtEaWvybszDG4tgxCJuRpV8VGuvNaI1fAnI4lUJzDG55MXcOH4JZcQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + get-intrinsic "^1.2.1" + +object.values@^1.1.7: + version "1.1.7" + resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.7.tgz#617ed13272e7e1071b43973aa1655d9291b8442a" + integrity sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + +obliterator@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/obliterator/-/obliterator-2.0.4.tgz#fa650e019b2d075d745e44f1effeb13a2adbe816" + integrity sha512-lgHwxlxV1qIg1Eap7LgIeoBWIMFibOjbrYPIPJZcI1mmGAI2m3lNYpK12Y+GBdPQ0U1hRwSord7GIaawz962qQ== + +oboe@2.1.5: + version "2.1.5" + resolved "https://registry.yarnpkg.com/oboe/-/oboe-2.1.5.tgz#5554284c543a2266d7a38f17e073821fbde393cd" + integrity sha512-zRFWiF+FoicxEs3jNI/WYUrVEgA7DeET/InK0XQuudGHRg8iIob3cNPrJTKaz4004uaA9Pbe+Dwa8iluhjLZWA== + dependencies: + http-https "^1.0.0" + +on-finished@2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" + integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== + dependencies: + ee-first "1.1.1" + +once@1.x, once@^1.3.0, once@^1.3.1, once@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== + dependencies: + wrappy "1" + +optionator@^0.8.1: + version "0.8.3" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" + integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== + dependencies: + deep-is "~0.1.3" + fast-levenshtein "~2.0.6" + levn "~0.3.0" + prelude-ls "~1.1.2" + type-check "~0.3.2" + word-wrap "~1.2.3" + +optionator@^0.9.1: + version "0.9.3" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.3.tgz#007397d44ed1872fdc6ed31360190f81814e2c64" + integrity sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg== + dependencies: + "@aashutoshrathi/word-wrap" "^1.2.3" + deep-is "^0.1.3" + fast-levenshtein "^2.0.6" + levn "^0.4.1" + prelude-ls "^1.2.1" + type-check "^0.4.0" + +os-locale@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-1.4.0.tgz#20f9f17ae29ed345e8bde583b13d2009803c14d9" + integrity sha512-PRT7ZORmwu2MEFt4/fv3Q+mEfN4zetKxufQrkShY2oGvUms9r8otu5HfdyIFHkYXjO7laNsoVGmM2MANfuTA8g== + dependencies: + lcid "^1.0.0" + +os-tmpdir@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + integrity sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g== + +p-cancelable@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-2.1.1.tgz#aab7fbd416582fa32a3db49859c122487c5ed2cf" + integrity sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg== + +p-cancelable@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-3.0.0.tgz#63826694b54d61ca1c20ebcb6d3ecf5e14cd8050" + integrity sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw== + +p-limit@^1.1.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" + integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== + dependencies: + p-try "^1.0.0" + +p-limit@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== + dependencies: + yocto-queue "^0.1.0" + +p-locate@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" + integrity sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg== + dependencies: + p-limit "^1.1.0" + +p-locate@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== + dependencies: + p-limit "^3.0.2" + +p-map@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b" + integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== + dependencies: + aggregate-error "^3.0.0" + +p-try@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" + integrity sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww== + +pako@^1.0.4: + version "1.0.11" + resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" + integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw== + +param-case@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/param-case/-/param-case-2.1.1.tgz#df94fd8cf6531ecf75e6bef9a0858fbc72be2247" + integrity sha512-eQE845L6ot89sk2N8liD8HAuH4ca6Vvr7VWAWwt7+kvvG5aBcPmmphQ68JsEG2qa9n1TykS2DLeMt363AAH8/w== + dependencies: + no-case "^2.2.0" + +parent-module@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== + dependencies: + callsites "^3.0.0" + +parse-cache-control@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parse-cache-control/-/parse-cache-control-1.0.1.tgz#8eeab3e54fa56920fe16ba38f77fa21aacc2d74e" + integrity sha512-60zvsJReQPX5/QP0Kzfd/VrpjScIQ7SHBW6bFCYfEP+fp0Eppr1SHhIO5nd1PjZtvclzSzES9D/p5nFJurwfWg== + +parse-headers@^2.0.0: + version "2.0.5" + resolved "https://registry.yarnpkg.com/parse-headers/-/parse-headers-2.0.5.tgz#069793f9356a54008571eb7f9761153e6c770da9" + integrity sha512-ft3iAoLOB/MlwbNXgzy43SWGP6sQki2jQvAyBg/zDFAgr9bfNWZIUj42Kw2eJIl8kEi4PbgE6U1Zau/HwI75HA== + +parse-json@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" + integrity sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ== + dependencies: + error-ex "^1.2.0" + +parse-json@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" + integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== + dependencies: + "@babel/code-frame" "^7.0.0" + error-ex "^1.3.1" + json-parse-even-better-errors "^2.3.0" + lines-and-columns "^1.1.6" + +parse5-htmlparser2-tree-adapter@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz#23c2cc233bcf09bb7beba8b8a69d46b08c62c2f1" + integrity sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g== + dependencies: + domhandler "^5.0.2" + parse5 "^7.0.0" + +parse5@^7.0.0: + version "7.1.2" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-7.1.2.tgz#0736bebbfd77793823240a23b7fc5e010b7f8e32" + integrity sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw== + dependencies: + entities "^4.4.0" + +parseurl@~1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" + integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== + +pascal-case@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pascal-case/-/pascal-case-2.0.1.tgz#2d578d3455f660da65eca18ef95b4e0de912761e" + integrity sha512-qjS4s8rBOJa2Xm0jmxXiyh1+OFf6ekCWOvUaRgAQSktzlTbMotS0nmG9gyYAybCWBcuP4fsBeRCKNwGBnMe2OQ== + dependencies: + camel-case "^3.0.0" + upper-case-first "^1.1.0" + +path-browserify@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-1.0.1.tgz#d98454a9c3753d5790860f16f68867b9e46be1fd" + integrity sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g== + +path-case@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/path-case/-/path-case-2.1.1.tgz#94b8037c372d3fe2906e465bb45e25d226e8eea5" + integrity sha512-Ou0N05MioItesaLr9q8TtHVWmJ6fxWdqKB2RohFmNWVyJ+2zeKIeDNWAN6B/Pe7wpzWChhZX6nONYmOnMeJQ/Q== + dependencies: + no-case "^2.2.0" + +path-exists@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" + integrity sha512-yTltuKuhtNeFJKa1PiRzfLAU5182q1y4Eb4XCJ3PBqyzEDkAZRzBrKKBct682ls9reBVHf9udYLN5Nd+K1B9BQ== + dependencies: + pinkie-promise "^2.0.0" + +path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + integrity sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ== + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== + +path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-parse@^1.0.6, path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ== + +path-type@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" + integrity sha512-S4eENJz1pkiQn9Znv33Q+deTOKmbl+jj1Fl+qiP/vYezj+S8x+J3Uo0ISrx/QoEvIlOaDWJhPaRd1flJ9HXZqg== + dependencies: + graceful-fs "^4.1.2" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +path-type@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== + +pathval@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.1.tgz#8534e77a77ce7ac5a2512ea21e0fdb8fcf6c3d8d" + integrity sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ== + +pbkdf2@^3.0.17, pbkdf2@^3.0.9: + version "3.1.2" + resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.2.tgz#dd822aa0887580e52f1a039dc3eda108efae3075" + integrity sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA== + dependencies: + create-hash "^1.1.2" + create-hmac "^1.1.4" + ripemd160 "^2.0.1" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +performance-now@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + integrity sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow== + +picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +pify@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + integrity sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog== + +pify@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" + integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== + +pinkie-promise@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + integrity sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw== + dependencies: + pinkie "^2.0.0" + +pinkie@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + integrity sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg== + +pinst@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pinst/-/pinst-3.0.0.tgz#80dec0a85f1f993c6084172020f3dbf512897eec" + integrity sha512-cengSmBxtCyaJqtRSvJorIIZXMXg+lJ3sIljGmtBGUVonMnMsVJbnzl6jGN1HkOWwxNuJynCJ2hXxxqCQrFDdw== + +pluralize@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-8.0.0.tgz#1a6fa16a38d12a1901e0320fa017051c539ce3b1" + integrity sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA== + +prelude-ls@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" + integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== + +prelude-ls@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" + integrity sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w== + +prettier-linter-helpers@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b" + integrity sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w== + dependencies: + fast-diff "^1.1.2" + +prettier-plugin-solidity@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/prettier-plugin-solidity/-/prettier-plugin-solidity-1.1.3.tgz#9a35124f578404caf617634a8cab80862d726cba" + integrity sha512-fQ9yucPi2sBbA2U2Xjh6m4isUTJ7S7QLc/XDDsktqqxYfTwdYKJ0EnnywXHwCGAaYbQNK+HIYPL1OemxuMsgeg== + dependencies: + "@solidity-parser/parser" "^0.16.0" + semver "^7.3.8" + solidity-comments-extractor "^0.0.7" + +prettier@^2.3.1, prettier@^2.6.2, prettier@^2.8.3: + version "2.8.8" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da" + integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q== + +process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + +process@^0.11.10: + version "0.11.10" + resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" + integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A== + +progress@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" + integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== + +promise@^8.0.0: + version "8.3.0" + resolved "https://registry.yarnpkg.com/promise/-/promise-8.3.0.tgz#8cb333d1edeb61ef23869fbb8a4ea0279ab60e0a" + integrity sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg== + dependencies: + asap "~2.0.6" + +proxy-addr@~2.0.7: + version "2.0.7" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" + integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== + dependencies: + forwarded "0.2.0" + ipaddr.js "1.9.1" + +proxy-from-env@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" + integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== + +prr@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" + integrity sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw== + +psl@^1.1.28: + version "1.9.0" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7" + integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag== + +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +punycode@2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.0.tgz#5f863edc89b96db09074bad7947bf09056ca4e7d" + integrity sha512-Yxz2kRwT90aPiWEMHVYnEf4+rhwF1tBmmZ4KepCP+Wkium9JxtWnUm1nqGwpiAHr/tnTSeHqr3wb++jgSkXjhA== + +punycode@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + integrity sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ== + +punycode@^2.1.0, punycode@^2.1.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" + integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== + +pure-rand@^5.0.1: + version "5.0.5" + resolved "https://registry.yarnpkg.com/pure-rand/-/pure-rand-5.0.5.tgz#bda2a7f6a1fc0f284d78d78ca5902f26f2ad35cf" + integrity sha512-BwQpbqxSCBJVpamI6ydzcKqyFmnd5msMWUGvzXLm1aXvusbbgkbOto/EUPM00hjveJEaJtdbhUjKSzWRhQVkaw== + +qs@6.11.0: + version "6.11.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a" + integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q== + dependencies: + side-channel "^1.0.4" + +qs@^6.11.2, qs@^6.4.0, qs@^6.9.4: + version "6.11.2" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.2.tgz#64bea51f12c1f5da1bc01496f48ffcff7c69d7d9" + integrity sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA== + dependencies: + side-channel "^1.0.4" + +qs@~6.5.2: + version "6.5.3" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.3.tgz#3aeeffc91967ef6e35c0e488ef46fb296ab76aad" + integrity sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA== + +query-string@^5.0.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/query-string/-/query-string-5.1.1.tgz#a78c012b71c17e05f2e3fa2319dd330682efb3cb" + integrity sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw== + dependencies: + decode-uri-component "^0.2.0" + object-assign "^4.1.0" + strict-uri-encode "^1.0.0" + +queue-microtask@^1.2.2, queue-microtask@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== + +quick-lru@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932" + integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA== + +randombytes@^2.0.1, randombytes@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + +range-parser@~1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== + +raw-body@2.5.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.1.tgz#fe1b1628b181b700215e5fd42389f98b71392857" + integrity sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig== + dependencies: + bytes "3.1.2" + http-errors "2.0.0" + iconv-lite "0.4.24" + unpipe "1.0.0" + +raw-body@2.5.2, raw-body@^2.4.1: + version "2.5.2" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.2.tgz#99febd83b90e08975087e8f1f9419a149366b68a" + integrity sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA== + dependencies: + bytes "3.1.2" + http-errors "2.0.0" + iconv-lite "0.4.24" + unpipe "1.0.0" + +read-pkg-up@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" + integrity sha512-WD9MTlNtI55IwYUS27iHh9tK3YoIVhxis8yKhLpTqWtml739uXc9NWTpxoHkfZf3+DkCCsXox94/VWZniuZm6A== + dependencies: + find-up "^1.0.0" + read-pkg "^1.0.0" + +read-pkg@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" + integrity sha512-7BGwRHqt4s/uVbuyoeejRn4YmFnYZiFl4AuaeXHlgZf3sONF0SOGlxs2Pw8g6hCKupo08RafIO5YXFNOKTfwsQ== + dependencies: + load-json-file "^1.0.0" + normalize-package-data "^2.3.2" + path-type "^1.0.0" + +readable-stream@^2.2.2: + version "2.3.8" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b" + integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +readable-stream@^3.1.0, readable-stream@^3.4.0, readable-stream@^3.6.0: + version "3.6.2" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" + integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== + dependencies: + picomatch "^2.2.1" + +rechoir@^0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" + integrity sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw== + dependencies: + resolve "^1.1.6" + +recursive-readdir@^2.2.2: + version "2.2.3" + resolved "https://registry.yarnpkg.com/recursive-readdir/-/recursive-readdir-2.2.3.tgz#e726f328c0d69153bcabd5c322d3195252379372" + integrity sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA== + dependencies: + minimatch "^3.0.5" + +reduce-flatten@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/reduce-flatten/-/reduce-flatten-2.0.0.tgz#734fd84e65f375d7ca4465c69798c25c9d10ae27" + integrity sha512-EJ4UNY/U1t2P/2k6oqotuX2Cc3T6nxJwsM0N0asT7dhrtH1ltUxDn4NalSYmPE2rCkVpcf/X6R0wDwcFpzhd4w== + +regenerator-runtime@^0.14.0: + version "0.14.0" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz#5e19d68eb12d486f797e15a3c6a918f7cec5eb45" + integrity sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA== + +regexp.prototype.flags@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz#90ce989138db209f81492edd734183ce99f9677e" + integrity sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + set-function-name "^2.0.0" + +regexpp@^3.0.0, regexpp@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" + integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== + +req-cwd@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/req-cwd/-/req-cwd-2.0.0.tgz#d4082b4d44598036640fb73ddea01ed53db49ebc" + integrity sha512-ueoIoLo1OfB6b05COxAA9UpeoscNpYyM+BqYlA7H6LVF4hKGPXQQSSaD2YmvDVJMkk4UDpAHIeU1zG53IqjvlQ== + dependencies: + req-from "^2.0.0" + +req-from@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/req-from/-/req-from-2.0.0.tgz#d74188e47f93796f4aa71df6ee35ae689f3e0e70" + integrity sha512-LzTfEVDVQHBRfjOUMgNBA+V6DWsSnoeKzf42J7l0xa/B4jyPOuuF5MlNSmomLNGemWTnV2TIdjSSLnEn95fOQA== + dependencies: + resolve-from "^3.0.0" + +request@^2.79.0, request@^2.85.0: + version "2.88.2" + resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" + integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== + dependencies: + aws-sign2 "~0.7.0" + aws4 "^1.8.0" + caseless "~0.12.0" + combined-stream "~1.0.6" + extend "~3.0.2" + forever-agent "~0.6.1" + form-data "~2.3.2" + har-validator "~5.1.3" + http-signature "~1.2.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.19" + oauth-sign "~0.9.0" + performance-now "^2.1.0" + qs "~6.5.2" + safe-buffer "^5.1.2" + tough-cookie "~2.5.0" + tunnel-agent "^0.6.0" + uuid "^3.3.2" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== + +require-from-string@^1.1.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-1.2.1.tgz#529c9ccef27380adfec9a2f965b649bbee636418" + integrity sha512-H7AkJWMobeskkttHyhTVtS0fxpFLjxhbfMa6Bk3wimP7sdPRGL3EyCg3sAQenFfAe+xQ+oAc85Nmtvq0ROM83Q== + +require-from-string@^2.0.0, require-from-string@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" + integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== + +require-main-filename@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" + integrity sha512-IqSUtOVP4ksd1C/ej5zeEh/BIP2ajqpn8c5x+q99gvcIG/Qf0cud5raVnE/Dwd0ua9TXYDoDc0RE5hBSdz22Ug== + +resolve-alpn@^1.0.0, resolve-alpn@^1.2.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/resolve-alpn/-/resolve-alpn-1.2.1.tgz#b7adbdac3546aaaec20b45e7d8265927072726f9" + integrity sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g== + +resolve-from@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" + integrity sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw== + +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + +resolve@1.1.x: + version "1.1.7" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" + integrity sha512-9znBF0vBcaSN3W2j7wKvdERPwqTxSpCq+if5C0WoTCyV9n24rua28jeuQ2pL/HOf+yUe/Mef+H/5p60K0Id3bg== + +resolve@1.17.0: + version "1.17.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.17.0.tgz#b25941b54968231cc2d1bb76a79cb7f2c0bf8444" + integrity sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w== + dependencies: + path-parse "^1.0.6" + +resolve@^1.1.6, resolve@^1.10.0, resolve@^1.10.1, resolve@^1.22.4: + version "1.22.8" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d" + integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== + dependencies: + is-core-module "^2.13.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + +responselike@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/responselike/-/responselike-2.0.1.tgz#9a0bc8fdc252f3fb1cca68b016591059ba1422bc" + integrity sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw== + dependencies: + lowercase-keys "^2.0.0" + +reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + +rimraf@^2.2.8: + version "2.7.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" + integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== + dependencies: + glob "^7.1.3" + +rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + +ripemd160-min@0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/ripemd160-min/-/ripemd160-min-0.0.6.tgz#a904b77658114474d02503e819dcc55853b67e62" + integrity sha512-+GcJgQivhs6S9qvLogusiTcS9kQUfgR75whKuy5jIhuiOfQuJ8fjqxV6EGD5duH1Y/FawFUMtMhyeq3Fbnib8A== + +ripemd160@^2.0.0, ripemd160@^2.0.1, ripemd160@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" + integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + +rlp@2.2.6: + version "2.2.6" + resolved "https://registry.yarnpkg.com/rlp/-/rlp-2.2.6.tgz#c80ba6266ac7a483ef1e69e8e2f056656de2fb2c" + integrity sha512-HAfAmL6SDYNWPUOJNrM500x4Thn4PZsEy5pijPh40U9WfNk0z15hUYzO9xVIMAdIHdFtD8CBDHd75Td1g36Mjg== + dependencies: + bn.js "^4.11.1" + +rlp@^2.2.3, rlp@^2.2.4: + version "2.2.7" + resolved "https://registry.yarnpkg.com/rlp/-/rlp-2.2.7.tgz#33f31c4afac81124ac4b283e2bd4d9720b30beaf" + integrity sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ== + dependencies: + bn.js "^5.2.0" + +router-intents@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/router-intents/-/router-intents-4.0.1.tgz#fe138e21b72aa53f03ca35f9b7833380c4852b65" + integrity sha512-49XdSQUdAOdYCoChZIvENj43OjhDdRD6YWkIz/6+0m4xHv2NlgFSqQ4seNVc29G4RI5qX0zl8IPW81HOsQe1/w== + dependencies: + "@ethersproject/abstract-signer" "^5.6.2" + "@ethersproject/constants" "^5.6.1" + axios "^1.5.0" + ethereumjs-util "^7.1.0" + +run-parallel-limit@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/run-parallel-limit/-/run-parallel-limit-1.1.0.tgz#be80e936f5768623a38a963262d6bef8ff11e7ba" + integrity sha512-jJA7irRNM91jaKc3Hcl1npHsFLOXOoTkPCUL1JEa1R82O2miplXXRaGdjW/KM/98YQWDhJLiSs793CnXfblJUw== + dependencies: + queue-microtask "^1.2.2" + +run-parallel@^1.1.9: + version "1.2.0" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" + integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== + dependencies: + queue-microtask "^1.2.2" + +rustbn.js@~0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/rustbn.js/-/rustbn.js-0.2.0.tgz#8082cb886e707155fd1cb6f23bd591ab8d55d0ca" + integrity sha512-4VlvkRUuCJvr2J6Y0ImW7NvTCriMi7ErOAqWk1y69vAdoNIzCF3yPmgeNzx+RQTLEDFq5sHfscn1MwHxP9hNfA== + +safe-array-concat@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/safe-array-concat/-/safe-array-concat-1.0.1.tgz#91686a63ce3adbea14d61b14c99572a8ff84754c" + integrity sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.2.1" + has-symbols "^1.0.3" + isarray "^2.0.5" + +safe-buffer@5.2.1, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@^5.2.1, safe-buffer@~5.2.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +safe-regex-test@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.0.0.tgz#793b874d524eb3640d1873aad03596db2d4f2295" + integrity sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.3" + is-regex "^1.1.4" + +"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +sc-istanbul@^0.4.5: + version "0.4.6" + resolved "https://registry.yarnpkg.com/sc-istanbul/-/sc-istanbul-0.4.6.tgz#cf6784355ff2076f92d70d59047d71c13703e839" + integrity sha512-qJFF/8tW/zJsbyfh/iT/ZM5QNHE3CXxtLJbZsL+CzdJLBsPD7SedJZoUA4d8iAcN2IoMp/Dx80shOOd2x96X/g== + dependencies: + abbrev "1.0.x" + async "1.x" + escodegen "1.8.x" + esprima "2.7.x" + glob "^5.0.15" + handlebars "^4.0.1" + js-yaml "3.x" + mkdirp "0.5.x" + nopt "3.x" + once "1.x" + resolve "1.1.x" + supports-color "^3.1.0" + which "^1.1.1" + wordwrap "^1.0.0" + +scrypt-js@2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-2.0.4.tgz#32f8c5149f0797672e551c07e230f834b6af5f16" + integrity sha512-4KsaGcPnuhtCZQCxFxN3GVYIhKFPTdLd8PLC552XwbMndtD0cjRFAhDuuydXQ0h08ZfPgzqe6EKHozpuH74iDw== + +scrypt-js@3.0.1, scrypt-js@^3.0.0, scrypt-js@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-3.0.1.tgz#d314a57c2aef69d1ad98a138a21fe9eafa9ee312" + integrity sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA== + +secp256k1@4.0.3, secp256k1@^4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/secp256k1/-/secp256k1-4.0.3.tgz#c4559ecd1b8d3c1827ed2d1b94190d69ce267303" + integrity sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA== + dependencies: + elliptic "^6.5.4" + node-addon-api "^2.0.0" + node-gyp-build "^4.2.0" + +seedrandom@3.0.5: + version "3.0.5" + resolved "https://registry.yarnpkg.com/seedrandom/-/seedrandom-3.0.5.tgz#54edc85c95222525b0c7a6f6b3543d8e0b3aa0a7" + integrity sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg== + +semaphore-async-await@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/semaphore-async-await/-/semaphore-async-await-1.5.1.tgz#857bef5e3644601ca4b9570b87e9df5ca12974fa" + integrity sha512-b/ptP11hETwYWpeilHXXQiV5UJNJl7ZWWooKRE5eBIYWoom6dZ0SluCIdCtKycsMtZgKWE01/qAw6jblw1YVhg== + +"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.5.0: + version "5.7.2" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" + integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== + +semver@^6.1.0, semver@^6.3.0, semver@^6.3.1: + version "6.3.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" + integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== + +semver@^7.2.1, semver@^7.3.4, semver@^7.3.5, semver@^7.3.8, semver@^7.5.2, semver@^7.5.4: + version "7.5.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" + integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== + dependencies: + lru-cache "^6.0.0" + +send@0.18.0: + version "0.18.0" + resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be" + integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg== + dependencies: + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "2.0.0" + mime "1.6.0" + ms "2.1.3" + on-finished "2.4.1" + range-parser "~1.2.1" + statuses "2.0.1" + +sentence-case@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/sentence-case/-/sentence-case-2.1.1.tgz#1f6e2dda39c168bf92d13f86d4a918933f667ed4" + integrity sha512-ENl7cYHaK/Ktwk5OTD+aDbQ3uC8IByu/6Bkg+HDv8Mm+XnBnppVNalcfJTNsp1ibstKh030/JKQQWglDvtKwEQ== + dependencies: + no-case "^2.2.0" + upper-case-first "^1.1.2" + +serialize-javascript@6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" + integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== + dependencies: + randombytes "^2.1.0" + +serve-static@1.15.0: + version "1.15.0" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540" + integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.3" + send "0.18.0" + +servify@^0.1.12: + version "0.1.12" + resolved "https://registry.yarnpkg.com/servify/-/servify-0.1.12.tgz#142ab7bee1f1d033b66d0707086085b17c06db95" + integrity sha512-/xE6GvsKKqyo1BAY+KxOWXcLpPsUUyji7Qg3bVD7hh1eRze5bR1uYiuDA/k3Gof1s9BTzQZEJK8sNcNGFIzeWw== + dependencies: + body-parser "^1.16.0" + cors "^2.8.1" + express "^4.14.0" + request "^2.79.0" + xhr "^2.3.3" + +set-blocking@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== + +set-function-length@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.1.1.tgz#4bc39fafb0307224a33e106a7d35ca1218d659ed" + integrity sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ== + dependencies: + define-data-property "^1.1.1" + get-intrinsic "^1.2.1" + gopd "^1.0.1" + has-property-descriptors "^1.0.0" + +set-function-name@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/set-function-name/-/set-function-name-2.0.1.tgz#12ce38b7954310b9f61faa12701620a0c882793a" + integrity sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA== + dependencies: + define-data-property "^1.0.1" + functions-have-names "^1.2.3" + has-property-descriptors "^1.0.0" + +setimmediate@1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.4.tgz#20e81de622d4a02588ce0c8da8973cbcf1d3138f" + integrity sha512-/TjEmXQVEzdod/FFskf3o7oOAsGhHf2j1dZqRFbDzq4F3mvvxflIIi4Hd3bLQE9y/CpwqfSQam5JakI/mi3Pog== + +setimmediate@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" + integrity sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA== + +setprototypeof@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" + integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== + +sha.js@^2.4.0, sha.js@^2.4.8: + version "2.4.11" + resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" + integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +sha1@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/sha1/-/sha1-1.1.1.tgz#addaa7a93168f393f19eb2b15091618e2700f848" + integrity sha512-dZBS6OrMjtgVkopB1Gmo4RQCDKiZsqcpAQpkV/aaj+FCrCg8r4I4qMkDPQjBgLIxlmu9k4nUbWq6ohXahOneYA== + dependencies: + charenc ">= 0.0.1" + crypt ">= 0.0.1" + +sha3@^2.1.1: + version "2.1.4" + resolved "https://registry.yarnpkg.com/sha3/-/sha3-2.1.4.tgz#000fac0fe7c2feac1f48a25e7a31b52a6492cc8f" + integrity sha512-S8cNxbyb0UGUM2VhRD4Poe5N58gJnJsLJ5vC7FYWGUmGhcsj4++WaIOBFVDxlG0W3To6xBuiRh+i0Qp2oNCOtg== + dependencies: + buffer "6.0.3" + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +shelljs@^0.8.3: + version "0.8.5" + resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.5.tgz#de055408d8361bed66c669d2f000538ced8ee20c" + integrity sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow== + dependencies: + glob "^7.0.0" + interpret "^1.0.0" + rechoir "^0.6.2" + +side-channel@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" + integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== + dependencies: + call-bind "^1.0.0" + get-intrinsic "^1.0.2" + object-inspect "^1.9.0" + +simple-concat@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.1.tgz#f46976082ba35c2263f1c8ab5edfe26c41c9552f" + integrity sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q== + +simple-get@^2.7.0: + version "2.8.2" + resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-2.8.2.tgz#5708fb0919d440657326cd5fe7d2599d07705019" + integrity sha512-Ijd/rV5o+mSBBs4F/x9oDPtTx9Zb6X9brmnXvMW4J7IR15ngi9q5xxqWBKU744jTZiaXtxaPL7uHG6vtN8kUkw== + dependencies: + decompress-response "^3.3.0" + once "^1.3.1" + simple-concat "^1.0.0" + +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== + +slice-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b" + integrity sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ== + dependencies: + ansi-styles "^4.0.0" + astral-regex "^2.0.0" + is-fullwidth-code-point "^3.0.0" + +snake-case@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/snake-case/-/snake-case-2.1.0.tgz#41bdb1b73f30ec66a04d4e2cad1b76387d4d6d9f" + integrity sha512-FMR5YoPFwOLuh4rRz92dywJjyKYZNLpMn1R5ujVpIYkbA9p01fq8RMg0FkO4M+Yobt4MjHeLTJVm5xFFBHSV2Q== + dependencies: + no-case "^2.2.0" + +solc@0.7.3: + version "0.7.3" + resolved "https://registry.yarnpkg.com/solc/-/solc-0.7.3.tgz#04646961bd867a744f63d2b4e3c0701ffdc7d78a" + integrity sha512-GAsWNAjGzIDg7VxzP6mPjdurby3IkGCjQcM8GFYZT6RyaoUZKmMU6Y7YwG+tFGhv7dwZ8rmR4iwFDrrD99JwqA== + dependencies: + command-exists "^1.2.8" + commander "3.0.2" + follow-redirects "^1.12.1" + fs-extra "^0.30.0" + js-sha3 "0.8.0" + memorystream "^0.3.1" + require-from-string "^2.0.0" + semver "^5.5.0" + tmp "0.0.33" + +solc@0.8.15: + version "0.8.15" + resolved "https://registry.yarnpkg.com/solc/-/solc-0.8.15.tgz#d274dca4d5a8b7d3c9295d4cbdc9291ee1c52152" + integrity sha512-Riv0GNHNk/SddN/JyEuFKwbcWcEeho15iyupTSHw5Np6WuXA5D8kEHbyzDHi6sqmvLzu2l+8b1YmL8Ytple+8w== + dependencies: + command-exists "^1.2.8" + commander "^8.1.0" + follow-redirects "^1.12.1" + js-sha3 "0.8.0" + memorystream "^0.3.1" + semver "^5.5.0" + tmp "0.0.33" + +solc@^0.4.20: + version "0.4.26" + resolved "https://registry.yarnpkg.com/solc/-/solc-0.4.26.tgz#5390a62a99f40806b86258c737c1cf653cc35cb5" + integrity sha512-o+c6FpkiHd+HPjmjEVpQgH7fqZ14tJpXhho+/bQXlXbliLIS/xjXb42Vxh+qQY1WCSTMQ0+a5vR9vi0MfhU6mA== + dependencies: + fs-extra "^0.30.0" + memorystream "^0.3.1" + require-from-string "^1.1.0" + semver "^5.3.0" + yargs "^4.7.1" + +solc@^0.8.15: + version "0.8.22" + resolved "https://registry.yarnpkg.com/solc/-/solc-0.8.22.tgz#6df0bb688b9a58bbf10932730301374a6ccfb862" + integrity sha512-bA2tMZXx93R8L5LUH7TlB/f+QhkVyxrrY6LmgJnFFZlRknrhYVlBK1e3uHIdKybwoFabOFSzeaZjPeL/GIpFGQ== + dependencies: + command-exists "^1.2.8" + commander "^8.1.0" + follow-redirects "^1.12.1" + js-sha3 "0.8.0" + memorystream "^0.3.1" + semver "^5.5.0" + tmp "0.0.33" + +solhint-plugin-prettier@^0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/solhint-plugin-prettier/-/solhint-plugin-prettier-0.0.5.tgz#e3b22800ba435cd640a9eca805a7f8bc3e3e6a6b" + integrity sha512-7jmWcnVshIrO2FFinIvDQmhQpfpS2rRRn3RejiYgnjIE68xO2bvrYvjqVNfrio4xH9ghOqn83tKuTzLjEbmGIA== + dependencies: + prettier-linter-helpers "^1.0.0" + +solhint@^3.3.7: + version "3.6.2" + resolved "https://registry.yarnpkg.com/solhint/-/solhint-3.6.2.tgz#2b2acbec8fdc37b2c68206a71ba89c7f519943fe" + integrity sha512-85EeLbmkcPwD+3JR7aEMKsVC9YrRSxd4qkXuMzrlf7+z2Eqdfm1wHWq1ffTuo5aDhoZxp2I9yF3QkxZOxOL7aQ== + dependencies: + "@solidity-parser/parser" "^0.16.0" + ajv "^6.12.6" + antlr4 "^4.11.0" + ast-parents "^0.0.1" + chalk "^4.1.2" + commander "^10.0.0" + cosmiconfig "^8.0.0" + fast-diff "^1.2.0" + glob "^8.0.3" + ignore "^5.2.4" + js-yaml "^4.1.0" + lodash "^4.17.21" + pluralize "^8.0.0" + semver "^7.5.2" + strip-ansi "^6.0.1" + table "^6.8.1" + text-table "^0.2.0" + optionalDependencies: + prettier "^2.8.3" + +solidity-ast@^0.4.38: + version "0.4.55" + resolved "https://registry.yarnpkg.com/solidity-ast/-/solidity-ast-0.4.55.tgz#00b685e6eefb2e8dfb67df1fe0afbe3b3bfb4b28" + integrity sha512-qeEU/r/K+V5lrAw8iswf2/yfWAnSGs3WKPHI+zAFKFjX0dIBVXEU/swQ8eJQYHf6PJWUZFO2uWV4V1wEOkeQbA== + dependencies: + array.prototype.findlast "^1.2.2" + +solidity-comments-extractor@^0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/solidity-comments-extractor/-/solidity-comments-extractor-0.0.7.tgz#99d8f1361438f84019795d928b931f4e5c39ca19" + integrity sha512-wciNMLg/Irp8OKGrh3S2tfvZiZ0NEyILfcRCXCD4mp7SgK/i9gzLfhY2hY7VMCQJ3kH9UB9BzNdibIVMchzyYw== + +solidity-coverage@^0.8.2: + version "0.8.5" + resolved "https://registry.yarnpkg.com/solidity-coverage/-/solidity-coverage-0.8.5.tgz#64071c3a0c06a0cecf9a7776c35f49edc961e875" + integrity sha512-6C6N6OV2O8FQA0FWA95FdzVH+L16HU94iFgg5wAFZ29UpLFkgNI/DRR2HotG1bC0F4gAc/OMs2BJI44Q/DYlKQ== + dependencies: + "@ethersproject/abi" "^5.0.9" + "@solidity-parser/parser" "^0.16.0" + chalk "^2.4.2" + death "^1.1.0" + detect-port "^1.3.0" + difflib "^0.2.4" + fs-extra "^8.1.0" + ghost-testrpc "^0.0.2" + global-modules "^2.0.0" + globby "^10.0.1" + jsonschema "^1.2.4" + lodash "^4.17.15" + mocha "10.2.0" + node-emoji "^1.10.0" + pify "^4.0.1" + recursive-readdir "^2.2.2" + sc-istanbul "^0.4.5" + semver "^7.3.4" + shelljs "^0.8.3" + web3-utils "^1.3.6" + +solidity-docgen@^0.6.0-beta.36: + version "0.6.0-beta.36" + resolved "https://registry.yarnpkg.com/solidity-docgen/-/solidity-docgen-0.6.0-beta.36.tgz#9c76eda58580fb52e2db318c22fe3154e0c09dd1" + integrity sha512-f/I5G2iJgU1h0XrrjRD0hHMr7C10u276vYvm//rw1TzFcYQ4xTOyAoi9oNAHRU0JU4mY9eTuxdVc2zahdMuhaQ== + dependencies: + handlebars "^4.7.7" + solidity-ast "^0.4.38" + +source-map-support@^0.5.13, source-map-support@^0.5.19: + version "0.5.21" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" + integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map@^0.6.0, source-map@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +source-map@~0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.2.0.tgz#dab73fbcfc2ba819b4de03bd6f6eaa48164b3f9d" + integrity sha512-CBdZ2oa/BHhS4xj5DlhjWNHcan57/5YuvfdLf17iVmIpd9KRm+DFLmC6nBNj+6Ua7Kt3TmOjDpQT1aTYOQtoUA== + dependencies: + amdefine ">=0.0.4" + +spdx-correct@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.2.0.tgz#4f5ab0668f0059e34f9c00dce331784a12de4e9c" + integrity sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA== + dependencies: + spdx-expression-parse "^3.0.0" + spdx-license-ids "^3.0.0" + +spdx-exceptions@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" + integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== + +spdx-expression-parse@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" + integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== + dependencies: + spdx-exceptions "^2.1.0" + spdx-license-ids "^3.0.0" + +spdx-license-ids@^3.0.0: + version "3.0.16" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.16.tgz#a14f64e0954f6e25cc6587bd4f392522db0d998f" + integrity sha512-eWN+LnM3GR6gPu35WxNgbGl8rmY1AEmoMDvL/QD6zYmPWgywxWqJWNdLGT+ke8dKNWrcYgYjPpG5gbTfghP8rw== + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== + +sshpk@^1.7.0: + version "1.18.0" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.18.0.tgz#1663e55cddf4d688b86a46b77f0d5fe363aba028" + integrity sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ== + dependencies: + asn1 "~0.2.3" + assert-plus "^1.0.0" + bcrypt-pbkdf "^1.0.0" + dashdash "^1.12.0" + ecc-jsbn "~0.1.1" + getpass "^0.1.1" + jsbn "~0.1.0" + safer-buffer "^2.0.2" + tweetnacl "~0.14.0" + +stacktrace-parser@^0.1.10: + version "0.1.10" + resolved "https://registry.yarnpkg.com/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz#29fb0cae4e0d0b85155879402857a1639eb6051a" + integrity sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg== + dependencies: + type-fest "^0.7.1" + +statuses@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" + integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== + +strict-uri-encode@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" + integrity sha512-R3f198pcvnB+5IpnBlRkphuE9n46WyVl8I39W/ZUTZLz4nqSP/oLYUrcnJrw462Ds8he4YKMov2efsTIw1BDGQ== + +string-format@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/string-format/-/string-format-2.0.0.tgz#f2df2e7097440d3b65de31b6d40d54c96eaffb9b" + integrity sha512-bbEs3scLeYNXLecRRuk6uJxdXUSj6le/8rNPHChIJTn2V79aXVTR1EH2OH5zLKKoz0V02fOUKZZcw01pLUShZA== + +string-width@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + integrity sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw== + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + +string-width@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^4.0.0" + +string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string.prototype.trim@^1.2.8: + version "1.2.8" + resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz#f9ac6f8af4bd55ddfa8895e6aea92a96395393bd" + integrity sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + +string.prototype.trimend@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz#1bb3afc5008661d73e2dc015cd4853732d6c471e" + integrity sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + +string.prototype.trimstart@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz#d4cdb44b83a4737ffbac2d406e405d43d0184298" + integrity sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +strip-ansi@^3.0.0, strip-ansi@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + integrity sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg== + dependencies: + ansi-regex "^2.0.0" + +strip-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" + integrity sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow== + dependencies: + ansi-regex "^3.0.0" + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-bom@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" + integrity sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g== + dependencies: + is-utf8 "^0.2.0" + +strip-bom@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA== + +strip-hex-prefix@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz#0c5f155fef1151373377de9dbb588da05500e36f" + integrity sha512-q8d4ue7JGEiVcypji1bALTos+0pWtyGlivAWyPuTkHzuTCJqrK9sWxYQZUq6Nq3cuyv3bm734IhHvHtGGURU6A== + dependencies: + is-hex-prefixed "1.0.0" + +strip-indent@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-2.0.0.tgz#5ef8db295d01e6ed6cbf7aab96998d7822527b68" + integrity sha512-RsSNPLpq6YUL7QYy44RnPVTn/lcVZtb48Uof3X5JLbF4zD/Gs7ZFDv2HWol+leoQN2mT86LAzSshGfkTlSOpsA== + +strip-json-comments@3.1.1, strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== + +supports-color@8.1.1: + version "8.1.1" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + +supports-color@^3.1.0: + version "3.2.3" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6" + integrity sha512-Jds2VIYDrlp5ui7t8abHN2bjAu4LV/q4N2KivFPpGH0lrka0BMq/33AmECUXlKPcHigkNaqfXRENFju+rlcy+A== + dependencies: + has-flag "^1.0.0" + +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + +swap-case@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/swap-case/-/swap-case-1.1.2.tgz#c39203a4587385fad3c850a0bd1bcafa081974e3" + integrity sha512-BAmWG6/bx8syfc6qXPprof3Mn5vQgf5dwdUNJhsNqU9WdPt5P+ES/wQ5bxfijy8zwZgZZHslC3iAsxsuQMCzJQ== + dependencies: + lower-case "^1.1.1" + upper-case "^1.1.1" + +swarm-js@^0.1.40: + version "0.1.42" + resolved "https://registry.yarnpkg.com/swarm-js/-/swarm-js-0.1.42.tgz#497995c62df6696f6e22372f457120e43e727979" + integrity sha512-BV7c/dVlA3R6ya1lMlSSNPLYrntt0LUq4YMgy3iwpCIc6rZnS5W2wUoctarZ5pXlpKtxDDf9hNziEkcfrxdhqQ== + dependencies: + bluebird "^3.5.0" + buffer "^5.0.5" + eth-lib "^0.1.26" + fs-extra "^4.0.2" + got "^11.8.5" + mime-types "^2.1.16" + mkdirp-promise "^5.0.1" + mock-fs "^4.1.0" + setimmediate "^1.0.5" + tar "^4.0.2" + xhr-request "^1.0.1" + +sync-request@^6.0.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/sync-request/-/sync-request-6.1.0.tgz#e96217565b5e50bbffe179868ba75532fb597e68" + integrity sha512-8fjNkrNlNCrVc/av+Jn+xxqfCjYaBoHqCsDz6mt030UMxJGr+GSfCV1dQt2gRtlL63+VPidwDVLr7V2OcTSdRw== + dependencies: + http-response-object "^3.0.1" + sync-rpc "^1.2.1" + then-request "^6.0.0" + +sync-rpc@^1.2.1: + version "1.3.6" + resolved "https://registry.yarnpkg.com/sync-rpc/-/sync-rpc-1.3.6.tgz#b2e8b2550a12ccbc71df8644810529deb68665a7" + integrity sha512-J8jTXuZzRlvU7HemDgHi3pGnh/rkoqR/OZSjhTyyZrEkkYQbk7Z33AXp37mkPfPpfdOuj7Ex3H/TJM1z48uPQw== + dependencies: + get-port "^3.1.0" + +table-layout@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/table-layout/-/table-layout-1.0.2.tgz#c4038a1853b0136d63365a734b6931cf4fad4a04" + integrity sha512-qd/R7n5rQTRFi+Zf2sk5XVVd9UQl6ZkduPFC3S7WEGJAmetDTjY3qPN50eSKzwuzEyQKy5TN2TiZdkIjos2L6A== + dependencies: + array-back "^4.0.1" + deep-extend "~0.6.0" + typical "^5.2.0" + wordwrapjs "^4.0.0" + +table@^6.0.9, table@^6.8.0, table@^6.8.1: + version "6.8.1" + resolved "https://registry.yarnpkg.com/table/-/table-6.8.1.tgz#ea2b71359fe03b017a5fbc296204471158080bdf" + integrity sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA== + dependencies: + ajv "^8.0.1" + lodash.truncate "^4.4.2" + slice-ansi "^4.0.0" + string-width "^4.2.3" + strip-ansi "^6.0.1" + +tar@^4.0.2: + version "4.4.19" + resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.19.tgz#2e4d7263df26f2b914dee10c825ab132123742f3" + integrity sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA== + dependencies: + chownr "^1.1.4" + fs-minipass "^1.2.7" + minipass "^2.9.0" + minizlib "^1.3.3" + mkdirp "^0.5.5" + safe-buffer "^5.2.1" + yallist "^3.1.1" + +testrpc@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/testrpc/-/testrpc-0.0.1.tgz#83e2195b1f5873aec7be1af8cbe6dcf39edb7aed" + integrity sha512-afH1hO+SQ/VPlmaLUFj2636QMeDvPCeQMc/9RBMW0IfjNe9gFD9Ra3ShqYkB7py0do1ZcCna/9acHyzTJ+GcNA== + +text-table@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== + +then-request@^6.0.0: + version "6.0.2" + resolved "https://registry.yarnpkg.com/then-request/-/then-request-6.0.2.tgz#ec18dd8b5ca43aaee5cb92f7e4c1630e950d4f0c" + integrity sha512-3ZBiG7JvP3wbDzA9iNY5zJQcHL4jn/0BWtXIkagfz7QgOL/LqjCEOBQuJNZfu0XYnv5JhKh+cDxCPM4ILrqruA== + dependencies: + "@types/concat-stream" "^1.6.0" + "@types/form-data" "0.0.33" + "@types/node" "^8.0.0" + "@types/qs" "^6.2.31" + caseless "~0.12.0" + concat-stream "^1.6.0" + form-data "^2.2.0" + http-basic "^8.1.1" + http-response-object "^3.0.1" + promise "^8.0.0" + qs "^6.4.0" + +timed-out@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" + integrity sha512-G7r3AhovYtr5YKOWQkta8RKAPb+J9IsO4uVmzjl8AZwfhs8UcUwTiD6gcJYSgOtzyjvQKrKYn41syHbUWMkafA== + +tiny-invariant@^1.1.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.3.1.tgz#8560808c916ef02ecfd55e66090df23a4b7aa642" + integrity sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw== + +tiny-warning@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754" + integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA== + +title-case@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/title-case/-/title-case-2.1.1.tgz#3e127216da58d2bc5becf137ab91dae3a7cd8faa" + integrity sha512-EkJoZ2O3zdCz3zJsYCsxyq2OC5hrxR9mfdd5I+w8h/tmFfeOxJ+vvkxsKxdmN0WtS9zLdHEgfgVOiMVgv+Po4Q== + dependencies: + no-case "^2.2.0" + upper-case "^1.0.3" + +tmp@0.0.33: + version "0.0.33" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" + integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== + dependencies: + os-tmpdir "~1.0.2" + +to-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" + +toformat@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/toformat/-/toformat-2.0.0.tgz#7a043fd2dfbe9021a4e36e508835ba32056739d8" + integrity sha512-03SWBVop6nU8bpyZCx7SodpYznbZF5R4ljwNLBcTQzKOD9xuihRo/psX58llS1BMFhhAI08H3luot5GoXJz2pQ== + +toidentifier@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" + integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== + +tough-cookie@~2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" + integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== + dependencies: + psl "^1.1.28" + punycode "^2.1.1" + +tr46@~0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" + integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== + +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.8.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" + +tsconfig-paths@^3.14.2: + version "3.14.2" + resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz#6e32f1f79412decd261f92d633a9dc1cfa99f088" + integrity sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g== + dependencies: + "@types/json5" "^0.0.29" + json5 "^1.0.2" + minimist "^1.2.6" + strip-bom "^3.0.0" + +tslib@^1.8.1, tslib@^1.9.3: + version "1.14.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" + integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== + +tsort@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/tsort/-/tsort-0.0.1.tgz#e2280f5e817f8bf4275657fd0f9aebd44f5a2786" + integrity sha512-Tyrf5mxF8Ofs1tNoxA13lFeZ2Zrbd6cKbuH3V+MQ5sb6DtBj5FjrXVsRWT8YvNAQTqNoz66dz1WsbigI22aEnw== + +tsutils@^3.21.0: + version "3.21.0" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" + integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA== + dependencies: + tslib "^1.8.1" + +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + integrity sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w== + dependencies: + safe-buffer "^5.0.1" + +tweetnacl-util@^0.15.1: + version "0.15.1" + resolved "https://registry.yarnpkg.com/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz#b80fcdb5c97bcc508be18c44a4be50f022eea00b" + integrity sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw== + +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + integrity sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA== + +tweetnacl@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-1.0.3.tgz#ac0af71680458d8a6378d0d0d050ab1407d35596" + integrity sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw== + +type-check@^0.4.0, type-check@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" + integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== + dependencies: + prelude-ls "^1.2.1" + +type-check@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" + integrity sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg== + dependencies: + prelude-ls "~1.1.2" + +type-detect@^4.0.0, type-detect@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" + integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== + +type-fest@^0.20.2: + version "0.20.2" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" + integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== + +type-fest@^0.21.3: + version "0.21.3" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" + integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== + +type-fest@^0.7.1: + version "0.7.1" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.7.1.tgz#8dda65feaf03ed78f0a3f9678f1869147f7c5c48" + integrity sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg== + +type-is@~1.6.18: + version "1.6.18" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" + integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.24" + +type@^1.0.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0" + integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg== + +type@^2.7.2: + version "2.7.2" + resolved "https://registry.yarnpkg.com/type/-/type-2.7.2.tgz#2376a15a3a28b1efa0f5350dcf72d24df6ef98d0" + integrity sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw== + +typechain@^8.0.0, typechain@^8.3.1: + version "8.3.2" + resolved "https://registry.yarnpkg.com/typechain/-/typechain-8.3.2.tgz#1090dd8d9c57b6ef2aed3640a516bdbf01b00d73" + integrity sha512-x/sQYr5w9K7yv3es7jo4KTX05CLxOf7TRWwoHlrjRh8H82G64g+k7VuWPJlgMo6qrjfCulOdfBjiaDtmhFYD/Q== + dependencies: + "@types/prettier" "^2.1.1" + debug "^4.3.1" + fs-extra "^7.0.0" + glob "7.1.7" + js-sha3 "^0.8.0" + lodash "^4.17.15" + mkdirp "^1.0.4" + prettier "^2.3.1" + ts-command-line-args "^2.2.0" + ts-essentials "^7.0.1" + +typed-array-buffer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz#18de3e7ed7974b0a729d3feecb94338d1472cd60" + integrity sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.2.1" + is-typed-array "^1.1.10" + +typed-array-byte-length@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz#d787a24a995711611fb2b87a4052799517b230d0" + integrity sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA== + dependencies: + call-bind "^1.0.2" + for-each "^0.3.3" + has-proto "^1.0.1" + is-typed-array "^1.1.10" + +typed-array-byte-offset@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz#cbbe89b51fdef9cd6aaf07ad4707340abbc4ea0b" + integrity sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg== + dependencies: + available-typed-arrays "^1.0.5" + call-bind "^1.0.2" + for-each "^0.3.3" + has-proto "^1.0.1" + is-typed-array "^1.1.10" + +typed-array-length@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/typed-array-length/-/typed-array-length-1.0.4.tgz#89d83785e5c4098bec72e08b319651f0eac9c1bb" + integrity sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng== + dependencies: + call-bind "^1.0.2" + for-each "^0.3.3" + is-typed-array "^1.1.9" + +typedarray-to-buffer@^3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" + integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== + dependencies: + is-typedarray "^1.0.0" + +typedarray@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" + integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA== + +typescript@^4.7.3: + version "4.9.5" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a" + integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== + +typical@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/typical/-/typical-4.0.0.tgz#cbeaff3b9d7ae1e2bbfaf5a4e6f11eccfde94fc4" + integrity sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw== + +typical@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/typical/-/typical-5.2.0.tgz#4daaac4f2b5315460804f0acf6cb69c52bb93066" + integrity sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg== + +uglify-js@^3.1.4: + version "3.17.4" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.17.4.tgz#61678cf5fa3f5b7eb789bb345df29afb8257c22c" + integrity sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g== + +ultron@~1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.1.1.tgz#9fe1536a10a664a65266a1e3ccf85fd36302bc9c" + integrity sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og== + +unbox-primitive@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e" + integrity sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw== + dependencies: + call-bind "^1.0.2" + has-bigints "^1.0.2" + has-symbols "^1.0.3" + which-boxed-primitive "^1.0.2" + +underscore@^1.8.3: + version "1.13.6" + resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.13.6.tgz#04786a1f589dc6c09f761fc5f45b89e935136441" + integrity sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A== + +undici-types@~5.26.4: + version "5.26.5" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" + integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== + +undici@^5.14.0: + version "5.27.2" + resolved "https://registry.yarnpkg.com/undici/-/undici-5.27.2.tgz#a270c563aea5b46cc0df2550523638c95c5d4411" + integrity sha512-iS857PdOEy/y3wlM3yRp+6SNQQ6xU0mmZcwRSriqk+et/cwWAtwmIGf6WkoDN2EK/AMdCO/dfXzIwi+rFMrjjQ== + dependencies: + "@fastify/busboy" "^2.0.0" + +universalify@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" + integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== + +universalify@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.1.tgz#168efc2180964e6386d061e094df61afe239b18d" + integrity sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw== + +unpipe@1.0.0, unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== + +upper-case-first@^1.1.0, upper-case-first@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/upper-case-first/-/upper-case-first-1.1.2.tgz#5d79bedcff14419518fd2edb0a0507c9b6859115" + integrity sha512-wINKYvI3Db8dtjikdAqoBbZoP6Q+PZUyfMR7pmwHzjC2quzSkUq5DmPrTtPEqHaz8AGtmsB4TqwapMTM1QAQOQ== + dependencies: + upper-case "^1.1.1" + +upper-case@^1.0.3, upper-case@^1.1.0, upper-case@^1.1.1, upper-case@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/upper-case/-/upper-case-1.1.3.tgz#f6b4501c2ec4cdd26ba78be7222961de77621598" + integrity sha512-WRbjgmYzgXkCV7zNVpy5YgrHgbBv126rMALQQMrmzOVC4GM2waQ9x7xtm8VU+1yF2kWyPzI9zbZ48n4vSxwfSA== + +uri-js@^4.2.2: + version "4.4.1" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== + dependencies: + punycode "^2.1.0" + +url-set-query@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/url-set-query/-/url-set-query-1.0.0.tgz#016e8cfd7c20ee05cafe7795e892bd0702faa339" + integrity sha512-3AChu4NiXquPfeckE5R5cGdiHCMWJx1dwCWOmWIL4KHAziJNOFIYJlpGFeKDvwLPHovZRCxK3cYlwzqI9Vp+Gg== + +url@^0.11.0: + version "0.11.3" + resolved "https://registry.yarnpkg.com/url/-/url-0.11.3.tgz#6f495f4b935de40ce4a0a52faee8954244f3d3ad" + integrity sha512-6hxOLGfZASQK/cijlZnZJTq8OXAkt/3YGfQX45vvMYXpZoo8NdWZcY73K108Jf759lS1Bv/8wXnHDTSz17dSRw== + dependencies: + punycode "^1.4.1" + qs "^6.11.2" + +utf-8-validate@5.0.7: + version "5.0.7" + resolved "https://registry.yarnpkg.com/utf-8-validate/-/utf-8-validate-5.0.7.tgz#c15a19a6af1f7ad9ec7ddc425747ca28c3644922" + integrity sha512-vLt1O5Pp+flcArHGIyKEQq883nBt8nN8tVBcoL0qUXj2XT1n7p70yGIq2VK98I5FdZ1YHc0wk/koOnHjnXWk1Q== + dependencies: + node-gyp-build "^4.3.0" + +utf-8-validate@^5.0.2: + version "5.0.10" + resolved "https://registry.yarnpkg.com/utf-8-validate/-/utf-8-validate-5.0.10.tgz#d7d10ea39318171ca982718b6b96a8d2442571a2" + integrity sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ== + dependencies: + node-gyp-build "^4.3.0" + +utf8@3.0.0, utf8@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/utf8/-/utf8-3.0.0.tgz#f052eed1364d696e769ef058b183df88c87f69d1" + integrity sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ== + +util-deprecate@^1.0.1, util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== + +util@^0.12.5: + version "0.12.5" + resolved "https://registry.yarnpkg.com/util/-/util-0.12.5.tgz#5f17a6059b73db61a875668781a1c2b136bd6fbc" + integrity sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA== + dependencies: + inherits "^2.0.3" + is-arguments "^1.0.4" + is-generator-function "^1.0.7" + is-typed-array "^1.1.3" + which-typed-array "^1.1.2" + +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== + +uuid@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-2.0.1.tgz#c2a30dedb3e535d72ccf82e343941a50ba8533ac" + integrity sha512-nWg9+Oa3qD2CQzHIP4qKUqwNfzKn8P0LtFhotaCTFchsV7ZfDhAybeip/HZVeMIpZi9JgY1E3nUlwaCmZT1sEg== + +uuid@^3.3.2: + version "3.4.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" + integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== + +uuid@^8.3.2: + version "8.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" + integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== + +uuid@^9.0.0: + version "9.0.1" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.1.tgz#e188d4c8853cc722220392c424cd637f32293f30" + integrity sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA== + +v8-compile-cache-lib@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf" + integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg== + +v8-compile-cache@^2.0.3: + version "2.4.0" + resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.4.0.tgz#cdada8bec61e15865f05d097c5f4fd30e94dc128" + integrity sha512-ocyWc3bAHBB/guyqJQVI5o4BZkPhznPYUG2ea80Gond/BgNWpap8TOmLSeeQG7bnh2KMISxskdADG59j7zruhw== + +validate-npm-package-license@^3.0.1: + version "3.0.4" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" + integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== + dependencies: + spdx-correct "^3.0.0" + spdx-expression-parse "^3.0.0" + +varint@^5.0.0: + version "5.0.2" + resolved "https://registry.yarnpkg.com/varint/-/varint-5.0.2.tgz#5b47f8a947eb668b848e034dcfa87d0ff8a7f7a4" + integrity sha512-lKxKYG6H03yCZUpAGOPOsMcGxd1RHCu1iKvEHYDPmTyq2HueGhD73ssNBqqQWfvYs04G9iUFRvmAVLW20Jw6ow== + +vary@^1, vary@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== + +verror@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" + integrity sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw== + dependencies: + assert-plus "^1.0.0" + core-util-is "1.0.2" + extsprintf "^1.2.0" + +web3-bzz@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/web3-bzz/-/web3-bzz-1.10.0.tgz#ac74bc71cdf294c7080a79091079192f05c5baed" + integrity sha512-o9IR59io3pDUsXTsps5pO5hW1D5zBmg46iNc2t4j2DkaYHNdDLwk2IP9ukoM2wg47QILfPEJYzhTfkS/CcX0KA== + dependencies: + "@types/node" "^12.12.6" + got "12.1.0" + swarm-js "^0.1.40" + +web3-bzz@1.10.3: + version "1.10.3" + resolved "https://registry.yarnpkg.com/web3-bzz/-/web3-bzz-1.10.3.tgz#13942b37757eb850f3500a8e08bf605448b67566" + integrity sha512-XDIRsTwekdBXtFytMpHBuun4cK4x0ZMIDXSoo1UVYp+oMyZj07c7gf7tNQY5qZ/sN+CJIas4ilhN25VJcjSijQ== + dependencies: + "@types/node" "^12.12.6" + got "12.1.0" + swarm-js "^0.1.40" + +web3-core-helpers@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/web3-core-helpers/-/web3-core-helpers-1.10.0.tgz#1016534c51a5df77ed4f94d1fcce31de4af37fad" + integrity sha512-pIxAzFDS5vnbXvfvLSpaA1tfRykAe9adw43YCKsEYQwH0gCLL0kMLkaCX3q+Q8EVmAh+e1jWL/nl9U0de1+++g== + dependencies: + web3-eth-iban "1.10.0" + web3-utils "1.10.0" + +web3-core-helpers@1.10.3: + version "1.10.3" + resolved "https://registry.yarnpkg.com/web3-core-helpers/-/web3-core-helpers-1.10.3.tgz#f2db40ea57e888795e46f229b06113b60bcd671c" + integrity sha512-Yv7dQC3B9ipOc5sWm3VAz1ys70Izfzb8n9rSiQYIPjpqtJM+3V4EeK6ghzNR6CO2es0+Yu9CtCkw0h8gQhrTxA== + dependencies: + web3-eth-iban "1.10.3" + web3-utils "1.10.3" + +web3-core-method@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/web3-core-method/-/web3-core-method-1.10.0.tgz#82668197fa086e8cc8066742e35a9d72535e3412" + integrity sha512-4R700jTLAMKDMhQ+nsVfIXvH6IGJlJzGisIfMKWAIswH31h5AZz7uDUW2YctI+HrYd+5uOAlS4OJeeT9bIpvkA== + dependencies: + "@ethersproject/transactions" "^5.6.2" + web3-core-helpers "1.10.0" + web3-core-promievent "1.10.0" + web3-core-subscriptions "1.10.0" + web3-utils "1.10.0" + +web3-core-method@1.10.3: + version "1.10.3" + resolved "https://registry.yarnpkg.com/web3-core-method/-/web3-core-method-1.10.3.tgz#63f16310ccab4eec8eca0a337d534565c2ba8d33" + integrity sha512-VZ/Dmml4NBmb0ep5PTSg9oqKoBtG0/YoMPei/bq/tUdlhB2dMB79sbeJPwx592uaV0Vpk7VltrrrBv5hTM1y4Q== + dependencies: + "@ethersproject/transactions" "^5.6.2" + web3-core-helpers "1.10.3" + web3-core-promievent "1.10.3" + web3-core-subscriptions "1.10.3" + web3-utils "1.10.3" + +web3-core-promievent@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/web3-core-promievent/-/web3-core-promievent-1.10.0.tgz#cbb5b3a76b888df45ed3a8d4d8d4f54ccb66a37b" + integrity sha512-68N7k5LWL5R38xRaKFrTFT2pm2jBNFaM4GioS00YjAKXRQ3KjmhijOMG3TICz6Aa5+6GDWYelDNx21YAeZ4YTg== + dependencies: + eventemitter3 "4.0.4" + +web3-core-promievent@1.10.3: + version "1.10.3" + resolved "https://registry.yarnpkg.com/web3-core-promievent/-/web3-core-promievent-1.10.3.tgz#9765dd42ce6cf2dc0a08eaffee607b855644f290" + integrity sha512-HgjY+TkuLm5uTwUtaAfkTgRx/NzMxvVradCi02gy17NxDVdg/p6svBHcp037vcNpkuGeFznFJgULP+s2hdVgUQ== + dependencies: + eventemitter3 "4.0.4" + +web3-core-requestmanager@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/web3-core-requestmanager/-/web3-core-requestmanager-1.10.0.tgz#4b34f6e05837e67c70ff6f6993652afc0d54c340" + integrity sha512-3z/JKE++Os62APml4dvBM+GAuId4h3L9ckUrj7ebEtS2AR0ixyQPbrBodgL91Sv7j7cQ3Y+hllaluqjguxvSaQ== + dependencies: + util "^0.12.5" + web3-core-helpers "1.10.0" + web3-providers-http "1.10.0" + web3-providers-ipc "1.10.0" + web3-providers-ws "1.10.0" + +web3-core-requestmanager@1.10.3: + version "1.10.3" + resolved "https://registry.yarnpkg.com/web3-core-requestmanager/-/web3-core-requestmanager-1.10.3.tgz#c34ca8e998a18d6ca3fa7f7a11d4391da401c987" + integrity sha512-VT9sKJfgM2yBOIxOXeXiDuFMP4pxzF6FT+y8KTLqhDFHkbG3XRe42Vm97mB/IvLQCJOmokEjl3ps8yP1kbggyw== + dependencies: + util "^0.12.5" + web3-core-helpers "1.10.3" + web3-providers-http "1.10.3" + web3-providers-ipc "1.10.3" + web3-providers-ws "1.10.3" + +web3-core-subscriptions@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/web3-core-subscriptions/-/web3-core-subscriptions-1.10.0.tgz#b534592ee1611788fc0cb0b95963b9b9b6eacb7c" + integrity sha512-HGm1PbDqsxejI075gxBc5OSkwymilRWZufIy9zEpnWKNmfbuv5FfHgW1/chtJP6aP3Uq2vHkvTDl3smQBb8l+g== + dependencies: + eventemitter3 "4.0.4" + web3-core-helpers "1.10.0" + +web3-core-subscriptions@1.10.3: + version "1.10.3" + resolved "https://registry.yarnpkg.com/web3-core-subscriptions/-/web3-core-subscriptions-1.10.3.tgz#58768cd72a9313252ef05dc52c09536f009a9479" + integrity sha512-KW0Mc8sgn70WadZu7RjQ4H5sNDJ5Lx8JMI3BWos+f2rW0foegOCyWhRu33W1s6ntXnqeBUw5rRCXZRlA3z+HNA== + dependencies: + eventemitter3 "4.0.4" + web3-core-helpers "1.10.3" + +web3-core@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/web3-core/-/web3-core-1.10.0.tgz#9aa07c5deb478cf356c5d3b5b35afafa5fa8e633" + integrity sha512-fWySwqy2hn3TL89w5TM8wXF1Z2Q6frQTKHWmP0ppRQorEK8NcHJRfeMiv/mQlSKoTS1F6n/nv2uyZsixFycjYQ== + dependencies: + "@types/bn.js" "^5.1.1" + "@types/node" "^12.12.6" + bignumber.js "^9.0.0" + web3-core-helpers "1.10.0" + web3-core-method "1.10.0" + web3-core-requestmanager "1.10.0" + web3-utils "1.10.0" + +web3-core@1.10.3: + version "1.10.3" + resolved "https://registry.yarnpkg.com/web3-core/-/web3-core-1.10.3.tgz#4aeb8f4b0cb5775d9fa4edf1127864743f1c3ae3" + integrity sha512-Vbk0/vUNZxJlz3RFjAhNNt7qTpX8yE3dn3uFxfX5OHbuon5u65YEOd3civ/aQNW745N0vGUlHFNxxmn+sG9DIw== + dependencies: + "@types/bn.js" "^5.1.1" + "@types/node" "^12.12.6" + bignumber.js "^9.0.0" + web3-core-helpers "1.10.3" + web3-core-method "1.10.3" + web3-core-requestmanager "1.10.3" + web3-utils "1.10.3" + +web3-eth-abi@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/web3-eth-abi/-/web3-eth-abi-1.10.0.tgz#53a7a2c95a571e205e27fd9e664df4919483cce1" + integrity sha512-cwS+qRBWpJ43aI9L3JS88QYPfFcSJJ3XapxOQ4j40v6mk7ATpA8CVK1vGTzpihNlOfMVRBkR95oAj7oL6aiDOg== + dependencies: + "@ethersproject/abi" "^5.6.3" + web3-utils "1.10.0" + +web3-eth-abi@1.10.3: + version "1.10.3" + resolved "https://registry.yarnpkg.com/web3-eth-abi/-/web3-eth-abi-1.10.3.tgz#7decfffa8fed26410f32cfefdc32d3e76f717ca2" + integrity sha512-O8EvV67uhq0OiCMekqYsDtb6FzfYzMXT7VMHowF8HV6qLZXCGTdB/NH4nJrEh2mFtEwVdS6AmLFJAQd2kVyoMQ== + dependencies: + "@ethersproject/abi" "^5.6.3" + web3-utils "1.10.3" + +web3-eth-accounts@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/web3-eth-accounts/-/web3-eth-accounts-1.10.0.tgz#2942beca0a4291455f32cf09de10457a19a48117" + integrity sha512-wiq39Uc3mOI8rw24wE2n15hboLE0E9BsQLdlmsL4Zua9diDS6B5abXG0XhFcoNsXIGMWXVZz4TOq3u4EdpXF/Q== + dependencies: + "@ethereumjs/common" "2.5.0" + "@ethereumjs/tx" "3.3.2" + eth-lib "0.2.8" + ethereumjs-util "^7.1.5" + scrypt-js "^3.0.1" + uuid "^9.0.0" + web3-core "1.10.0" + web3-core-helpers "1.10.0" + web3-core-method "1.10.0" + web3-utils "1.10.0" + +web3-eth-accounts@1.10.3: + version "1.10.3" + resolved "https://registry.yarnpkg.com/web3-eth-accounts/-/web3-eth-accounts-1.10.3.tgz#9ecb816b81cd97333988bfcd0afaee5d13bbb198" + integrity sha512-8MipGgwusDVgn7NwKOmpeo3gxzzd+SmwcWeBdpXknuyDiZSQy9tXe+E9LeFGrmys/8mLLYP79n3jSbiTyv+6pQ== + dependencies: + "@ethereumjs/common" "2.6.5" + "@ethereumjs/tx" "3.5.2" + "@ethereumjs/util" "^8.1.0" + eth-lib "0.2.8" + scrypt-js "^3.0.1" + uuid "^9.0.0" + web3-core "1.10.3" + web3-core-helpers "1.10.3" + web3-core-method "1.10.3" + web3-utils "1.10.3" + +web3-eth-contract@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/web3-eth-contract/-/web3-eth-contract-1.10.0.tgz#8e68c7654576773ec3c91903f08e49d0242c503a" + integrity sha512-MIC5FOzP/+2evDksQQ/dpcXhSqa/2hFNytdl/x61IeWxhh6vlFeSjq0YVTAyIzdjwnL7nEmZpjfI6y6/Ufhy7w== + dependencies: + "@types/bn.js" "^5.1.1" + web3-core "1.10.0" + web3-core-helpers "1.10.0" + web3-core-method "1.10.0" + web3-core-promievent "1.10.0" + web3-core-subscriptions "1.10.0" + web3-eth-abi "1.10.0" + web3-utils "1.10.0" + +web3-eth-contract@1.10.3: + version "1.10.3" + resolved "https://registry.yarnpkg.com/web3-eth-contract/-/web3-eth-contract-1.10.3.tgz#8880468e2ba7d8a4791cf714f67d5e1ec1591275" + integrity sha512-Y2CW61dCCyY4IoUMD4JsEQWrILX4FJWDWC/Txx/pr3K/+fGsBGvS9kWQN5EsVXOp4g7HoFOfVh9Lf7BmVVSRmg== + dependencies: + "@types/bn.js" "^5.1.1" + web3-core "1.10.3" + web3-core-helpers "1.10.3" + web3-core-method "1.10.3" + web3-core-promievent "1.10.3" + web3-core-subscriptions "1.10.3" + web3-eth-abi "1.10.3" + web3-utils "1.10.3" + +web3-eth-ens@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/web3-eth-ens/-/web3-eth-ens-1.10.0.tgz#96a676524e0b580c87913f557a13ed810cf91cd9" + integrity sha512-3hpGgzX3qjgxNAmqdrC2YUQMTfnZbs4GeLEmy8aCWziVwogbuqQZ+Gzdfrym45eOZodk+lmXyLuAdqkNlvkc1g== + dependencies: + content-hash "^2.5.2" + eth-ens-namehash "2.0.8" + web3-core "1.10.0" + web3-core-helpers "1.10.0" + web3-core-promievent "1.10.0" + web3-eth-abi "1.10.0" + web3-eth-contract "1.10.0" + web3-utils "1.10.0" + +web3-eth-ens@1.10.3: + version "1.10.3" + resolved "https://registry.yarnpkg.com/web3-eth-ens/-/web3-eth-ens-1.10.3.tgz#ae5b49bcb9823027e0b28aa6b1de58d726cbaafa" + integrity sha512-hR+odRDXGqKemw1GFniKBEXpjYwLgttTES+bc7BfTeoUyUZXbyDHe5ifC+h+vpzxh4oS0TnfcIoarK0Z9tFSiQ== + dependencies: + content-hash "^2.5.2" + eth-ens-namehash "2.0.8" + web3-core "1.10.3" + web3-core-helpers "1.10.3" + web3-core-promievent "1.10.3" + web3-eth-abi "1.10.3" + web3-eth-contract "1.10.3" + web3-utils "1.10.3" + +web3-eth-iban@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/web3-eth-iban/-/web3-eth-iban-1.10.0.tgz#5a46646401965b0f09a4f58e7248c8a8cd22538a" + integrity sha512-0l+SP3IGhInw7Q20LY3IVafYEuufo4Dn75jAHT7c2aDJsIolvf2Lc6ugHkBajlwUneGfbRQs/ccYPQ9JeMUbrg== + dependencies: + bn.js "^5.2.1" + web3-utils "1.10.0" + +web3-eth-iban@1.10.3: + version "1.10.3" + resolved "https://registry.yarnpkg.com/web3-eth-iban/-/web3-eth-iban-1.10.3.tgz#91d458e5400195edc883a0d4383bf1cecd17240d" + integrity sha512-ZCfOjYKAjaX2TGI8uif5ah+J3BYFuo+47JOIV1RIz2l7kD9VfnxvRH5UiQDRyMALQC7KFd2hUqIEtHklapNyKA== + dependencies: + bn.js "^5.2.1" + web3-utils "1.10.3" + +web3-eth-personal@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/web3-eth-personal/-/web3-eth-personal-1.10.0.tgz#94d525f7a29050a0c2a12032df150ac5ea633071" + integrity sha512-anseKn98w/d703eWq52uNuZi7GhQeVjTC5/svrBWEKob0WZ5kPdo+EZoFN0sp5a5ubbrk/E0xSl1/M5yORMtpg== + dependencies: + "@types/node" "^12.12.6" + web3-core "1.10.0" + web3-core-helpers "1.10.0" + web3-core-method "1.10.0" + web3-net "1.10.0" + web3-utils "1.10.0" + +web3-eth-personal@1.10.3: + version "1.10.3" + resolved "https://registry.yarnpkg.com/web3-eth-personal/-/web3-eth-personal-1.10.3.tgz#4e72008aa211327ccc3bfa7671c510e623368457" + integrity sha512-avrQ6yWdADIvuNQcFZXmGLCEzulQa76hUOuVywN7O3cklB4nFc/Gp3yTvD3bOAaE7DhjLQfhUTCzXL7WMxVTsw== + dependencies: + "@types/node" "^12.12.6" + web3-core "1.10.3" + web3-core-helpers "1.10.3" + web3-core-method "1.10.3" + web3-net "1.10.3" + web3-utils "1.10.3" + +web3-eth@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/web3-eth/-/web3-eth-1.10.0.tgz#38b905e2759697c9624ab080cfcf4e6c60b3a6cf" + integrity sha512-Z5vT6slNMLPKuwRyKGbqeGYC87OAy8bOblaqRTgg94CXcn/mmqU7iPIlG4506YdcdK3x6cfEDG7B6w+jRxypKA== + dependencies: + web3-core "1.10.0" + web3-core-helpers "1.10.0" + web3-core-method "1.10.0" + web3-core-subscriptions "1.10.0" + web3-eth-abi "1.10.0" + web3-eth-accounts "1.10.0" + web3-eth-contract "1.10.0" + web3-eth-ens "1.10.0" + web3-eth-iban "1.10.0" + web3-eth-personal "1.10.0" + web3-net "1.10.0" + web3-utils "1.10.0" + +web3-eth@1.10.3: + version "1.10.3" + resolved "https://registry.yarnpkg.com/web3-eth/-/web3-eth-1.10.3.tgz#b8c6f37f1aac52422583a5a9c29130983a3fb3b1" + integrity sha512-Uk1U2qGiif2mIG8iKu23/EQJ2ksB1BQXy3wF3RvFuyxt8Ft9OEpmGlO7wOtAyJdoKzD5vcul19bJpPcWSAYZhA== + dependencies: + web3-core "1.10.3" + web3-core-helpers "1.10.3" + web3-core-method "1.10.3" + web3-core-subscriptions "1.10.3" + web3-eth-abi "1.10.3" + web3-eth-accounts "1.10.3" + web3-eth-contract "1.10.3" + web3-eth-ens "1.10.3" + web3-eth-iban "1.10.3" + web3-eth-personal "1.10.3" + web3-net "1.10.3" + web3-utils "1.10.3" + +web3-net@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/web3-net/-/web3-net-1.10.0.tgz#be53e7f5dafd55e7c9013d49c505448b92c9c97b" + integrity sha512-NLH/N3IshYWASpxk4/18Ge6n60GEvWBVeM8inx2dmZJVmRI6SJIlUxbL8jySgiTn3MMZlhbdvrGo8fpUW7a1GA== + dependencies: + web3-core "1.10.0" + web3-core-method "1.10.0" + web3-utils "1.10.0" + +web3-net@1.10.3: + version "1.10.3" + resolved "https://registry.yarnpkg.com/web3-net/-/web3-net-1.10.3.tgz#9486c2fe51452cb958e11915db6f90bd6caa5482" + integrity sha512-IoSr33235qVoI1vtKssPUigJU9Fc/Ph0T9CgRi15sx+itysmvtlmXMNoyd6Xrgm9LuM4CIhxz7yDzH93B79IFg== + dependencies: + web3-core "1.10.3" + web3-core-method "1.10.3" + web3-utils "1.10.3" + +web3-providers-http@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/web3-providers-http/-/web3-providers-http-1.10.0.tgz#864fa48675e7918c9a4374e5f664b32c09d0151b" + integrity sha512-eNr965YB8a9mLiNrkjAWNAPXgmQWfpBfkkn7tpEFlghfww0u3I0tktMZiaToJVcL2+Xq+81cxbkpeWJ5XQDwOA== + dependencies: + abortcontroller-polyfill "^1.7.3" + cross-fetch "^3.1.4" + es6-promise "^4.2.8" + web3-core-helpers "1.10.0" + +web3-providers-http@1.10.3: + version "1.10.3" + resolved "https://registry.yarnpkg.com/web3-providers-http/-/web3-providers-http-1.10.3.tgz#d8166ee89db82d37281ea9e15c5882a2d7928755" + integrity sha512-6dAgsHR3MxJ0Qyu3QLFlQEelTapVfWNTu5F45FYh8t7Y03T1/o+YAkVxsbY5AdmD+y5bXG/XPJ4q8tjL6MgZHw== + dependencies: + abortcontroller-polyfill "^1.7.5" + cross-fetch "^4.0.0" + es6-promise "^4.2.8" + web3-core-helpers "1.10.3" + +web3-providers-ipc@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/web3-providers-ipc/-/web3-providers-ipc-1.10.0.tgz#9747c7a6aee96a51488e32fa7c636c3460b39889" + integrity sha512-OfXG1aWN8L1OUqppshzq8YISkWrYHaATW9H8eh0p89TlWMc1KZOL9vttBuaBEi96D/n0eYDn2trzt22bqHWfXA== + dependencies: + oboe "2.1.5" + web3-core-helpers "1.10.0" + +web3-providers-ipc@1.10.3: + version "1.10.3" + resolved "https://registry.yarnpkg.com/web3-providers-ipc/-/web3-providers-ipc-1.10.3.tgz#a7e015957fc037d8a87bd4b6ae3561c1b1ad1f46" + integrity sha512-vP5WIGT8FLnGRfswTxNs9rMfS1vCbMezj/zHbBe/zB9GauBRTYVrUo2H/hVrhLg8Ut7AbsKZ+tCJ4mAwpKi2hA== + dependencies: + oboe "2.1.5" + web3-core-helpers "1.10.3" + +web3-providers-ws@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/web3-providers-ws/-/web3-providers-ws-1.10.0.tgz#cb0b87b94c4df965cdf486af3a8cd26daf3975e5" + integrity sha512-sK0fNcglW36yD5xjnjtSGBnEtf59cbw4vZzJ+CmOWIKGIR96mP5l684g0WD0Eo+f4NQc2anWWXG74lRc9OVMCQ== + dependencies: + eventemitter3 "4.0.4" + web3-core-helpers "1.10.0" + websocket "^1.0.32" + +web3-providers-ws@1.10.3: + version "1.10.3" + resolved "https://registry.yarnpkg.com/web3-providers-ws/-/web3-providers-ws-1.10.3.tgz#03c84958f9da251349cd26fd7a4ae567e3af6caa" + integrity sha512-/filBXRl48INxsh6AuCcsy4v5ndnTZ/p6bl67kmO9aK1wffv7CT++DrtclDtVMeDGCgB3van+hEf9xTAVXur7Q== + dependencies: + eventemitter3 "4.0.4" + web3-core-helpers "1.10.3" + websocket "^1.0.32" + +web3-shh@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/web3-shh/-/web3-shh-1.10.0.tgz#c2979b87e0f67a7fef2ce9ee853bd7bfbe9b79a8" + integrity sha512-uNUUuNsO2AjX41GJARV9zJibs11eq6HtOe6Wr0FtRUcj8SN6nHeYIzwstAvJ4fXA53gRqFMTxdntHEt9aXVjpg== + dependencies: + web3-core "1.10.0" + web3-core-method "1.10.0" + web3-core-subscriptions "1.10.0" + web3-net "1.10.0" + +web3-shh@1.10.3: + version "1.10.3" + resolved "https://registry.yarnpkg.com/web3-shh/-/web3-shh-1.10.3.tgz#ee44f760598a65a290d611c443838aac854ee858" + integrity sha512-cAZ60CPvs9azdwMSQ/PSUdyV4PEtaW5edAZhu3rCXf6XxQRliBboic+AvwUvB6j3eswY50VGa5FygfVmJ1JVng== + dependencies: + web3-core "1.10.3" + web3-core-method "1.10.3" + web3-core-subscriptions "1.10.3" + web3-net "1.10.3" + +web3-utils@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.10.0.tgz#ca4c1b431a765c14ac7f773e92e0fd9377ccf578" + integrity sha512-kSaCM0uMcZTNUSmn5vMEhlo02RObGNRRCkdX0V9UTAU0+lrvn0HSaudyCo6CQzuXUsnuY2ERJGCGPfeWmv19Rg== + dependencies: + bn.js "^5.2.1" + ethereum-bloom-filters "^1.0.6" + ethereumjs-util "^7.1.0" + ethjs-unit "0.1.6" + number-to-bn "1.7.0" + randombytes "^2.1.0" + utf8 "3.0.0" + +web3-utils@1.10.3, web3-utils@^1.0.0-beta.31, web3-utils@^1.3.6: + version "1.10.3" + resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.10.3.tgz#f1db99c82549c7d9f8348f04ffe4e0188b449714" + integrity sha512-OqcUrEE16fDBbGoQtZXWdavsPzbGIDc5v3VrRTZ0XrIpefC/viZ1ZU9bGEemazyS0catk/3rkOOxpzTfY+XsyQ== + dependencies: + "@ethereumjs/util" "^8.1.0" + bn.js "^5.2.1" + ethereum-bloom-filters "^1.0.6" + ethereum-cryptography "^2.1.2" + ethjs-unit "0.1.6" + number-to-bn "1.7.0" + randombytes "^2.1.0" + utf8 "3.0.0" + +web3@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/web3/-/web3-1.10.0.tgz#2fde0009f59aa756c93e07ea2a7f3ab971091274" + integrity sha512-YfKY9wSkGcM8seO+daR89oVTcbu18NsVfvOngzqMYGUU0pPSQmE57qQDvQzUeoIOHAnXEBNzrhjQJmm8ER0rng== + dependencies: + web3-bzz "1.10.0" + web3-core "1.10.0" + web3-eth "1.10.0" + web3-eth-personal "1.10.0" + web3-net "1.10.0" + web3-shh "1.10.0" + web3-utils "1.10.0" + +web3@^1.0.0-beta.34, web3@^1.7.4: + version "1.10.3" + resolved "https://registry.yarnpkg.com/web3/-/web3-1.10.3.tgz#5e80ac532dc432b09fde668d570b0ad4e6710897" + integrity sha512-DgUdOOqC/gTqW+VQl1EdPxrVRPB66xVNtuZ5KD4adVBtko87hkgM8BTZ0lZ8IbUfnQk6DyjcDujMiH3oszllAw== + dependencies: + web3-bzz "1.10.3" + web3-core "1.10.3" + web3-eth "1.10.3" + web3-eth-personal "1.10.3" + web3-net "1.10.3" + web3-shh "1.10.3" + web3-utils "1.10.3" + +webidl-conversions@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" + integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== + +websocket@^1.0.32: + version "1.0.34" + resolved "https://registry.yarnpkg.com/websocket/-/websocket-1.0.34.tgz#2bdc2602c08bf2c82253b730655c0ef7dcab3111" + integrity sha512-PRDso2sGwF6kM75QykIesBijKSVceR6jL2G8NGYyq2XrItNC2P5/qL5XeR056GhA+Ly7JMFvJb9I312mJfmqnQ== + dependencies: + bufferutil "^4.0.1" + debug "^2.2.0" + es5-ext "^0.10.50" + typedarray-to-buffer "^3.1.5" + utf-8-validate "^5.0.2" + yaeti "^0.0.6" + +whatwg-url@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" + integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== + dependencies: + tr46 "~0.0.3" + webidl-conversions "^3.0.0" + +which-boxed-primitive@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" + integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== + dependencies: + is-bigint "^1.0.1" + is-boolean-object "^1.1.0" + is-number-object "^1.0.4" + is-string "^1.0.5" + is-symbol "^1.0.3" + +which-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f" + integrity sha512-F6+WgncZi/mJDrammbTuHe1q0R5hOXv/mBaiNA2TCNT/LTHusX0V+CJnj9XT8ki5ln2UZyyddDgHfCzyrOH7MQ== + +which-typed-array@^1.1.11, which-typed-array@^1.1.13, which-typed-array@^1.1.2: + version "1.1.13" + resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.13.tgz#870cd5be06ddb616f504e7b039c4c24898184d36" + integrity sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow== + dependencies: + available-typed-arrays "^1.0.5" + call-bind "^1.0.4" + for-each "^0.3.3" + gopd "^1.0.1" + has-tostringtag "^1.0.0" + +which@^1.1.1, which@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== + dependencies: + isexe "^2.0.0" + +which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +window-size@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.2.0.tgz#b4315bb4214a3d7058ebeee892e13fa24d98b075" + integrity sha512-UD7d8HFA2+PZsbKyaOCEy8gMh1oDtHgJh1LfgjQ4zVXmYjAT/kvz3PueITKuqDiIXQe7yzpPnxX3lNc+AhQMyw== + +word-wrap@~1.2.3: + version "1.2.5" + resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.5.tgz#d2c45c6dd4fbce621a66f136cbe328afd0410b34" + integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA== + +wordwrap@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" + integrity sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q== + +wordwrapjs@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/wordwrapjs/-/wordwrapjs-4.0.1.tgz#d9790bccfb110a0fc7836b5ebce0937b37a8b98f" + integrity sha512-kKlNACbvHrkpIw6oPeYDSmdCTu2hdMHoyXLTcUKala++lx5Y+wjJ/e474Jqv5abnVmwxw08DiTuHmw69lJGksA== + dependencies: + reduce-flatten "^2.0.0" + typical "^5.2.0" + +workerpool@6.2.1: + version "6.2.1" + resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343" + integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw== + +wrap-ansi@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" + integrity sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw== + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity 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== + +ws@^3.0.0: + version "3.3.3" + resolved "https://registry.yarnpkg.com/ws/-/ws-3.3.3.tgz#f1cf84fe2d5e901ebce94efaece785f187a228f2" + integrity sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA== + dependencies: + async-limiter "~1.0.0" + safe-buffer "~5.1.0" + ultron "~1.1.0" + +ws@^7.4.6: + version "7.5.9" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.9.tgz#54fa7db29f4c7cec68b1ddd3a89de099942bb591" + integrity sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q== + +xhr-request-promise@^0.1.2: + version "0.1.3" + resolved "https://registry.yarnpkg.com/xhr-request-promise/-/xhr-request-promise-0.1.3.tgz#2d5f4b16d8c6c893be97f1a62b0ed4cf3ca5f96c" + integrity sha512-YUBytBsuwgitWtdRzXDDkWAXzhdGB8bYm0sSzMPZT7Z2MBjMSTHFsyCT1yCRATY+XC69DUrQraRAEgcoCRaIPg== + dependencies: + xhr-request "^1.1.0" + +xhr-request@^1.0.1, xhr-request@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/xhr-request/-/xhr-request-1.1.0.tgz#f4a7c1868b9f198723444d82dcae317643f2e2ed" + integrity sha512-Y7qzEaR3FDtL3fP30k9wO/e+FBnBByZeybKOhASsGP30NIkRAAkKD/sCnLvgEfAIEC1rcmK7YG8f4oEnIrrWzA== + dependencies: + buffer-to-arraybuffer "^0.0.5" + object-assign "^4.1.1" + query-string "^5.0.1" + simple-get "^2.7.0" + timed-out "^4.0.1" + url-set-query "^1.0.0" + xhr "^2.0.4" + +xhr@^2.0.4, xhr@^2.3.3: + version "2.6.0" + resolved "https://registry.yarnpkg.com/xhr/-/xhr-2.6.0.tgz#b69d4395e792b4173d6b7df077f0fc5e4e2b249d" + integrity sha512-/eCGLb5rxjx5e3mF1A7s+pLlR6CGyqWN91fv1JgER5mVWg1MZmlhBvy9kjcsOdRk8RrIujotWyJamfyrp+WIcA== + dependencies: + global "~4.4.0" + is-function "^1.0.1" + parse-headers "^2.0.0" + xtend "^4.0.0" + +xmlhttprequest@1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz#67fe075c5c24fef39f9d65f5f7b7fe75171968fc" + integrity sha512-58Im/U0mlVBLM38NdZjHyhuMtCqa61469k2YP/AaPbvCoV9aQGUpbJBj1QRm2ytRiVQBD/fsw7L2bJGDVQswBA== + +xtend@^4.0.0, xtend@^4.0.1, xtend@^4.0.2, xtend@~4.0.0: + version "4.0.2" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" + integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== + +y18n@^3.2.1: + version "3.2.2" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.2.tgz#85c901bd6470ce71fc4bb723ad209b70f7f28696" + integrity sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ== + +y18n@^5.0.5: + version "5.0.8" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" + integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== + +yaeti@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/yaeti/-/yaeti-0.0.6.tgz#f26f484d72684cf42bedfb76970aa1608fbf9577" + integrity sha512-MvQa//+KcZCUkBTIC9blM+CU9J2GzuTytsOUwf2lidtvkx/6gnEp1QvJv34t9vdjhFmha/mUiNDbN0D0mJWdug== + +yallist@^3.0.0, yallist@^3.0.2, yallist@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" + integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + +yargs-parser@20.2.4: + version "20.2.4" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" + integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== + +yargs-parser@^2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-2.4.1.tgz#85568de3cf150ff49fa51825f03a8c880ddcc5c4" + integrity sha512-9pIKIJhnI5tonzG6OnCFlz/yln8xHYcGl+pn3xR0Vzff0vzN1PbNRaelgfgRUwZ3s4i3jvxT9WhmUGL4whnasA== + dependencies: + camelcase "^3.0.0" + lodash.assign "^4.0.6" + +yargs-parser@^20.2.2: + version "20.2.9" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" + integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== + +yargs-unparser@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb" + integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== + dependencies: + camelcase "^6.0.0" + decamelize "^4.0.0" + flat "^5.0.2" + is-plain-obj "^2.1.0" + +yargs@16.2.0: + version "16.2.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" + integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== + dependencies: + cliui "^7.0.2" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.0" + y18n "^5.0.5" + yargs-parser "^20.2.2" + +yargs@^4.7.1: + version "4.8.1" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-4.8.1.tgz#c0c42924ca4aaa6b0e6da1739dfb216439f9ddc0" + integrity sha512-LqodLrnIDM3IFT+Hf/5sxBnEGECrfdC1uIbgZeJmESCSo4HoCAaKEus8MylXHAkdacGc0ye+Qa+dpkuom8uVYA== + dependencies: + cliui "^3.2.0" + decamelize "^1.1.1" + get-caller-file "^1.0.1" + lodash.assign "^4.0.3" + os-locale "^1.4.0" + read-pkg-up "^1.0.1" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^1.0.1" + which-module "^1.0.0" + window-size "^0.2.0" + y18n "^3.2.1" + yargs-parser "^2.4.1" + +yn@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" + integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== + +yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== + +zksync-web3@^0.14.3: + version "0.14.4" + resolved "https://registry.yarnpkg.com/zksync-web3/-/zksync-web3-0.14.4.tgz#0b70a7e1a9d45cc57c0971736079185746d46b1f" + integrity sha512-kYehMD/S6Uhe1g434UnaMN+sBr9nQm23Ywn0EUP5BfQCsbjcr3ORuS68PosZw8xUTu3pac7G6YMSnNHk+fwzvg==