diff --git a/.env.example b/.env.example index 8e2cf2a..7779719 100644 --- a/.env.example +++ b/.env.example @@ -10,6 +10,7 @@ PAYMASTER_OWNER_ADDRESS_DEV= PAYMASTER_OWNER_ADDRESS_PROD= PAYMASTER_SIGNER_ADDRESS_DEV= PAYMASTER_SIGNER_ADDRESS_PROD= +SPONSORSHIP_FEE_COLLECTOR_ADDRESS_PROD= TOKEN_PAYMASTER_OWNER_ADDRESS_DEV= TOKEN_PAYMASTER_OWNER_ADDRESS_PROD= TOKEN_PAYMASTER_SIGNER_ADDRESS_DEV= diff --git a/.gas-snapshot b/.gas-snapshot index c62f117..d24fc07 100644 --- a/.gas-snapshot +++ b/.gas-snapshot @@ -1,14 +1,24 @@ -TokenPaymasterTest:test2TokenPaymasterFailInvalidPaymasteDataLength() (gas: 278584) -TokenPaymasterTest:testCall() (gas: 313171) -TokenPaymasterTest:testCheckStates() (gas: 18600) -TokenPaymasterTest:testDeploy() (gas: 1604349) -TokenPaymasterTest:testOwnershipTransfer() (gas: 23443) -TokenPaymasterTest:testParsePaymasterData() (gas: 621) -TokenPaymasterTest:testTokenPaymasterFailHighPriceMarkup() (gas: 300775) -TokenPaymasterTest:testTokenPaymasterFailInvalidPMSignature() (gas: 283184) -TokenPaymasterTest:testTokenPaymasterFailInvalidPMSignatureLength() (gas: 283496) -TokenPaymasterTest:testTokenPaymasterFailInvalidPaymasteDataLength() (gas: 221406) -TokenPaymasterTest:testTokenPaymasterFailWrongPMSignature() (gas: 295014) -TokenPaymasterTest:testTokenPaymasterRefund() (gas: 399655) -TokenPaymasterTest:testWithdrawERC20(uint256) (runs: 256, μ: 61802, ~: 64060) -TokenPaymasterTest:testWithdrawERC20FailNotOwner(uint256) (runs: 256, μ: 48871, ~: 51000) \ No newline at end of file +TokenPaymasterMumbaiTest:test2TokenPaymasterFailInvalidPaymasteDataLength() (gas: 506028) +TokenPaymasterMumbaiTest:testCall() (gas: 164706) +TokenPaymasterMumbaiTest:testCheckStates() (gas: 18809) +TokenPaymasterMumbaiTest:testDeploy() (gas: 1761558) +TokenPaymasterMumbaiTest:testOwnershipTransfer() (gas: 23623) +TokenPaymasterMumbaiTest:testTokenPaymasterFailHighPriceMarkup() (gas: 521192) +TokenPaymasterMumbaiTest:testTokenPaymasterFailInvalidPMSignature() (gas: 509672) +TokenPaymasterMumbaiTest:testTokenPaymasterFailInvalidPaymasteDataLength() (gas: 460199) +TokenPaymasterMumbaiTest:testTokenPaymasterFailWrongPMSignature() (gas: 515316) +TokenPaymasterMumbaiTest:testTokenPaymasterRefund() (gas: 470153) +TokenPaymasterMumbaiTest:testWithdrawERC20(uint256) (runs: 256, μ: 202488, ~: 203918) +TokenPaymasterMumbaiTest:testWithdrawERC20FailNotOwner(uint256) (runs: 256, μ: 173830, ~: 173830) +TokenPaymasterTest:test2TokenPaymasterFailInvalidPaymasteDataLength() (gas: 290853) +TokenPaymasterTest:testCall() (gas: 166515) +TokenPaymasterTest:testCheckStates() (gas: 18787) +TokenPaymasterTest:testDeploy() (gas: 1761536) +TokenPaymasterTest:testOwnershipTransfer() (gas: 23579) +TokenPaymasterTest:testTokenPaymasterFailHighPriceMarkup() (gas: 309758) +TokenPaymasterTest:testTokenPaymasterFailInvalidPMSignature() (gas: 295496) +TokenPaymasterTest:testTokenPaymasterFailInvalidPaymasteDataLength() (gas: 231031) +TokenPaymasterTest:testTokenPaymasterFailWrongPMSignature() (gas: 302475) +TokenPaymasterTest:testTokenPaymasterRefund() (gas: 255197) +TokenPaymasterTest:testWithdrawERC20(uint256) (runs: 256, μ: 61632, ~: 63985) +TokenPaymasterTest:testWithdrawERC20FailNotOwner(uint256) (runs: 256, μ: 48656, ~: 50873) \ No newline at end of file diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index a50eb11..ee7b584 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -29,5 +29,5 @@ Related Issue: # (issue number) # Branch Naming - + \ No newline at end of file diff --git a/.github/workflows/check_branch_name.yml b/.github/workflows/check_branch_name.yml new file mode 100644 index 0000000..1ced204 --- /dev/null +++ b/.github/workflows/check_branch_name.yml @@ -0,0 +1,18 @@ +name: Check Branch Name +on: + create: + +jobs: + check-branch-name: + runs-on: ubuntu-latest + if: github.event.ref_type == 'branch' && !contains(github.ref, 'refs/heads/main') + steps: + - name: Check Branch Name + run: | + BRANCH_PREFIX_REGEX="^(feat/|fix/|release/|chore/).+" + BRANCH_NAME=${GITHUB_REF#refs/heads/} + if [[ ! $BRANCH_NAME =~ $BRANCH_PREFIX_REGEX ]]; then + echo "Invalid branch name: $BRANCH_NAME" + echo "Branch name must start with 'feat/', 'fix/', 'chore/', or 'release/'." + exit 1 + fi diff --git a/.gitignore b/.gitignore index 0028d08..140ce61 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,7 @@ forge-cache/ typechain-types typechain typings +yarn-error.log #Hardhat files cache @@ -19,3 +20,5 @@ artifacts-filtered account-abstraction scw-contracts +.DS_Store +yarn-error.log diff --git a/.gitmodules b/.gitmodules index e9cf533..f1be11f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,9 +1,11 @@ -[submodule "lib/account-abstraction"] - path = lib/account-abstraction - url = https://github.com/eth-infinitism/account-abstraction [submodule "lib/forge-std"] path = lib/forge-std url = https://github.com/foundry-rs/forge-std [submodule "lib/scw-contracts"] path = lib/scw-contracts url = https://github.com/bcnmy/scw-contracts + branch = develop +[submodule "lib/account-abstraction"] + path = lib/account-abstraction + url = https://github.com/eth-infinitism/account-abstraction + tag = v0.6.0 diff --git a/.husky/pre-commit b/.husky/pre-commit index 2b2afa7..af50890 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1,2 +1,4 @@ #!/usr/bin/env sh -. "$(dirname -- "$0")/_/husky.sh" \ No newline at end of file +. "$(dirname -- "$0")/_/husky.sh" + +yarn lint:sol \ No newline at end of file diff --git a/.solhint.json b/.solhint.json index 48b6778..6018f40 100644 --- a/.solhint.json +++ b/.solhint.json @@ -1,7 +1,7 @@ { "extends": "solhint:recommended", "rules": { - "compiler-version": ["error", "0.8.17"], + "compiler-version": ["error", "0.8.23"], "func-visibility": ["warn", { "ignoreConstructors": true }], "reentrancy": "error", "state-visibility": "error", diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..9e61241 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,67 @@ +# Contributing to Biconomy Projects 🚀 + +First off, thank you for considering contributing to Biconomy! We truly appreciate your effort. +Contributions from the community are what make Biconomy awesome. 🙌 + +Your contributions are valued and will help in driving the decentralized web forward. + +> If you're passionate about our mission but can't contribute directly, there are other ways to support: +> +> - ⭐ Star our projects on GitHub +> - 🐦 [Tweet about Biconomy](https://twitter.com/biconomy/) +> - 📌 Reference Biconomy in your project's readme +> - 🗣️ Share about Biconomy at meetups or with peers + +## Table of Contents + +- [Contributing to Biconomy Projects 🚀](#contributing-to-biconomy-projects-) + - [Table of Contents](#table-of-contents) + - [Have a Question?](#have-a-question) + - [Ready to Contribute?](#ready-to-contribute) + - [Legal Notice 📜](#legal-notice-) + - [Reporting Bugs 🐛](#reporting-bugs-) + - [Suggesting Enhancements 💡](#suggesting-enhancements-) + - [First Time Contributing? 🌱](#first-time-contributing-) + - [Improving Documentation 📚](#improving-documentation-) + - [Commit Messages 📝](#commit-messages-) + - [Join Biconomy's Team! 🚀](#join-biconomys-team-) + +## Have a Question? + +Before reaching out, please ensure you've gone through our [Documentation](https://docs.biconomy.io/). If you still have questions: + +1. Search for existing [Issues](https://github.com/bcnmy/biconomy-paymasters/issues) that might answer your question. +2. Check out our [Forum](https://forum.biconomy.io/). +3. Join our [Discord](https://discord.com/invite/biconomy) or [Telegram](https://t.me/biconomy) communities. + +If you still need assistance, feel free to open an [Issue](https://github.com/bcnmy/biconomy-paymasters/issues/new) with your question. + +## Ready to Contribute? + +### Legal Notice 📜 + +By contributing, you agree that you've authored your contribution and that it can be provided under the project's license. + +### Reporting Bugs 🐛 + +Before submitting a bug report, ensure you're using the latest version and that you've read our [documentation](https://docs.biconomy.io/). If you've identified a bug that hasn't been reported, open a new [Issue](https://github.com/bcnmy/biconomy-paymasters/issues/new) detailing the bug. + +### Suggesting Enhancements 💡 + +Have a feature in mind? First, ensure it aligns with Biconomy's mission and hasn't been suggested before. Then, open an [Issue](https://github.com/bcnmy/biconomy-paymasters/issues/new) to discuss your enhancement. + +### First Time Contributing? 🌱 + +Welcome! We're thrilled to have you. If you're unsure where to start, look for issues labeled `good first issue`. + +### Improving Documentation 📚 + +Good documentation is key! If you spot areas for improvement or errors in our documentation, we'd love your input. If you wish to suggest changes, feel free to raise a PR on our [documentation repository](https://github.com/bcnmy/docs). + +### Commit Messages 📝 + +Ensure your commit messages are clear and descriptive. + +## Join Biconomy's Team! 🚀 + +Interested in joining our mission full-time? Check out our [current job openings](https://jobs.lever.co/biconomy). diff --git a/DerivedPriceFeedFlat.sol b/DerivedPriceFeedFlat.sol deleted file mode 100644 index d73d003..0000000 --- a/DerivedPriceFeedFlat.sol +++ /dev/null @@ -1,149 +0,0 @@ -// Sources flattened with hardhat v2.14.1 https://hardhat.org - -// File @chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol@v0.6.1 - -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -interface AggregatorV3Interface { - function decimals() external view returns (uint8); - - function description() external view returns (string memory); - - function version() external view returns (uint256); - - function getRoundData(uint80 _roundId) - external - view - returns ( - uint80 roundId, - int256 answer, - uint256 startedAt, - uint256 updatedAt, - uint80 answeredInRound - ); - - function latestRoundData() - external - view - returns ( - uint80 roundId, - int256 answer, - uint256 startedAt, - uint256 updatedAt, - uint80 answeredInRound - ); -} - - -// File contracts/token/oracles/DerivedPriceFeed.sol - -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.17; - -error MismatchInBaseAndQuoteDecimals(); -error InvalidPriceFromRound(); -error LatestRoundIncomplete(); -error PriceFeedStale(); -error OracleAddressCannotBeZero(); - -contract DerivedPriceFeed { - // price is native-per-dollar - AggregatorV3Interface internal nativeOracle; - // price is tokens-per-dollar - AggregatorV3Interface internal tokenOracle; - - string internal DESCRIPTION; - - constructor( - address _nativeOracleAddress, - address _tokenOracleAddress, - string memory _description - ) { - if (_nativeOracleAddress == address(0)) - revert OracleAddressCannotBeZero(); - if (_tokenOracleAddress == address(0)) - revert OracleAddressCannotBeZero(); - nativeOracle = AggregatorV3Interface(_nativeOracleAddress); - tokenOracle = AggregatorV3Interface(_tokenOracleAddress); - - // If either of the base or quote price feeds have mismatch in decimal then it could be a problem, so throw! - uint8 decimals1 = nativeOracle.decimals(); - uint8 decimals2 = tokenOracle.decimals(); - if (decimals1 != decimals2) revert MismatchInBaseAndQuoteDecimals(); - - DESCRIPTION = _description; - } - - function decimals() public view returns (uint8) { - return 18; - } - - function description() public view returns (string memory) { - return DESCRIPTION; - } - - function validateRound( - uint80 roundId, - int256 price, - uint256 updatedAt, - uint80 answeredInRound, - uint256 staleFeedThreshold - ) internal view { - if (price <= 0) revert InvalidPriceFromRound(); - // 2 days old price is considered stale since the price is updated every 24 hours - if (updatedAt < block.timestamp - staleFeedThreshold) - revert PriceFeedStale(); - if (updatedAt == 0) revert LatestRoundIncomplete(); - if (answeredInRound < roundId) revert PriceFeedStale(); - } - - function getThePrice() public view returns (int) { - /** - * Returns the latest price of price feed 1 - */ - - ( - uint80 roundID1, - int256 price1, - , - uint256 updatedAt1, - uint80 answeredInRound1 - ) = nativeOracle.latestRoundData(); - - // By default 2 days old price is considered stale BUT it may vary per price feed - // comapred to stable coin feeds this may have different heartbeat - validateRound( - roundID1, - price1, - updatedAt1, - answeredInRound1, - 60 * 60 * 24 * 2 - ); - - /** - * Returns the latest price of price feed 2 - */ - - ( - uint80 roundID2, - int256 price2, - , - uint256 updatedAt2, - uint80 answeredInRound2 - ) = tokenOracle.latestRoundData(); - - // By default 2 days old price is considered stale BUT it may vary per price feed - validateRound( - roundID2, - price2, - updatedAt2, - answeredInRound2, - 60 * 60 * 24 * 2 - ); - - // Always using decimals 18 for derived price feeds - int token_native = (price2 * (10 ** 18)) / price1; - return token_native; - } -} diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..cf907e9 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 Biconomy + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index f186692..6294834 100644 --- a/README.md +++ b/README.md @@ -1,87 +1,93 @@ -# biconomy-paymasters +# Biconomy Paymasters 🌐 -### Playground for ERC4337 Paymasters built with :heart_eyes: by Biconomy -#### Some examples +Welcome to the `biconomy-paymasters`` repository! Paymaster contracts enable seamless userOp fee handling in decentralized applications, offering innovative solutions similar to traditional web2 payment processing models. 🛠️ -1. Singleton Verifying Paymaster: Acts as a sponsorship paymaster and lets Dapps manage deposit without deploying a new one for each Dapp. +## What are Biconomy Paymasters? 🤔 -2. Token Paymaster: Extended version of Verifying Paymaster which can accept fees from user by withdrawing ERC20 tokens +Biconomy Paymasters, structured as smart contracts, streamline the management of gas fees, offering end-users the convenience of executing user operations without gas costs or the flexibility to pay fees with ERC20 tokens. 🚀 -#### Other WIP +- **Sponsorship Paymaster**: Allows transactions without end-users needing to pay for gas, enhancing UX. +- **Token Paymaster**: Provides the ability to pay for transactions with ERC20 tokens. -Fiat Paymaster +## Features 🌟 -Deposit Paymaster +- Simplified transaction fee handling. +- ERC 4337 Account Abstraction compliant. +- Multi-token support for gas payments. +- Hybrid Paymaster approach, combining gas sponsorship and token-based payments into a single, streamlined solution. -Custom versions of above Verifying (allow Dapp deposit sponsorship in different tokens) and Token Paymaster (acts as deposit paymaster also) +## Upcoming Features (Work in Progress) +- Fiat Paymaster (WIP): Planned feature to allow users to pay gas fees using fiat currency. +- Deposit Paymaster (WIP): Intended to enable Dapp deposit sponsorship in various tokens. +### ERC20 Token Paymaster -# How to run the project +![ERC20 Token Paymaster](./assets/readme/erc20-token-gas-payment-flow.png) -#### You're going to need to place a private key in a .env file in the root. #### +- ERC20 Token Paymaster helps users pay for their transactions using ERC20 tokens. +- Users initiate a transaction using an ERC20 token. +- Paymaster validates the transaction and covers the userOp fees.This flow ensures ease of use and convenience for users. -#### In order to add/udpate git submodule account-abstraction: #### -.gitmodules file is already added. two submodules are being used in this project +### Sponsorship Paymaster -git submodule update --init (This command will initialize and fetch the submodules listed in the .gitmodules file.) +![Sponsorship Paymaster](./assets/readme/conditional-gas-sponsorship-paymaster.png) -git submodule update --remote (This will update the submodules to the latest commit in their respective repositories.) +- Users initiate the process with their userOps. +- The operation is checked against the requirements set by the Sponsorship Paymaster. +- Once verified and approved, the Paymaster sponsors the gas fees. +- This process ensures userOps are confirmed on the network without users incurring gas costs. -you can also alternatively run forge install (or forge install ) +Note: The Paymaster's approval process is crucial, requiring a verifying party's signature to confirm sponsorship eligibility for each userOp​​. -If you encounter any issues during the submodule update process, you can try deleting the submodules directory and then running the git submodule update --init command again. +## Getting Started 🏁 -#### If you face below error, make sure typechain artifacts are generated in account-abstraction folder. #### -Error: Cannot find module '../typechain' +To set up and use the Biconomy Paymasters, you'll need to have Node.js, Yarn, Hardhat, and Foundry installed. -cd lib/account-abstraction -yarn -npx hardhat compile +### Prerequisites 📋 +Make sure you have Node.js and Yarn installed. You will also need to install Foundry for smart contract development with Solidity. -This project demonstrates an advanced Hardhat use case, integrating other tools commonly used alongside Hardhat in the ecosystem. Foundry support is also added. +### Installation 📦 -Try running some of the following tasks: +Clone the repository and install the dependencies with `yarn`: -```shell -forge build --via-ir - -npx hardhat accounts -npx hardhat compile -npx hardhat clean -npx hardhat test -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 +```bash +git clone https://github.com/bcnmy/biconomy-paymasters.git +cd biconomy-paymasters +yarn install ``` -# Etherscan verification - -To try out Etherscan verification, you first need to deploy a contract to an Ethereum network that's supported by Etherscan, such as Ropsten. +### Building the Project 🏗️ -In this project, copy the .env.example file to a file named .env, and then edit it to fill in the details. Enter your Etherscan API key, your Ropsten node URL (eg from Alchemy), and the private key of the account which will send the deployment transaction. With a valid .env file in place, first deploy your contract: +Compile your smart contracts and generate typechain artifacts: -```shell -hardhat run --network polygon_mumbai scripts/deploy.ts +```bash +yarn build ``` -Then, copy the deployment address and paste it in to replace `DEPLOYED_CONTRACT_ADDRESS` in this command: +### Running Tests 🧪 + +After building, run your tests to ensure everything is working correctly: -```shell -npx hardhat verify --network polygon_mumbai DEPLOYED_CONTRACT_ADDRESS "Hello, Hardhat!" +```bash +yarn test ``` -# Performance optimizations +This will run both Hardhat and Foundry tests as specified in your `package.json` scripts. + +## Documentation 📚 + +For more detailed information about Paymasters and how to integrate them into your project, visit the [Biconomy Paymaster Documentation](https://docs.biconomy.io/category/paymaster). + +## Foundry Installation + +For instructions on how to set up Foundryfollow the instructions provided in the [Foundry Book](https://book.getfoundry.sh/getting-started/installation.html). + +## Contributing 🤝 + +We welcome contributions from the community. Please take a look at the [guidelines for contributions](./CONTRIBUTING.md). -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). +## License 📜 +This project is licensed under the MIT License. See the [`LICENSE`](./LICENSE.md) file for more information. diff --git a/assets/readme/conditional-gas-sponsorship-paymaster.png b/assets/readme/conditional-gas-sponsorship-paymaster.png new file mode 100644 index 0000000..fb847ac Binary files /dev/null and b/assets/readme/conditional-gas-sponsorship-paymaster.png differ diff --git a/assets/readme/erc20-token-gas-payment-flow.png b/assets/readme/erc20-token-gas-payment-flow.png new file mode 100644 index 0000000..709cb8b Binary files /dev/null and b/assets/readme/erc20-token-gas-payment-flow.png differ diff --git a/assets/readme/paymaster-off-chain-request-processing-flow.png b/assets/readme/paymaster-off-chain-request-processing-flow.png new file mode 100644 index 0000000..043f649 Binary files /dev/null and b/assets/readme/paymaster-off-chain-request-processing-flow.png differ diff --git a/audits/Final Biconomy Security Assessment Report.pdf b/audits/Final Biconomy Security Assessment Report.pdf new file mode 100644 index 0000000..e7d4239 Binary files /dev/null and b/audits/Final Biconomy Security Assessment Report.pdf differ diff --git a/audits/Token Paymaster - Zellic Audit Report.pdf b/audits/Token Paymaster - Zellic Audit Report.pdf new file mode 100644 index 0000000..881e17d Binary files /dev/null and b/audits/Token Paymaster - Zellic Audit Report.pdf differ diff --git a/contracts/BasePaymaster.sol b/contracts/BasePaymaster.sol index 6a46eff..d2dc8d0 100644 --- a/contracts/BasePaymaster.sol +++ b/contracts/BasePaymaster.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.8.17; +pragma solidity ^0.8.23; /* solhint-disable reason-string */ @@ -24,21 +24,17 @@ abstract contract BasePaymaster is IPaymaster, Ownable { } /// @inheritdoc IPaymaster - function validatePaymasterUserOp( - UserOperation calldata userOp, - bytes32 userOpHash, - uint256 maxCost - ) external override returns (bytes memory context, uint256 validationData) { + function validatePaymasterUserOp(UserOperation calldata userOp, bytes32 userOpHash, uint256 maxCost) + external + override + returns (bytes memory context, uint256 validationData) + { _requireFromEntryPoint(); return _validatePaymasterUserOp(userOp, userOpHash, maxCost); } /// @inheritdoc IPaymaster - function postOp( - PostOpMode mode, - bytes calldata context, - uint256 actualGasCost - ) external override { + function postOp(PostOpMode mode, bytes calldata context, uint256 actualGasCost) external override { _requireFromEntryPoint(); _postOp(mode, context, actualGasCost); } @@ -53,10 +49,7 @@ abstract contract BasePaymaster is IPaymaster, Ownable { * @param withdrawAddress target to send to * @param amount to withdraw */ - function withdrawTo( - address payable withdrawAddress, - uint256 amount - ) external virtual; + function withdrawTo(address payable withdrawAddress, uint256 amount) external virtual; /** * add stake for this paymaster. @@ -96,11 +89,10 @@ abstract contract BasePaymaster is IPaymaster, Ownable { require(msg.sender == address(entryPoint), "Sender not EntryPoint"); } - function _validatePaymasterUserOp( - UserOperation calldata userOp, - bytes32 userOpHash, - uint256 maxCost - ) internal virtual returns (bytes memory context, uint256 validationData); + function _validatePaymasterUserOp(UserOperation calldata userOp, bytes32 userOpHash, uint256 maxCost) + internal + virtual + returns (bytes memory context, uint256 validationData); /** * post-operation handler. @@ -114,11 +106,7 @@ abstract contract BasePaymaster is IPaymaster, Ownable { * @param context - the context value returned by validatePaymasterUserOp * @param actualGasCost - actual gas used so far (without this postOp call). */ - function _postOp( - PostOpMode mode, - bytes calldata context, - uint256 actualGasCost - ) internal virtual { + function _postOp(PostOpMode mode, bytes calldata context, uint256 actualGasCost) internal virtual { (mode, context, actualGasCost); // unused params // subclass must override this method if validatePaymasterUserOp returns a context revert("must override"); diff --git a/contracts/common/Errors.sol b/contracts/common/Errors.sol index 2b758c2..a303f51 100644 --- a/contracts/common/Errors.sol +++ b/contracts/common/Errors.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: LGPL-3.0-only -pragma solidity 0.8.17; +pragma solidity ^0.8.23; contract BasePaymasterErrors { /** @@ -9,7 +9,7 @@ contract BasePaymasterErrors { error CallerIsNotAnEntryPoint(address caller); } -contract VerifyingPaymasterErrors { +contract SponsorshipPaymasterErrors { /** * @notice Throws when the Entrypoint address provided is address(0) */ @@ -20,6 +20,26 @@ contract VerifyingPaymasterErrors { */ error VerifyingSignerCannotBeZero(); + /** + * @notice Throws when the paymaster id provided is a deployed contract + */ + error PaymasterIdCannotBeContract(); + + /** + * @notice Throws when the fee collector address provided is a deployed contract + */ + error FeeCollectorCannotBeContract(); + + /** + * @notice Throws when the fee collector address provided is a deployed contract + */ + error VerifyingSignerCannotBeContract(); + + /** + * @notice Throws when the fee collector address provided is address(0) + */ + error FeeCollectorCannotBeZero(); + /** * @notice Throws when the paymaster address provided is address(0) */ diff --git a/contracts/deployer/Create3.sol b/contracts/deployer/Create3.sol index 02155f4..97c3cb9 100644 --- a/contracts/deployer/Create3.sol +++ b/contracts/deployer/Create3.sol @@ -1,36 +1,35 @@ //SPDX-License-Identifier: Unlicense -pragma solidity 0.8.17; +pragma solidity ^0.8.23; /** - @title A library for deploying contracts EIP-3171 style. - @author Agustin Aguilar -*/ + * @title A library for deploying contracts EIP-3171 style. + * @author Agustin Aguilar + */ library Create3 { /** - @notice The bytecode for a contract that proxies the creation of another contract - @dev If this code is deployed using CREATE2 it can be used to decouple `creationCode` from the child contract address + * @notice The bytecode for a contract that proxies the creation of another contract + * @dev If this code is deployed using CREATE2 it can be used to decouple `creationCode` from the child contract address + * + * 0x67363d3d37363d34f03d5260086018f3: + * 0x00 0x67 0x67XXXXXXXXXXXXXXXX PUSH8 bytecode 0x363d3d37363d34f0 + * 0x01 0x3d 0x3d RETURNDATASIZE 0 0x363d3d37363d34f0 + * 0x02 0x52 0x52 MSTORE + * 0x03 0x60 0x6008 PUSH1 08 8 + * 0x04 0x60 0x6018 PUSH1 18 24 8 + * 0x05 0xf3 0xf3 RETURN + * + * 0x363d3d37363d34f0: + * 0x00 0x36 0x36 CALLDATASIZE cds + * 0x01 0x3d 0x3d RETURNDATASIZE 0 cds + * 0x02 0x3d 0x3d RETURNDATASIZE 0 0 cds + * 0x03 0x37 0x37 CALLDATACOPY + * 0x04 0x36 0x36 CALLDATASIZE cds + * 0x05 0x3d 0x3d RETURNDATASIZE 0 cds + * 0x06 0x34 0x34 CALLVALUE val 0 cds + * 0x07 0xf0 0xf0 CREATE addr + */ - 0x67363d3d37363d34f03d5260086018f3: - 0x00 0x67 0x67XXXXXXXXXXXXXXXX PUSH8 bytecode 0x363d3d37363d34f0 - 0x01 0x3d 0x3d RETURNDATASIZE 0 0x363d3d37363d34f0 - 0x02 0x52 0x52 MSTORE - 0x03 0x60 0x6008 PUSH1 08 8 - 0x04 0x60 0x6018 PUSH1 18 24 8 - 0x05 0xf3 0xf3 RETURN - - 0x363d3d37363d34f0: - 0x00 0x36 0x36 CALLDATASIZE cds - 0x01 0x3d 0x3d RETURNDATASIZE 0 cds - 0x02 0x3d 0x3d RETURNDATASIZE 0 0 cds - 0x03 0x37 0x37 CALLDATACOPY - 0x04 0x36 0x36 CALLDATASIZE cds - 0x05 0x3d 0x3d RETURNDATASIZE 0 cds - 0x06 0x34 0x34 CALLVALUE val 0 cds - 0x07 0xf0 0xf0 CREATE addr - */ - - bytes internal constant PROXY_CHILD_BYTECODE = - hex"67_36_3d_3d_37_36_3d_34_f0_3d_52_60_08_60_18_f3"; + bytes internal constant PROXY_CHILD_BYTECODE = hex"67363d3d37363d34f03d5260086018f3"; // KECCAK256_PROXY_CHILD_BYTECODE = keccak256(PROXY_CHILD_BYTECODE); bytes32 internal constant KECCAK256_PROXY_CHILD_BYTECODE = @@ -41,17 +40,13 @@ library Create3 { error TargetAlreadyExists(); /** - @notice Creates a new contract with given `_creationCode` and `_salt` - @param _salt Salt of the contract creation, resulting address will be derivated from this value only - @param _creationCode Creation code (constructor) of the contract to be deployed, this value doesn't affect the resulting address - @param _value In WEI of ETH to be forwarded to child contract - @return addr of the deployed contract, reverts on error - */ - function create3( - bytes32 _salt, - bytes memory _creationCode, - uint256 _value - ) internal returns (address addr) { + * @notice Creates a new contract with given `_creationCode` and `_salt` + * @param _salt Salt of the contract creation, resulting address will be derivated from this value only + * @param _creationCode Creation code (constructor) of the contract to be deployed, this value doesn't affect the resulting address + * @param _value In WEI of ETH to be forwarded to child contract + * @return addr of the deployed contract, reverts on error + */ + function create3(bytes32 _salt, bytes memory _creationCode, uint256 _value) internal returns (address addr) { // Creation code bytes memory creationCode = PROXY_CHILD_BYTECODE; @@ -62,56 +57,36 @@ library Create3 { // Create CREATE2 proxy address proxy; assembly { - proxy := create2( - 0, - add(creationCode, 32), - mload(creationCode), - _salt - ) + proxy := create2(0, add(creationCode, 32), mload(creationCode), _salt) } if (proxy == address(0)) revert ErrorCreatingProxy(); // Call proxy with final init code - (bool success, ) = proxy.call{value: _value}(_creationCode); + (bool success,) = proxy.call{value: _value}(_creationCode); if (!success || codeSize(addr) == 0) revert ErrorCreatingContract(); } /** - @notice Creates a new contract with given `_creationCode` and `_salt` - @param _salt Salt of the contract creation, resulting address will be derivated from this value only - @param _creationCode Creation code (constructor) of the contract to be deployed, this value doesn't affect the resulting address - @return addr of the deployed contract, reverts on error - */ - function create3( - bytes32 _salt, - bytes memory _creationCode - ) internal returns (address addr) { + * @notice Creates a new contract with given `_creationCode` and `_salt` + * @param _salt Salt of the contract creation, resulting address will be derivated from this value only + * @param _creationCode Creation code (constructor) of the contract to be deployed, this value doesn't affect the resulting address + * @return addr of the deployed contract, reverts on error + */ + function create3(bytes32 _salt, bytes memory _creationCode) internal returns (address addr) { return create3(_salt, _creationCode, 0); } function addressOfProxy(bytes32 _salt) internal view returns (address) { - return - address( - uint160( - uint256( - keccak256( - abi.encodePacked( - hex"ff", - address(this), - _salt, - KECCAK256_PROXY_CHILD_BYTECODE - ) - ) - ) - ) - ); + return address( + uint160(uint256(keccak256(abi.encodePacked(hex"ff", address(this), _salt, KECCAK256_PROXY_CHILD_BYTECODE)))) + ); } /** - @notice Returns the size of the code on a given address - @param _addr Address that may or may not contain code - @return size of the code on the given `_addr` - */ + * @notice Returns the size of the code on a given address + * @param _addr Address that may or may not contain code + * @return size of the code on the given `_addr` + */ function codeSize(address _addr) internal view returns (uint256 size) { assembly { size := extcodesize(_addr) @@ -119,21 +94,14 @@ library Create3 { } /** - @notice Computes the resulting address of a contract deployed using address(this) and the given `_salt` - @param _salt Salt of the contract creation, resulting address will be derivated from this value only - @return addr of the deployed contract, reverts on error - - @dev The address creation formula is: keccak256(rlp([keccak256(0xff ++ address(this) ++ _salt ++ keccak256(childBytecode))[12:], 0x01])) - */ + * @notice Computes the resulting address of a contract deployed using address(this) and the given `_salt` + * @param _salt Salt of the contract creation, resulting address will be derivated from this value only + * @return addr of the deployed contract, reverts on error + * + * @dev The address creation formula is: keccak256(rlp([keccak256(0xff ++ address(this) ++ _salt ++ keccak256(childBytecode))[12:], 0x01])) + */ function addressOf(bytes32 _salt) internal view returns (address) { address proxy = addressOfProxy(_salt); - return - address( - uint160( - uint256( - keccak256(abi.encodePacked(hex"d6_94", proxy, hex"01")) - ) - ) - ); + return address(uint160(uint256(keccak256(abi.encodePacked(hex"d694", proxy, hex"01"))))); } } diff --git a/contracts/deployer/Deployer.sol b/contracts/deployer/Deployer.sol index 7571f00..421f28a 100644 --- a/contracts/deployer/Deployer.sol +++ b/contracts/deployer/Deployer.sol @@ -1,5 +1,5 @@ //SPDX-License-Identifier: Unlicense -pragma solidity 0.8.17; +pragma solidity ^0.8.23; import "./Create3.sol"; diff --git a/contracts/interfaces/IWETH9.sol b/contracts/interfaces/IWETH9.sol index 26759eb..a6999b4 100644 --- a/contracts/interfaces/IWETH9.sol +++ b/contracts/interfaces/IWETH9.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity 0.8.17; +pragma solidity ^0.8.23; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; diff --git a/contracts/interfaces/paymasters/IBiconomyTokenPaymaster.sol b/contracts/interfaces/paymasters/IBiconomyTokenPaymaster.sol new file mode 100644 index 0000000..a2d0482 --- /dev/null +++ b/contracts/interfaces/paymasters/IBiconomyTokenPaymaster.sol @@ -0,0 +1,53 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.23; + +interface IBiconomyTokenPaymaster { + /** + * price source can be off-chain calculation or oracles + * for oracle based it can be based on chainlink feeds or TWAP oracles + * for ORACLE_BASED oracle aggregator address has to be passed in paymasterAndData + */ + enum ExchangeRateSource { + EXTERNAL_EXCHANGE_RATE, + ORACLE_BASED + } + + /** + * Designed to enable the community to track change in storage variable UNACCOUNTED_COST which is used + * to maintain gas execution cost which can't be calculated within contract + */ + event EPGasOverheadChanged( + uint256 indexed _oldOverheadCost, uint256 indexed _newOverheadCost, address indexed _actor + ); + + /** + * Designed to enable the community to track change in storage variable verifyingSigner which is used + * to authorize any operation for this paymaster (validation stage) and provides signature + */ + event VerifyingSignerChanged(address indexed _oldSigner, address indexed _newSigner, address indexed _actor); + + /** + * Designed to enable the community to track change in storage variable feeReceiver which is an address (self or other SCW/EOA) + * responsible for collecting all the tokens being withdrawn as fees + */ + event FeeReceiverChanged(address indexed _oldfeeReceiver, address indexed _newfeeReceiver, address indexed _actor); + + event TokensWithdrawn(address indexed _token, address indexed _to, uint256 indexed _amount, address actor); + + /** + * Designed to enable tracking how much fees were charged from the sender and in which ERC20 token + * More information can be emitted like exchangeRate used, what was the source of exchangeRate etc + */ + // priceMarkup = Multiplier value to calculate markup, 1e6 means 1x multiplier = No markup + event TokenPaymasterOperation( + address indexed sender, + address indexed token, + uint256 indexed totalCharge, + uint32 priceMarkup, + bytes32 userOpHash, + uint128 exchangeRate, + ExchangeRateSource priceSource + ); + + event Received(address indexed sender, uint256 value); +} diff --git a/contracts/interfaces/paymasters/ISponsorshipPaymaster.sol b/contracts/interfaces/paymasters/ISponsorshipPaymaster.sol new file mode 100644 index 0000000..b36b238 --- /dev/null +++ b/contracts/interfaces/paymasters/ISponsorshipPaymaster.sol @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.23; + +interface ISponsorshipPaymaster { + event EPGasOverheadChanged(uint256 indexed _oldValue, uint256 indexed _newValue); + + event FixedPriceMarkupChanged(uint32 indexed _oldValue, uint32 indexed _newValue); + + event VerifyingSignerChanged(address indexed _oldSigner, address indexed _newSigner, address indexed _actor); + + event FeeCollectorChanged( + address indexed _oldFeeCollector, address indexed _newFeeCollector, address indexed _actor + ); + event GasDeposited(address indexed _paymasterId, uint256 indexed _value); + event GasWithdrawn(address indexed _paymasterId, address indexed _to, uint256 indexed _value); + event GasBalanceDeducted(address indexed _paymasterId, uint256 indexed _charge, bytes32 indexed userOpHash); + event PremiumCollected(address indexed _paymasterId, uint256 indexed _premium); + + /** + * @dev updates the verifyingSigner address + * @param _newVerifyingSigner The new verifyingSigner address + */ + function setSigner(address _newVerifyingSigner) external payable; + + /** + * @dev updates the postOp + unacocunted gas overhead + * @param value The new value + */ + function setUnaccountedEPGasOverhead(uint256 value) external payable; + + /** + * @dev Returns the current balance of the paymasterId(aka fundingId) + * @param paymasterId The address of the paymasterId + */ + function getBalance(address paymasterId) external view returns (uint256 balance); +} diff --git a/contracts/libs/AddressUtils.sol b/contracts/libs/AddressUtils.sol new file mode 100644 index 0000000..9858d8c --- /dev/null +++ b/contracts/libs/AddressUtils.sol @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.23; + +/** + * Utility library of inline functions on addresses + */ +library AddressUtils { + /** + * Returns whether the target address is a contract + * @dev This function will return false if invoked during the constructor of a contract, + * as the code is not actually created until after the constructor finishes. + * @param _addr address to check + * @return whether the target address is a contract + */ + function isContract(address _addr) internal view returns (bool) { + uint256 size; + // XXX Currently there is no better way to check if there is a contract in an address + // than to check the size of the code at that address. + // See https://ethereum.stackexchange.com/a/14016/36603 + // for more details about how this works. + // TODO Check this again before the Serenity release, because all addresses will be + // contracts then. + // solium-disable-next-line security/no-inline-assembly + assembly { + size := extcodesize(_addr) + } + return size > 0; + } +} diff --git a/contracts/libs/CalldataHelper.sol b/contracts/libs/CalldataHelper.sol new file mode 100644 index 0000000..3f9bf81 --- /dev/null +++ b/contracts/libs/CalldataHelper.sol @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.23; + +library CalldataHelper { + function calldataKeccak(bytes calldata data) internal pure returns (bytes32 ret) { + assembly ("memory-safe") { + let mem := mload(0x40) + let len := data.length + calldatacopy(mem, data.offset, len) + ret := keccak256(mem, len) + } + } +} diff --git a/contracts/libs/MathLib.sol b/contracts/libs/MathLib.sol new file mode 100644 index 0000000..04c0796 --- /dev/null +++ b/contracts/libs/MathLib.sol @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity ^0.8.23; + +library MathLib { + function minuint256(uint256 a, uint256 b) internal pure returns (uint256 result) { + assembly { + result := xor(b, mul(xor(b, a), gt(b, a))) + } +} + + function maxuint256(uint256 a, uint256 b) internal pure returns (uint256 result) { + assembly { + result := xor(a, mul(xor(a, b), gt(b, a))) + } + } + + function minuint32(uint32 a, uint32 b) internal pure returns (uint32 result) { + assembly { + result := xor(b, mul(xor(b, a), gt(b, a))) + } +} + + function maxuint32(uint32 a, uint32 b) internal pure returns (uint32 result) { + assembly { + result := xor(a, mul(xor(a, b), gt(b, a))) + } + } +} diff --git a/contracts/references/AdvancedVerifyingPaymaster.sol b/contracts/references/AdvancedVerifyingPaymaster.sol deleted file mode 100644 index 9872277..0000000 --- a/contracts/references/AdvancedVerifyingPaymaster.sol +++ /dev/null @@ -1,178 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0 -pragma solidity ^0.8.17; - -import {IEntryPoint} from "@account-abstraction/contracts/interfaces/IEntryPoint.sol"; -import {UserOperation} from "@account-abstraction/contracts/interfaces/UserOperation.sol"; -import {UserOperationLib} from "@account-abstraction/contracts/interfaces/UserOperation.sol"; -import {BasePaymaster} from "@account-abstraction/contracts/core/BasePaymaster.sol"; -import {ECDSA} from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; -import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; -import {Math} from "@openzeppelin/contracts/utils/math/Math.sol"; -import "@account-abstraction/contracts/core/Helpers.sol" as Helpers; - -// Stackup paymaster -/** - * A paymaster based on the eth-infinitism sample VerifyingPaymaster contract. - * It has the same functionality as the sample, but with added support for withdrawing ERC20 tokens. - * All withdrawn tokens will be transferred to the owner address. - * Note that the off-chain signer should have a strategy in place to handle a failed token withdrawal. - * - * See account-abstraction/contracts/samples/VerifyingPaymaster.sol for detailed comments. - */ -contract StackupVerifyingPaymaster is BasePaymaster { - using ECDSA for bytes32; - using UserOperationLib for UserOperation; - using SafeERC20 for IERC20; - - mapping(address => uint256) public senderNonce; - - uint256 private constant VALID_PND_OFFSET = 20; - - uint256 private constant SIGNATURE_OFFSET = 148; - - uint256 public constant POST_OP_GAS = 35000; - - constructor( - IEntryPoint _entryPoint, - address _owner - ) BasePaymaster(_entryPoint) { - _transferOwnership(_owner); - } - - function pack( - UserOperation calldata userOp - ) internal pure returns (bytes memory ret) { - bytes calldata pnd = userOp.paymasterAndData; - // solhint-disable-next-line no-inline-assembly - assembly { - let ofs := userOp - let len := sub(sub(pnd.offset, ofs), 32) - ret := mload(0x40) - mstore(0x40, add(ret, add(len, 32))) - mstore(ret, len) - calldatacopy(add(ret, 32), ofs, len) - } - } - - function getHash( - UserOperation calldata userOp, - uint48 validUntil, - uint48 validAfter, - address erc20Token, - uint256 exchangeRate - ) public view returns (bytes32) { - return - keccak256( - abi.encode( - pack(userOp), - block.chainid, - address(this), - senderNonce[userOp.getSender()], - validUntil, - validAfter, - erc20Token, - exchangeRate - ) - ); - } - - function _validatePaymasterUserOp( - UserOperation calldata userOp, - bytes32 /*userOpHash*/, - uint256 requiredPreFund - ) internal override returns (bytes memory context, uint256 validationData) { - (requiredPreFund); - - ( - uint48 validUntil, - uint48 validAfter, - address erc20Token, - uint256 exchangeRate, - bytes calldata signature - ) = parsePaymasterAndData(userOp.paymasterAndData); - // solhint-disable-next-line reason-string - require( - signature.length == 64 || signature.length == 65, - "VerifyingPaymaster: invalid signature length in paymasterAndData" - ); - bytes32 hash = ECDSA.toEthSignedMessageHash( - getHash(userOp, validUntil, validAfter, erc20Token, exchangeRate) - ); - senderNonce[userOp.getSender()]++; - context = ""; - if (erc20Token != address(0)) { - context = abi.encode( - userOp.sender, - erc20Token, - exchangeRate, - userOp.maxFeePerGas, - userOp.maxPriorityFeePerGas - ); - } - - if (owner() != ECDSA.recover(hash, signature)) { - return ( - context, - Helpers._packValidationData(true, validUntil, validAfter) - ); - } - - return ( - context, - Helpers._packValidationData(false, validUntil, validAfter) - ); - } - - function _postOp( - PostOpMode mode, - bytes calldata context, - uint256 actualGasCost - ) internal override { - ( - address sender, - IERC20 token, - uint256 exchangeRate, - uint256 maxFeePerGas, - uint256 maxPriorityFeePerGas - ) = abi.decode(context, (address, IERC20, uint256, uint256, uint256)); - - uint256 opGasPrice; - unchecked { - if (maxFeePerGas == maxPriorityFeePerGas) { - opGasPrice = maxFeePerGas; - } else { - opGasPrice = Math.min( - maxFeePerGas, - maxPriorityFeePerGas + block.basefee - ); - } - } - - uint256 actualTokenCost = ((actualGasCost + - (POST_OP_GAS * opGasPrice)) * exchangeRate) / 1e18; - if (mode != PostOpMode.postOpReverted) { - token.safeTransferFrom(sender, owner(), actualTokenCost); - } - } - - function parsePaymasterAndData( - bytes calldata paymasterAndData - ) - public - pure - returns ( - uint48 validUntil, - uint48 validAfter, - address erc20Token, - uint256 exchangeRate, - bytes calldata signature - ) - { - (validUntil, validAfter, erc20Token, exchangeRate) = abi.decode( - paymasterAndData[VALID_PND_OFFSET:SIGNATURE_OFFSET], - (uint48, uint48, address, uint256) - ); - signature = paymasterAndData[SIGNATURE_OFFSET:]; - } -} diff --git a/contracts/references/CandidePaymaster.sol b/contracts/references/CandidePaymaster.sol deleted file mode 100644 index 1adb371..0000000 --- a/contracts/references/CandidePaymaster.sol +++ /dev/null @@ -1,229 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0 -pragma solidity ^0.8.12; - -/// @author CandideWallet Team - -import "@account-abstraction/contracts/core/BasePaymaster.sol"; -import "@account-abstraction/contracts/interfaces/IEntryPoint.sol"; -import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; -import "@openzeppelin/contracts/access/Ownable.sol"; - -import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; -import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; - -contract CandidePaymaster is BasePaymaster { - using ECDSA for bytes32; - using UserOperationLib for UserOperation; - using SafeERC20 for IERC20Metadata; - - enum SponsoringMode { - FULL, - GAS, - FREE - } - - struct PaymasterData { - IERC20Metadata token; - SponsoringMode mode; - uint48 validUntil; - uint256 fee; - uint256 exchangeRate; - bytes signature; - } - - //calculated cost of the postOp - uint256 public constant COST_OF_POST = 45000; - mapping(IERC20Metadata => uint256) public balances; - // - - event UserOperationSponsored( - address indexed sender, - address indexed token, - uint256 cost - ); - - constructor( - IEntryPoint _entryPoint, - address _owner - ) BasePaymaster(_entryPoint) { - _transferOwnership(_owner); - } - - /** - * withdraw tokens. - * @param token the token deposit to withdraw - * @param target address to send to - * @param amount amount to withdraw - */ - function withdrawTokensTo( - IERC20Metadata token, - address target, - uint256 amount - ) public { - require(owner() == msg.sender, "CP00: only owner can withdraw tokens"); - balances[token] -= amount; - token.safeTransfer(target, amount); - } - - function pack( - UserOperation calldata userOp - ) internal pure returns (bytes32) { - return - keccak256( - abi.encode( - userOp.sender, - userOp.nonce, - keccak256(userOp.initCode), - keccak256(userOp.callData), - userOp.callGasLimit, - userOp.verificationGasLimit, - userOp.preVerificationGas, - userOp.maxFeePerGas, - userOp.maxPriorityFeePerGas - ) - ); - } - - /** - * return the hash we're going to sign off-chain (and validate on-chain) - * this method is called by the off-chain service, to sign the request. - * it is called on-chain from the validatePaymasterUserOp, to validate the signature. - * note that this signature covers all fields of the UserOperation, except the "paymasterAndData", - * which will carry the signature itself. - */ - function getHash( - UserOperation calldata userOp, - PaymasterData memory paymasterData - ) public view returns (bytes32) { - return - keccak256( - abi.encode( - pack(userOp), - block.chainid, - address(this), - address(paymasterData.token), - paymasterData.mode, - paymasterData.validUntil, - paymasterData.fee, - paymasterData.exchangeRate - ) - ); - } - - function parsePaymasterAndData( - bytes calldata paymasterAndData - ) public pure returns (PaymasterData memory) { - IERC20Metadata token = IERC20Metadata( - address(bytes20(paymasterAndData[20:40])) - ); - SponsoringMode mode = SponsoringMode( - uint8(bytes1(paymasterAndData[40:41])) - ); - uint48 validUntil = uint48(bytes6(paymasterAndData[41:47])); - uint256 fee = uint256(bytes32(paymasterAndData[47:79])); - uint256 exchangeRate = uint256(bytes32(paymasterAndData[79:111])); - bytes memory signature = bytes(paymasterAndData[111:]); - return - PaymasterData( - token, - mode, - validUntil, - fee, - exchangeRate, - signature - ); - } - - /** - * Verify our external signer signed this request and decode paymasterData - * paymasterData contains the following: - * token address length 20 - * signature length 64 or 65 - */ - function _validatePaymasterUserOp( - UserOperation calldata userOp, - bytes32 userOpHash, - uint256 /** maxCost */ - ) - internal - virtual - override - returns (bytes memory context, uint256 validationData) - { - (userOpHash); - - PaymasterData memory paymasterData = parsePaymasterAndData( - userOp.paymasterAndData - ); - require( - paymasterData.signature.length == 64 || - paymasterData.signature.length == 65, - "CP01: invalid signature length in paymasterAndData" - ); - - bytes32 _hash = getHash(userOp, paymasterData).toEthSignedMessageHash(); - if (owner() != _hash.recover(paymasterData.signature)) { - return ("", _packValidationData(true, paymasterData.validUntil, 0)); - } - - address account = userOp.getSender(); - uint256 gasPriceUserOp = userOp.gasPrice(); - bytes memory _context = abi.encode( - account, - paymasterData.token, - paymasterData.mode, - paymasterData.fee, - paymasterData.exchangeRate, - gasPriceUserOp - ); - - return ( - _context, - _packValidationData(false, paymasterData.validUntil, 0) - ); - } - - /** - * Perform the post-operation to charge the sender for the gas. - */ - function _postOp( - PostOpMode mode, - bytes calldata context, - uint256 actualGasCost - ) internal override { - ( - address account, - IERC20Metadata token, - SponsoringMode sponsoringMode, - uint256 fee, - uint256 exchangeRate, - uint256 gasPricePostOp - ) = abi.decode( - context, - ( - address, - IERC20Metadata, - SponsoringMode, - uint256, - uint256, - uint256 - ) - ); - if (sponsoringMode == SponsoringMode.FREE) return; - // - uint256 actualTokenCost = ((actualGasCost + - (COST_OF_POST * gasPricePostOp)) * exchangeRate) / 1e18; - if (sponsoringMode == SponsoringMode.FULL) { - actualTokenCost = actualTokenCost + fee; - } - if (mode != PostOpMode.postOpReverted) { - token.safeTransferFrom(account, address(this), actualTokenCost); - balances[token] += actualTokenCost; - emit UserOperationSponsored( - account, - address(token), - actualTokenCost - ); - } - } -} diff --git a/contracts/references/infinitism/IOracle.sol b/contracts/references/infinitism/IOracle.sol deleted file mode 100644 index 12d9954..0000000 --- a/contracts/references/infinitism/IOracle.sol +++ /dev/null @@ -1,17 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -interface IOracle { - function decimals() external view returns (uint8); - - function latestRoundData() - external - view - returns ( - uint80 roundId, - int256 answer, - uint256 startedAt, - uint256 updatedAt, - uint80 answeredInRound - ); -} diff --git a/contracts/references/infinitism/OracleHelper.sol b/contracts/references/infinitism/OracleHelper.sol deleted file mode 100644 index 8fccf45..0000000 --- a/contracts/references/infinitism/OracleHelper.sol +++ /dev/null @@ -1,154 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.8.17; - -/* solhint-disable not-rely-on-time */ - -import "@uniswap/v3-periphery/contracts/interfaces/ISwapRouter.sol"; - -import "./IOracle.sol"; - -/// @title Helper functions for dealing with various forms of price feed oracles. -/// @notice Maintains a price cache and updates the current price if needed. -/// In the best case scenario we have a direct oracle from the token to the native asset. -/// Also support tokens that have no direct price oracle to the native asset. -/// Sometimes oracles provide the price in the opposite direction of what we need in the moment. -abstract contract OracleHelper { - event TokenPriceUpdated(uint256 currentPrice, uint256 previousPrice); - - uint256 private constant PRICE_DENOMINATOR = 1e26; - - struct OracleHelperConfig { - /// @notice The Oracle contract used to fetch the latest token prices - IOracle tokenOracle; - /// @notice The Oracle contract used to fetch the latest ETH prices - IOracle nativeOracle; - /// @notice If 'true' we will fetch price directly from tokenOracle - /// @notice If 'false' we will use nativeOracle to establish a token price through a shared third currency - bool tokenToNativeOracle; - /// @notice 'true' if price is dollars-per-token (or ether-per-token), 'false' if price is tokens-per-dollar - bool tokenOracleReverse; - /// @notice 'false' if price is dollars-per-ether, 'true' if price is ether-per-dollar - bool nativeOracleReverse; - /// @notice The price update threshold percentage that triggers a price update (1e6 = 100%) - uint256 priceUpdateThreshold; - /// @notice The price cache will be returned without even fetching the oracles for this number of seconds - uint256 cacheTimeToLive; - } - - /// @notice The cached token price from the Oracle, always in (ether-per-token) * PRICE_DENOMINATOR format - uint256 public cachedPrice; - - /// @notice The timestamp of a block when the cached price was updated - uint256 public cachedPriceTimestamp; - - OracleHelperConfig private oracleHelperConfig; - - /// @notice The "10^(tokenOracle.decimals)" value used for the price calculation - uint256 private tokenOracleDecimalPower; - - /// @notice The "10^(nativeOracle.decimals)" value used for the price calculation - uint256 private nativeOracleDecimalPower; - - constructor(OracleHelperConfig memory _oracleHelperConfig) { - cachedPrice = type(uint256).max; // initialize the storage slot to invalid value - _setOracleConfiguration(_oracleHelperConfig); - } - - function _setOracleConfiguration( - OracleHelperConfig memory _oracleHelperConfig - ) internal { - oracleHelperConfig = _oracleHelperConfig; - require( - _oracleHelperConfig.priceUpdateThreshold <= 1e6, - "TPM: update threshold too high" - ); - tokenOracleDecimalPower = - 10 ** oracleHelperConfig.tokenOracle.decimals(); - nativeOracleDecimalPower = - 10 ** oracleHelperConfig.nativeOracle.decimals(); - } - - /// @notice Updates the token price by fetching the latest price from the Oracle. - function updateCachedPrice(bool force) public returns (uint256 newPrice) { - uint256 cacheTimeToLive = oracleHelperConfig.cacheTimeToLive; - uint256 priceUpdateThreshold = oracleHelperConfig.priceUpdateThreshold; - IOracle tokenOracle = oracleHelperConfig.tokenOracle; - IOracle nativeOracle = oracleHelperConfig.nativeOracle; - - uint256 cacheAge = block.timestamp - cachedPriceTimestamp; - if (!force && cacheAge <= cacheTimeToLive) { - return cachedPrice; - } - uint256 _cachedPrice = cachedPrice; - uint256 tokenPrice = fetchPrice(tokenOracle); - uint256 nativeAssetPrice = 1; - // If the 'TokenOracle' returns the price in the native asset units there is no need to fetch native asset price - if (!oracleHelperConfig.tokenToNativeOracle) { - nativeAssetPrice = fetchPrice(nativeOracle); - } - uint256 price = calculatePrice( - tokenPrice, - nativeAssetPrice, - oracleHelperConfig.tokenOracleReverse, - oracleHelperConfig.nativeOracleReverse - ); - uint256 priceNewByOld = (price * PRICE_DENOMINATOR) / _cachedPrice; - - bool updateRequired = force || - priceNewByOld > PRICE_DENOMINATOR + priceUpdateThreshold || - priceNewByOld < PRICE_DENOMINATOR - priceUpdateThreshold; - if (!updateRequired) { - return _cachedPrice; - } - uint256 previousPrice = _cachedPrice; - _cachedPrice = price; - cachedPrice = _cachedPrice; - emit TokenPriceUpdated(_cachedPrice, previousPrice); - return _cachedPrice; - } - - function calculatePrice( - uint256 tokenPrice, - uint256 nativeAssetPrice, - bool tokenOracleReverse, - bool nativeOracleReverse - ) private view returns (uint256) { - if (tokenOracleReverse) { - tokenPrice = - (PRICE_DENOMINATOR * tokenOracleDecimalPower) / - tokenPrice; - } else { - tokenPrice = - (PRICE_DENOMINATOR * tokenPrice) / - tokenOracleDecimalPower; - } - - if (nativeOracleReverse) { - return (nativeAssetPrice * tokenPrice) / nativeOracleDecimalPower; - } else { - return (tokenPrice * nativeOracleDecimalPower) / nativeAssetPrice; - } - } - - /// @notice Fetches the latest price from the given Oracle. - /// @dev This function is used to get the latest price from the tokenOracle or nativeOracle. - /// @param _oracle The Oracle contract to fetch the price from. - /// @return price The latest price fetched from the Oracle. - function fetchPrice(IOracle _oracle) internal view returns (uint256 price) { - ( - uint80 roundId, - int256 answer, - , - uint256 updatedAt, - uint80 answeredInRound - ) = _oracle.latestRoundData(); - require(answer > 0, "TPM: Chainlink price <= 0"); - // 2 days old price is considered stale since the price is updated every 24 hours - require( - updatedAt >= block.timestamp - 60 * 60 * 24 * 2, - "TPM: Incomplete round" - ); - require(answeredInRound >= roundId, "TPM: Stale price"); - price = uint256(answer); - } -} diff --git a/contracts/references/infinitism/SampleTokenPaymaster.sol b/contracts/references/infinitism/SampleTokenPaymaster.sol deleted file mode 100644 index b227c2f..0000000 --- a/contracts/references/infinitism/SampleTokenPaymaster.sol +++ /dev/null @@ -1,274 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0 -pragma solidity ^0.8.12; - -// Import the required libraries and contracts -import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; -import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; -import "@openzeppelin/contracts/utils/cryptography/EIP712.sol"; - -import "@account-abstraction/contracts/core/EntryPoint.sol"; -import "@account-abstraction/contracts/core/BasePaymaster.sol"; -import "./UniswapHelper.sol"; -import "./OracleHelper.sol"; - -// OG GSN same correlation https://github.com/opengsn/gsn/blob/master/packages/paymasters/contracts/TokenPaymaster.sol - -// TODO: note https://github.com/pimlicolabs/erc20-paymaster-contracts/issues/10 -// TODO: set a hard limit on how much gas a single user op may cost (postOp to fix the price) -/// @title Sample ERC-20 Token Paymaster for ERC-4337 -/// @notice Based on Pimlico 'PimlicoERC20Paymaster' and OpenGSN 'PermitERC20UniswapV3Paymaster' -/// This Paymaster covers gas fees in exchange for ERC20 tokens charged using allowance pre-issued by ERC-4337 accounts. -/// The contract refunds excess tokens if the actual gas cost is lower than the initially provided amount. -/// The token price cannot be queried in the validation code due to storage access restrictions of ERC-4337. -/// The price is cached inside the contract and is updated in the 'postOp' stage if the change is >10%. -/// It is theoretically possible the token has depreciated so much since the last 'postOp' the refund becomes negative. -/// The contract reverts the inner user transaction in that case but keeps the charge. -/// The contract also allows honest clients to prepay tokens at a higher price to avoid getting reverted. -/// It also allows updating price configuration and withdrawing tokens by the contract owner. -/// The contract uses an Oracle to fetch the latest token prices. -/// @dev Inherits from BasePaymaster. -contract TokenPaymaster is BasePaymaster, UniswapHelper, OracleHelper { - struct TokenPaymasterConfig { - /// @notice The price markup percentage applied to the token price (1e6 = 100%) - uint256 priceMarkup; - /// @notice Exchange tokens to native currency if the EntryPoint balance of this Paymaster falls below this value - uint256 minEntryPointBalance; - } - - event ConfigUpdated(TokenPaymasterConfig tokenPaymasterConfig); - - event UserOperationSponsored( - address indexed user, - uint256 actualTokenCharge, - uint256 actualGasCost, - uint256 actualTokenPrice - ); - - event PostOpReverted(address indexed user, uint256 preCharge); - - event Received(address indexed sender, uint256 value); - - /// @notice All 'price' variables are multiplied by this value to avoid rounding up - uint256 private constant PRICE_DENOMINATOR = 1e6; - - /// @notice Estimated gas cost for refunding tokens after the transaction is completed - uint256 public constant REFUND_POSTOP_COST = 40000; - - TokenPaymasterConfig private tokenPaymasterConfig; - - // TODO: I don't like defaults in Solidity - accept ALL parameters of fail!!! - /// @notice Initializes the PimlicoERC20Paymaster contract with the given parameters. - /// @param _token The ERC20 token used for transaction fee payments. - /// @param _entryPoint The EntryPoint contract used in the Account Abstraction infrastructure. - /// @ param _tokenOracle The Oracle contract used to fetch the latest token prices. - /// @ param _nativeAssetOracle The Oracle contract used to fetch the latest native asset (ETH, Matic, Avax, etc.) prices. - /// @param _owner The address that will be set as the owner of the contract. - constructor( - IERC20Metadata _token, - IEntryPoint _entryPoint, - IERC20 _wrappedNative, - ISwapRouter _uniswap, - TokenPaymasterConfig memory _tokenPaymasterConfig, - OracleHelperConfig memory _oracleHelperConfig, - UniswapHelperConfig memory _uniswapHelperConfig, - address _owner - ) - BasePaymaster(_entryPoint) - OracleHelper(_oracleHelperConfig) - UniswapHelper( - _token, - _wrappedNative, - _uniswap, - 10 ** _token.decimals(), - _uniswapHelperConfig - ) - { - setTokenPaymasterConfig(_tokenPaymasterConfig); - transferOwnership(_owner); - } - - /// @notice Updates the configuration for the Token Paymaster. - /// @param _tokenPaymasterConfig The new price markup percentage (1e6 = 100%). - function setTokenPaymasterConfig( - TokenPaymasterConfig memory _tokenPaymasterConfig - ) public onlyOwner { - require( - _tokenPaymasterConfig.priceMarkup <= 2 * PRICE_DENOMINATOR, - "TPM: price markup too high" - ); - require( - _tokenPaymasterConfig.priceMarkup >= PRICE_DENOMINATOR, - "TPM: price markup too low" - ); - tokenPaymasterConfig = _tokenPaymasterConfig; - emit ConfigUpdated(_tokenPaymasterConfig); - } - - function setOracleConfiguration( - OracleHelperConfig memory _oracleHelperConfig - ) external onlyOwner { - _setOracleConfiguration(_oracleHelperConfig); - } - - function setUniswapConfiguration( - UniswapHelperConfig memory _uniswapHelperConfig - ) external onlyOwner { - _setUniswapHelperConfiguration(_uniswapHelperConfig); - } - - /// @notice Allows the contract owner to withdraw a specified amount of tokens from the contract. - /// @param to The address to transfer the tokens to. - /// @param amount The amount of tokens to transfer. - function withdrawToken(address to, uint256 amount) external onlyOwner { - SafeERC20.safeTransfer(token, to, amount); - } - - /// @notice Validates a paymaster user operation and calculates the required token amount for the transaction. - /// @param userOp The user operation data. - /// @param requiredPreFund The amount of tokens required for pre-funding. - /// @return context The context containing the token amount and user sender address (if applicable). - /// @return validationResult A uint256 value indicating the result of the validation (always 0 in this implementation). - function _validatePaymasterUserOp( - UserOperation calldata userOp, - bytes32, - uint256 requiredPreFund - ) - internal - override - returns (bytes memory context, uint256 validationResult) - { - unchecked { - uint256 priceMarkup = tokenPaymasterConfig.priceMarkup; - uint256 paymasterAndDataLength = userOp.paymasterAndData.length - - 20; - require( - paymasterAndDataLength == 0 || paymasterAndDataLength == 32, - "TPM: invalid data length" - ); - uint256 preChargeNative = requiredPreFund + - (REFUND_POSTOP_COST * userOp.maxFeePerGas); - // note: as price is in ether-per-token and we want more tokens increasing it means dividing it by markup - uint256 cachedPriceWithMarkup = (cachedPrice * PRICE_DENOMINATOR) / - priceMarkup; - if (paymasterAndDataLength == 32) { - uint256 clientSuppliedPrice = uint256( - bytes32(userOp.paymasterAndData[20:52]) - ); - if (clientSuppliedPrice < cachedPriceWithMarkup) { - // note: smaller number means 'more ether per token' - cachedPriceWithMarkup = clientSuppliedPrice; - } - } - uint256 tokenAmount = weiToToken( - preChargeNative, - cachedPriceWithMarkup - ); - SafeERC20.safeTransferFrom( - token, - userOp.sender, - address(this), - tokenAmount - ); - context = abi.encodePacked( - tokenAmount, - userOp.maxFeePerGas, - userOp.maxPriorityFeePerGas, - userOp.sender - ); - validationResult = 0; - } - } - - /// @notice Performs post-operation tasks, such as updating the token price and refunding excess tokens. - /// @dev This function is called after a user operation has been executed or reverted. - /// @param mode The post-operation mode (either successful or reverted). - /// @param context The context containing the token amount and user sender address. - /// @param actualGasCost The actual gas cost of the transaction. - function _postOp( - PostOpMode mode, - bytes calldata context, - uint256 actualGasCost - ) internal override { - unchecked { - uint256 priceMarkup = tokenPaymasterConfig.priceMarkup; - uint256 preCharge = uint256(bytes32(context[0:32])); - uint256 maxFeePerGas = uint256(bytes32(context[32:64])); - uint256 maxPriorityFeePerGas = uint256(bytes32(context[64:96])); - uint256 gasPrice = getGasPrice(maxFeePerGas, maxPriorityFeePerGas); - address userOpSender = address(bytes20(context[96:116])); - if (mode == PostOpMode.postOpReverted) { - emit PostOpReverted(userOpSender, preCharge); - // Do nothing here to not revert the whole bundle and harm reputation - return; - } - uint256 _cachedPrice = updateCachedPrice(false); - // note: as price is in ether-per-token and we want more tokens increasing it means dividing it by markup - uint256 cachedPriceWithMarkup = (_cachedPrice * PRICE_DENOMINATOR) / - priceMarkup; - // Refund tokens based on actual gas cost - uint256 actualChargeNative = actualGasCost + - REFUND_POSTOP_COST * - gasPrice; - uint256 actualTokenNeeded = weiToToken( - actualChargeNative, - cachedPriceWithMarkup - ); - if (preCharge > actualTokenNeeded) { - // If the initially provided token amount is greater than the actual amount needed, refund the difference - SafeERC20.safeTransfer( - token, - userOpSender, - preCharge - actualTokenNeeded - ); - } else if (preCharge < actualTokenNeeded) { - // Attempt to cover Paymaster's gas expenses by withdrawing the 'overdraft' from the client - // If the transfer reverts also revert the 'postOp' to remove the incentive to cheat - SafeERC20.safeTransferFrom( - token, - userOpSender, - address(this), - actualTokenNeeded - preCharge - ); - } - - emit UserOperationSponsored( - userOpSender, - actualTokenNeeded, - actualGasCost, - cachedPrice - ); - refillEntryPointDeposit(_cachedPrice); - } - } - - /// @notice If necessary this function uses this Paymaster's token balance to refill the deposit on EntryPoint - function refillEntryPointDeposit(uint256 _cachedPrice) private { - uint256 currentEntryPointBalance = entryPoint.balanceOf(address(this)); - if ( - currentEntryPointBalance < tokenPaymasterConfig.minEntryPointBalance - ) { - uint256 swappedWeth = _maybeSwapTokenToWeth(token, _cachedPrice); - unwrapWeth(swappedWeth); - entryPoint.depositTo{value: address(this).balance}(address(this)); - } - } - - function getGasPrice( - uint256 maxFeePerGas, - uint256 maxPriorityFeePerGas - ) internal view returns (uint256) { - if (maxFeePerGas == maxPriorityFeePerGas) { - //legacy mode (for networks that don't support basefee opcode) - return maxFeePerGas; - } - return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee); - } - - function min(uint256 a, uint256 b) internal pure returns (uint256) { - return a < b ? a : b; - } - - receive() external payable { - emit Received(msg.sender, msg.value); - } -} diff --git a/contracts/references/infinitism/UniswapHelper.sol b/contracts/references/infinitism/UniswapHelper.sol deleted file mode 100644 index 6c0a19e..0000000 --- a/contracts/references/infinitism/UniswapHelper.sol +++ /dev/null @@ -1,158 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.8.17; - -/* solhint-disable not-rely-on-time */ - -import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; - -import "@uniswap/v3-periphery/contracts/interfaces/ISwapRouter.sol"; -import "@uniswap/v3-periphery/contracts/interfaces/IPeripheryPayments.sol"; - -abstract contract UniswapHelper { - event UniswapReverted( - address tokenIn, - address tokenOut, - uint256 amountIn, - uint256 amountOutMin - ); - - uint256 private constant PRICE_DENOMINATOR = 1e26; - - struct UniswapHelperConfig { - /// @notice Minimum native asset amount to receive from a single swap - uint256 minSwapAmount; - uint24 uniswapPoolFee; - uint8 slippage; - } - - /// @notice The Uniswap V3 SwapRouter contract - ISwapRouter public immutable uniswap; - - /// @notice The ERC20 token used for transaction fee payments - IERC20 public immutable token; - - /// @notice The ERC-20 token that wraps the native asset for current chain - IERC20 public immutable wrappedNative; - - UniswapHelperConfig private uniswapHelperConfig; - - /// @notice The "10^(token.decimals)" value used for the price calculation - uint256 private immutable tokenDecimalPower; - - constructor( - IERC20 _token, - IERC20 _wrappedNative, - ISwapRouter _uniswap, - uint256 _tokenDecimalPower, - UniswapHelperConfig memory _uniswapHelperConfig - ) { - _token.approve(address(_uniswap), type(uint256).max); - token = _token; - wrappedNative = _wrappedNative; - uniswap = _uniswap; - tokenDecimalPower = _tokenDecimalPower; - _setUniswapHelperConfiguration(_uniswapHelperConfig); - } - - function _setUniswapHelperConfiguration( - UniswapHelperConfig memory _uniswapHelperConfig - ) internal { - uniswapHelperConfig = _uniswapHelperConfig; - } - - function _maybeSwapTokenToWeth( - IERC20 tokenIn, - uint256 quote - ) internal returns (uint256) { - uint256 tokenBalance = tokenIn.balanceOf(address(this)); - uint256 amountOutMin = addSlippage( - tokenToWei(tokenBalance, quote), - uniswapHelperConfig.slippage - ); - if (amountOutMin < uniswapHelperConfig.minSwapAmount) { - return 0; - } - // note: calling 'swapToToken' but destination token is Wrapped Ether - return - swapToToken( - address(tokenIn), - address(wrappedNative), - tokenBalance, - amountOutMin, - uniswapHelperConfig.uniswapPoolFee - ); - } - - function addSlippage( - uint256 amount, - uint8 slippage - ) private pure returns (uint256) { - return (amount * (1000 - slippage)) / 1000; - } - - function tokenToWei( - uint256 amount, - uint256 price - ) public pure returns (uint256) { - return (amount * price) / PRICE_DENOMINATOR; - } - - function weiToToken( - uint256 amount, - uint256 price - ) public pure returns (uint256) { - return (amount * PRICE_DENOMINATOR) / price; - } - - // turn ERC-20 tokens into wrapped ETH at market price - function swapToWeth( - address tokenIn, - address wethOut, - uint256 amountOut, - uint24 fee - ) internal returns (uint256 amountIn) { - ISwapRouter.ExactOutputSingleParams memory params = ISwapRouter - .ExactOutputSingleParams( - tokenIn, - wethOut, //tokenOut - fee, - address(uniswap), //recipient - keep WETH at SwapRouter for withdrawal - block.timestamp, //deadline - amountOut, - type(uint256).max, - 0 - ); - amountIn = uniswap.exactOutputSingle(params); - } - - function unwrapWeth(uint256 amount) internal { - IPeripheryPayments(address(uniswap)).unwrapWETH9(amount, address(this)); - } - - // swap ERC-20 tokens at market price - function swapToToken( - address tokenIn, - address tokenOut, - uint256 amountIn, - uint256 amountOutMin, - uint24 fee - ) internal returns (uint256 amountOut) { - ISwapRouter.ExactInputSingleParams memory params = ISwapRouter - .ExactInputSingleParams( - tokenIn, //tokenIn - tokenOut, //tokenOut - fee, - address(uniswap), - block.timestamp, //deadline - amountIn, - amountOutMin, - 0 - ); - try uniswap.exactInputSingle(params) returns (uint256 _amountOut) { - amountOut = _amountOut; - } catch { - emit UniswapReverted(tokenIn, tokenOut, amountIn, amountOutMin); - amountOut = 0; - } - } -} diff --git a/contracts/references/pimlico/IOracle.sol b/contracts/references/pimlico/IOracle.sol deleted file mode 100644 index 43a4c5b..0000000 --- a/contracts/references/pimlico/IOracle.sol +++ /dev/null @@ -1,17 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.17; - -interface IOracle { - function decimals() external view returns (uint8); - - function latestRoundData() - external - view - returns ( - uint80 roundId, - int256 answer, - uint256 startedAt, - uint256 updatedAt, - uint80 answeredInRound - ); -} diff --git a/contracts/references/pimlico/PimlicoERC20Paymaster.sol b/contracts/references/pimlico/PimlicoERC20Paymaster.sol deleted file mode 100644 index e82a371..0000000 --- a/contracts/references/pimlico/PimlicoERC20Paymaster.sol +++ /dev/null @@ -1,232 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.8.17; - -// Import the required libraries and contracts -import "@account-abstraction/contracts/core/BasePaymaster.sol"; -import "@account-abstraction/contracts/core/Helpers.sol"; -import "@account-abstraction/contracts/interfaces/UserOperation.sol"; -import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; -import "@openzeppelin/contracts/utils/cryptography/EIP712.sol"; -import "./IOracle.sol"; -import "@account-abstraction/contracts/core/EntryPoint.sol"; -import "../../utils/SafeTransferLib.sol"; - -/// @title PimlicoERC20Paymaster -/// @notice An ERC-4337 Paymaster contract by Pimlico which is able to sponsor gas fees in exchange for ERC20 tokens. -/// The contract refunds excess tokens if the actual gas cost is lower than the initially provided amount. -/// It also allows updating price configuration and withdrawing tokens by the contract owner. -/// The contract uses an Oracle to fetch the latest token prices. -/// @dev Inherits from BasePaymaster. - -contract PimlicoERC20Paymaster is BasePaymaster { - uint256 public constant priceDenominator = 1e6; - uint256 public constant REFUND_POSTOP_COST = 40000; // Estimated gas cost for refunding tokens after the transaction is completed - - // The token, tokenOracle, and nativeAssetOracle are declared as immutable, - // meaning their values cannot change after contract creation. - IERC20 public immutable token; // The ERC20 token used for transaction fee payments - uint256 public immutable tokenDecimals; - IOracle public immutable tokenOracle; // The Oracle contract used to fetch the latest token prices - IOracle public immutable nativeAssetOracle; // The Oracle contract used to fetch the latest ETH prices - - uint192 public previousPrice; // The cached token price from the Oracle - uint32 public priceMarkup; // The price markup percentage applied to the token price (1e6 = 100%) - uint32 public priceUpdateThreshold; // The price update threshold percentage that triggers a price update (1e6 = 100%) - - event ConfigUpdated(uint32 priceMarkup, uint32 updateThreshold); - - event UserOperationSponsored( - address indexed user, - uint256 actualTokenNeeded, - uint256 actualGasCost - ); - - /// @notice Initializes the PimlicoERC20Paymaster contract with the given parameters. - /// @param _token The ERC20 token used for transaction fee payments. - /// @param _entryPoint The EntryPoint contract used in the Account Abstraction infrastructure. - /// @param _tokenOracle The Oracle contract used to fetch the latest token prices. - /// @param _nativeAssetOracle The Oracle contract used to fetch the latest native asset (ETH, Matic, Avax, etc.) prices. - /// @param _owner The address that will be set as the owner of the contract. - constructor( - IERC20Metadata _token, - IEntryPoint _entryPoint, - IOracle _tokenOracle, - IOracle _nativeAssetOracle, - address _owner - ) BasePaymaster(_entryPoint) { - token = _token; - tokenOracle = _tokenOracle; // oracle for token -> usd - nativeAssetOracle = _nativeAssetOracle; // oracle for native asset(eth/matic/avax..) -> usd - priceMarkup = 110e4; // 110% 1e6 = 100% - priceUpdateThreshold = 25e3; // 2.5% 1e6 = 100% - transferOwnership(_owner); - tokenDecimals = 10 ** _token.decimals(); - require( - _tokenOracle.decimals() == 8, - "PP-ERC20 : token oracle decimals must be 8" - ); - require( - _nativeAssetOracle.decimals() == 8, - "PP-ERC20 : native asset oracle decimals must be 8" - ); - } - - /// @notice Updates the price markup and price update threshold configurations. - /// @param _priceMarkup The new price markup percentage (1e6 = 100%). - /// @param _updateThreshold The new price update threshold percentage (1e6 = 100%). - function updateConfig( - uint32 _priceMarkup, - uint32 _updateThreshold - ) external onlyOwner { - require(_priceMarkup <= 120e4, "PP-ERC20 : price markup too high"); - require(_priceMarkup >= 1e6, "PP-ERC20 : price markeup too low"); - require( - _updateThreshold <= 1e6, - "PP-ERC20 : update threshold too high" - ); - priceMarkup = _priceMarkup; - priceUpdateThreshold = _updateThreshold; - emit ConfigUpdated(_priceMarkup, _updateThreshold); - } - - /// @notice Allows the contract owner to withdraw a specified amount of tokens from the contract. - /// @param to The address to transfer the tokens to. - /// @param amount The amount of tokens to transfer. - function withdrawToken(address to, uint256 amount) external onlyOwner { - SafeTransferLib.safeTransfer(address(token), to, amount); - } - - /// @notice Updates the token price by fetching the latest price from the Oracle. - function updatePrice() external { - // This function updates the cached ERC20/ETH price ratio - uint192 tokenPrice = fetchPrice(tokenOracle); - uint192 nativeAssetPrice = fetchPrice(nativeAssetOracle); - previousPrice = - (nativeAssetPrice * uint192(tokenDecimals)) / - tokenPrice; - } - - /// @notice Validates a paymaster user operation and calculates the required token amount for the transaction. - /// @param userOp The user operation data. - /// @param requiredPreFund The amount of tokens required for pre-funding. - /// @return context The context containing the token amount and user sender address (if applicable). - /// @return validationResult A uint256 value indicating the result of the validation (always 0 in this implementation). - function _validatePaymasterUserOp( - UserOperation calldata userOp, - bytes32, - uint256 requiredPreFund - ) - internal - override - returns (bytes memory context, uint256 validationResult) - { - unchecked { - uint256 cachedPrice = previousPrice; - require(cachedPrice != 0, "PP-ERC20 : price not set"); - uint256 length = userOp.paymasterAndData.length - 20; - // 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdf is the mask for the last 6 bits 011111 which mean length should be 100000(32) || 000000(0) - require( - length & - 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdf == - 0, - "PP-ERC20 : invalid data length" - ); - // NOTE: we assumed that nativeAsset's decimals is 18, if there is any nativeAsset with different decimals, need to change the 1e18 to the correct decimals - uint256 tokenAmount = ((requiredPreFund + - (REFUND_POSTOP_COST) * - userOp.maxFeePerGas) * - priceMarkup * - cachedPrice) / (1e18 * priceDenominator); - if (length == 32) { - require( - tokenAmount <= - uint256(bytes32(userOp.paymasterAndData[20:52])), - "PP-ERC20 : token amount too high" - ); - } - SafeTransferLib.safeTransferFrom( - address(token), - userOp.sender, - address(this), - tokenAmount - ); - context = abi.encodePacked(tokenAmount, userOp.sender); - // No return here since validationData == 0 and we have context saved in memory - validationResult = 0; - } - } - - /// @notice Performs post-operation tasks, such as updating the token price and refunding excess tokens. - /// @dev This function is called after a user operation has been executed or reverted. - /// @param mode The post-operation mode (either successful or reverted). - /// @param context The context containing the token amount and user sender address. - /// @param actualGasCost The actual gas cost of the transaction. - function _postOp( - PostOpMode mode, - bytes calldata context, - uint256 actualGasCost - ) internal override { - if (mode == PostOpMode.postOpReverted) { - return; // Do nothing here to not revert the whole bundle and harm reputation - } - unchecked { - uint192 tokenPrice = fetchPrice(tokenOracle); - uint192 nativeAsset = fetchPrice(nativeAssetOracle); - uint256 cachedPrice = previousPrice; - uint192 price = (nativeAsset * uint192(tokenDecimals)) / tokenPrice; - uint256 cachedUpdateThreshold = priceUpdateThreshold; - if ( - (uint256(price) * priceDenominator) / cachedPrice > - priceDenominator + cachedUpdateThreshold || - (uint256(price) * priceDenominator) / cachedPrice < - priceDenominator - cachedUpdateThreshold - ) { - previousPrice = uint192(int192(price)); - cachedPrice = uint192(int192(price)); - } - // Refund tokens based on actual gas cost - // NOTE: we assumed that nativeAsset's decimals is 18, if there is any nativeAsset with different decimals, need to change the 1e18 to the correct decimals - uint256 actualTokenNeeded = ((actualGasCost + - REFUND_POSTOP_COST * - tx.gasprice) * - priceMarkup * - cachedPrice) / (1e18 * priceDenominator); // We use tx.gasprice here since we don't know the actual gas price used by the user - if (uint256(bytes32(context[0:32])) > actualTokenNeeded) { - // If the initially provided token amount is greater than the actual amount needed, refund the difference - SafeTransferLib.safeTransfer( - address(token), - address(bytes20(context[32:52])), - uint256(bytes32(context[0:32])) - actualTokenNeeded - ); - } // If the token amount is not greater than the actual amount needed, no refund occurs - - emit UserOperationSponsored( - address(bytes20(context[32:52])), - actualTokenNeeded, - actualGasCost - ); - } - } - - /// @notice Fetches the latest price from the given Oracle. - /// @dev This function is used to get the latest price from the tokenOracle or nativeAssetOracle. - /// @param _oracle The Oracle contract to fetch the price from. - /// @return price The latest price fetched from the Oracle. - function fetchPrice(IOracle _oracle) internal view returns (uint192 price) { - ( - uint80 roundId, - int256 answer, - , - uint256 updatedAt, - uint80 answeredInRound - ) = _oracle.latestRoundData(); - require(answer > 0, "PP-ERC20 : Chainlink price <= 0"); - // 2 days old price is considered stale since the price is updated every 24 hours - require( - updatedAt >= block.timestamp - 60 * 60 * 24 * 2, - "PP-ERC20 : Incomplete round" - ); - require(answeredInRound >= roundId, "PP-ERC20 : Stale price"); - price = uint192(int192(answer)); - } -} diff --git a/contracts/references/soul/IPriceOracle.sol b/contracts/references/soul/IPriceOracle.sol deleted file mode 100644 index f2a6c63..0000000 --- a/contracts/references/soul/IPriceOracle.sol +++ /dev/null @@ -1,8 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.17; - -interface IPriceOracle { - function exchangePrice( - address _token - ) external view returns (uint256 price, uint8 decimals); -} diff --git a/contracts/references/soul/ITokenPaymaster.sol b/contracts/references/soul/ITokenPaymaster.sol deleted file mode 100644 index 4ae128b..0000000 --- a/contracts/references/soul/ITokenPaymaster.sol +++ /dev/null @@ -1,34 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.17; - -import "@account-abstraction/contracts/interfaces/IPaymaster.sol"; -import "@openzeppelin/contracts/utils/introspection/ERC165.sol"; - -interface ITokenPaymaster is IPaymaster, IERC165 { - /** - * @dev Emitted when token is added. - */ - event TokenAdded(address token); - - /** - * @dev Emitted when token is removed. - */ - event TokenRemoved(address token); - - /** - * @dev Returns the supported entrypoint. - */ - function entryPoint() external view returns (address); - - /** - * @dev Returns true if this contract supports the given token address. - */ - function isSupportedToken(address _token) external view returns (bool); - - /** - * @dev Returns the exchange price of the token in wei. - */ - function exchangePrice( - address _token - ) external view returns (uint256, uint8); -} diff --git a/contracts/references/soul/PriceOracle.sol b/contracts/references/soul/PriceOracle.sol deleted file mode 100644 index ed3a7fb..0000000 --- a/contracts/references/soul/PriceOracle.sol +++ /dev/null @@ -1,36 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.17; - -import "./IPriceOracle.sol"; -import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol"; - -contract PriceOracle is IPriceOracle { - /** - * @notice for security reason, the price feed is immutable - */ - AggregatorV3Interface public immutable priceFeed; - - mapping(address => bool) private supportedToken; - - constructor(AggregatorV3Interface _priceFeed) { - priceFeed = _priceFeed; - supportedToken[address(0)] = true; - } - - function exchangePrice( - address token - ) external view override returns (uint256 price, uint8 decimals) { - (token); - ( - , - /* uint80 roundID */ int256 _price /*uint256 startedAt*/ /*uint256 timeStamp*/ /*uint80 answeredInRound*/, - , - , - - ) = priceFeed.latestRoundData(); - // price -> uint256 - require(_price >= 0, "price is negative"); - price = uint256(_price); - decimals = priceFeed.decimals(); - } -} diff --git a/contracts/references/soul/TokenPaymaster.sol b/contracts/references/soul/TokenPaymaster.sol deleted file mode 100644 index 6f7c310..0000000 --- a/contracts/references/soul/TokenPaymaster.sol +++ /dev/null @@ -1,361 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.17; - -import "@openzeppelin/contracts/access/Ownable.sol"; -import "./ITokenPaymaster.sol"; -import {IEntryPoint} from "@account-abstraction/contracts/interfaces/IEntryPoint.sol"; -import "./IPriceOracle.sol"; -import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; -import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; - -contract TokenPaymaster is ITokenPaymaster, Ownable { - using UserOperationLib for UserOperation; - using SafeERC20 for IERC20; - - IEntryPoint public immutable _IEntryPoint; - address public immutable walletFactory; - - mapping(address => IPriceOracle) private supportedToken; - - // calculated cost of the postOp - uint256 private constant COST_OF_POST = 40000; - - // Trusted token approve gas cost - uint256 private constant SAFE_APPROVE_GAS_COST = 50000; - - constructor( - IEntryPoint _entryPoint, - address _owner, - address _walletFactory - ) { - require(address(_entryPoint) != address(0), "invalid etnrypoint addr"); - _IEntryPoint = _entryPoint; - - if (_owner != address(0)) { - _transferOwnership(_owner); - } - require( - address(_walletFactory) != address(0), - "invalid etnrypoint addr" - ); - walletFactory = _walletFactory; - } - - /** - * @dev Returns the supported entrypoint. - */ - function entryPoint() external view override returns (address) { - return address(_IEntryPoint); - } - - /** - * @dev Returns true if this contract supports the given token address. - */ - function isSupportedToken( - address _token - ) external view override returns (bool) { - return _isSupportedToken(_token); - } - - /** - * @dev Returns the exchange price of the token in wei. - */ - function exchangePrice( - address _token - ) external view override returns (uint256 price, uint8 decimals) { - /* - Note the current alpha version of paymaster is using storage other than - `account storage`, bundler needs to whitelist the current paymaster. - (this means that the bundler has to take some risk itself) - */ - - (price, decimals) = supportedToken[_token].exchangePrice(_token); - price = (price * 99) / 100; // 1% conver chainlink `Deviation threshold` - } - - /** - * @dev add a token to the supported token list. - */ - function setToken( - address[] calldata _token, - address[] calldata _priceOracle - ) external onlyOwner { - require(_token.length == _priceOracle.length, "length mismatch"); - for (uint256 i = 0; i < _token.length; i++) { - address token = _token[i]; - address priceOracle = _priceOracle[i]; - require(token != address(0), "token cannot be zero address"); - address currentPriceOracle = address(supportedToken[token]); - if (priceOracle == address(0)) { - if (currentPriceOracle != address(0)) { - // remove token - delete supportedToken[token]; - emit TokenRemoved(token); - } - } else { - if (currentPriceOracle != address(0)) { - emit TokenRemoved(currentPriceOracle); - } - supportedToken[token] = IPriceOracle(priceOracle); - emit TokenAdded(token); - } - } - } - - function validatePaymasterUserOp( - UserOperation calldata userOp, - bytes32 userOpHash, - uint256 maxCost - ) external view override returns (bytes memory context, uint256 deadline) { - _requireFromEntryPoint(); - return _validatePaymasterUserOp(userOp, userOpHash, maxCost); - } - - function postOp( - PostOpMode mode, - bytes calldata context, - uint256 actualGasCost - ) external override { - _requireFromEntryPoint(); - _postOp(mode, context, actualGasCost); - } - - function _decodeApprove( - bytes memory func - ) private pure returns (address spender, uint256 value) { - // 0x095ea7b3 approve(address,uint256) - // 0x095ea7b3 address uint256 - // ____4_____|____32___|___32__ - - require(bytes4(func) == bytes4(0x095ea7b3), "invalid approve func"); - assembly { - spender := mload(add(func, 36)) // 32 + 4 - value := mload(add(func, 68)) // 32 + 4 +32 - } - } - - function _validateConstructor( - UserOperation calldata userOp, - address token, - uint256 tokenRequiredPreFund - ) internal view { - address factory = address(bytes20(userOp.initCode)); - require(factory == walletFactory, "unknown wallet factory"); - require( - bytes4(userOp.callData) == - bytes4( - 0x2763604f /* 0x2763604f execFromEntryPoint(address[],uint256[],bytes[]) */ - ), - "invalid callData" - ); - ( - address[] memory dest, - uint256[] memory value, - bytes[] memory func - ) = abi.decode(userOp.callData[4:], (address[], uint256[], bytes[])); - require( - dest.length == value.length && dest.length == func.length, - "invalid callData" - ); - - address _destAddress = address(0); - for (uint256 i = 0; i < dest.length; i++) { - address destAddr = dest[i]; - require(_isSupportedToken(destAddr), "unsupported token"); - if (destAddr == token) { - (address spender, uint256 amount) = _decodeApprove(func[i]); - require(spender == address(this), "invalid spender"); - require(amount >= tokenRequiredPreFund, "not enough approve"); - } - require(destAddr > _destAddress, "duplicate"); - _destAddress = destAddr; - } - // callGasLimit - uint256 callGasLimit = dest.length * SAFE_APPROVE_GAS_COST; - require( - userOp.callGasLimit >= callGasLimit, - "Paymaster: gas too low for postOp" - ); - } - - function _validatePaymasterUserOp( - UserOperation calldata userOp, - bytes32 /*userOpHash*/, - uint256 requiredPreFund - ) private view returns (bytes memory context, uint256 deadline) { - require( - userOp.verificationGasLimit > 45000, - "Paymaster: gas too low for postOp" - ); - - address sender = userOp.getSender(); - - // paymasterAndData: [paymaster, token, maxCost] - (address token, uint256 maxCost) = abi.decode( - userOp.paymasterAndData[20:], - (address, uint256) - ); - IERC20 ERC20Token = IERC20(token); - - (uint256 _price, uint8 _decimals) = this.exchangePrice(token); - uint8 tokenDecimals = IERC20Metadata(token).decimals(); - - // #risk: overflow - // exchangeRate = ( _price * 10^tokenDecimals ) / 10^_decimals / 10^18 - uint256 exchangeRate = (_price * 10 ** tokenDecimals) / 10 ** _decimals; // ./10^18 - // tokenRequiredPreFund = requiredPreFund * exchangeRate / 10^18 - - uint256 costOfPost = userOp.gasPrice() * COST_OF_POST; - - uint256 tokenRequiredPreFund = ((requiredPreFund + costOfPost) * - exchangeRate) / 10 ** 18; - - require(tokenRequiredPreFund <= maxCost, "Paymaster: maxCost too low"); - - if (userOp.initCode.length != 0) { - _validateConstructor(userOp, token, tokenRequiredPreFund); - } else { - require( - ERC20Token.allowance(sender, address(this)) >= - tokenRequiredPreFund, - "Paymaster: not enough allowance" - ); - } - - require( - ERC20Token.balanceOf(sender) >= tokenRequiredPreFund, - "Paymaster: not enough balance" - ); - - return (abi.encode(sender, token, costOfPost, exchangeRate), 0); - } - - /** - * post-operation handler. - * (verified to be called only through the entryPoint) - * @dev if subclass returns a non-empty context from validatePaymasterUserOp, it must also implement this method. - * @param mode enum with the following options: - * opSucceeded - user operation succeeded. - * opReverted - user op reverted. still has to pay for gas. - * postOpReverted - user op succeeded, but caused postOp (in mode=opSucceeded) to revert. - * Now this is the 2nd call, after user's op was deliberately reverted. - * @param context - the context value returned by validatePaymasterUserOp - * @param actualGasCost - actual gas used so far (without this postOp call). - */ - function _postOp( - PostOpMode mode, - bytes calldata context, - uint256 actualGasCost - ) private { - (mode); - ( - address sender, - address payable token, - uint256 costOfPost, - uint256 exchangeRate - ) = abi.decode(context, (address, address, uint256, uint256)); - uint256 tokenRequiredFund = ((actualGasCost + costOfPost) * - exchangeRate) / 10 ** 18; - IERC20(token).safeTransferFrom( - sender, - address(this), - tokenRequiredFund - ); - } - - /** - * add a deposit for this paymaster, used for paying for transaction fees - */ - function deposit() public payable { - _IEntryPoint.depositTo{value: msg.value}(address(this)); - } - - /** - * withdraw value from the deposit - * @param withdrawAddress target to send to - * @param amount to withdraw - */ - function withdrawTo( - address payable withdrawAddress, - uint256 amount - ) public onlyOwner { - _IEntryPoint.withdrawTo(withdrawAddress, amount); - } - - /** - * add stake for this paymaster. - * This method can also carry eth value to add to the current stake. - * @param unstakeDelaySec - the unstake delay for this paymaster. Can only be increased. - */ - function addStake(uint32 unstakeDelaySec) external payable onlyOwner { - _IEntryPoint.addStake{value: msg.value}(unstakeDelaySec); - } - - /** - * return current paymaster's deposit on the entryPoint. - */ - function getDeposit() public view returns (uint256) { - return _IEntryPoint.balanceOf(address(this)); - } - - /** - * unlock the stake, in order to withdraw it. - * The paymaster can't serve requests once unlocked, until it calls addStake again - */ - function unlockStake() external onlyOwner { - _IEntryPoint.unlockStake(); - } - - /** - * withdraw the entire paymaster's stake. - * stake must be unlocked first (and then wait for the unstakeDelay to be over) - * @param withdrawAddress the address to send withdrawn value. - */ - function withdrawStake(address payable withdrawAddress) external onlyOwner { - _IEntryPoint.withdrawStake(withdrawAddress); - } - - // withdraw token from this contract - function withdrawToken( - address token, - address to, - uint256 amount - ) external onlyOwner { - _withdrawToken(token, to, amount); - } - - // withdraw token from this contract - function withdrawToken( - address[] calldata token, - address to, - uint256[] calldata amount - ) external onlyOwner { - require(token.length == amount.length, "length mismatch"); - for (uint256 i = 0; i < token.length; i++) { - _withdrawToken(token[i], to, amount[i]); - } - } - - /** - * @dev See {IERC165-supportsInterface}. - */ - function supportsInterface( - bytes4 interfaceId - ) public pure override(IERC165) returns (bool) { - return interfaceId == type(ITokenPaymaster).interfaceId; - } - - function _withdrawToken(address token, address to, uint256 amount) private { - IERC20(token).transfer(to, amount); - } - - function _isSupportedToken(address _token) private view returns (bool) { - return address(supportedToken[_token]) != address(0); - } - - /// validate the call is made from a valid entrypoint - function _requireFromEntryPoint() private view { - require(msg.sender == address(_IEntryPoint)); - } -} diff --git a/contracts/verifying/PaymasterHelpers.sol b/contracts/sponsorship/PaymasterHelpers.sol similarity index 57% rename from contracts/verifying/PaymasterHelpers.sol rename to contracts/sponsorship/PaymasterHelpers.sol index 09b9cdf..5b533ba 100644 --- a/contracts/verifying/PaymasterHelpers.sol +++ b/contracts/sponsorship/PaymasterHelpers.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.8.17; +pragma solidity ^0.8.23; import {ECDSA} from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; import {UserOperation} from "@account-abstraction/contracts/interfaces/UserOperation.sol"; @@ -40,38 +40,19 @@ library PaymasterHelpers { /** * @dev Decodes paymaster data assuming it follows PaymasterData */ - function _decodePaymasterData( - UserOperation calldata op - ) internal pure returns (PaymasterData memory) { + function _decodePaymasterData(UserOperation calldata op) internal pure returns (PaymasterData memory) { bytes calldata paymasterAndData = op.paymasterAndData; - ( - address paymasterId, - uint48 validUntil, - uint48 validAfter, - bytes memory signature - ) = abi.decode(paymasterAndData[20:], (address, uint48, uint48, bytes)); - return - PaymasterData( - paymasterId, - validUntil, - validAfter, - signature, - signature.length - ); + (address paymasterId, uint48 validUntil, uint48 validAfter, bytes memory signature) = + abi.decode(paymasterAndData[20:], (address, uint48, uint48, bytes)); + return PaymasterData(paymasterId, validUntil, validAfter, signature, signature.length); } /** * @dev Decodes paymaster context assuming it follows PaymasterContext */ - function _decodePaymasterContext( - bytes memory context - ) internal pure returns (PaymasterContext memory) { - ( - address paymasterId, - uint256 maxFeePerGas, - uint256 maxPriorityFeePerGas - ) = abi.decode(context, (address, uint256, uint256)); - return - PaymasterContext(paymasterId, maxFeePerGas, maxPriorityFeePerGas); + function _decodePaymasterContext(bytes memory context) internal pure returns (PaymasterContext memory) { + (address paymasterId, uint256 maxFeePerGas, uint256 maxPriorityFeePerGas) = + abi.decode(context, (address, uint256, uint256)); + return PaymasterContext(paymasterId, maxFeePerGas, maxPriorityFeePerGas); } } diff --git a/contracts/sponsorship/SponsorshipPaymaster.sol b/contracts/sponsorship/SponsorshipPaymaster.sol new file mode 100644 index 0000000..83ba35d --- /dev/null +++ b/contracts/sponsorship/SponsorshipPaymaster.sol @@ -0,0 +1,339 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity ^0.8.23; + +/* solhint-disable reason-string */ +/* solhint-disable no-inline-assembly */ +import {ECDSA} from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; +import {ReentrancyGuard} from "@openzeppelin/contracts/security/ReentrancyGuard.sol"; +import {UserOperation, UserOperationLib} from "@account-abstraction/contracts/interfaces/UserOperation.sol"; +import "../BasePaymaster.sol"; +import {SponsorshipPaymasterErrors} from "../common/Errors.sol"; +import {MathLib} from "../libs/MathLib.sol"; +import {AddressUtils} from "../libs/AddressUtils.sol"; +import {ISponsorshipPaymaster} from "../interfaces/paymasters/ISponsorshipPaymaster.sol"; + +/** + * @title SponsorshipPaymaster + * @author livingrockrises + * @notice Based on Infinitism 'VerifyingPaymaster' contract + * @dev This contract is used to sponsor the transaction fees of the user operations + * Uses a verifying signer to provide the signature if predetermined conditions are met + * regarding the user operation calldata. Also this paymaster is Singleton in nature which + * means multiple Dapps/Wallet clients willing to sponsor the transactions can share this paymaster. + * Maintains it's own accounting of the gas balance for each Dapp/Wallet client + * and Manages it's own deposit on the EntryPoint. + */ +contract SponsorshipPaymaster is + BasePaymaster, + ReentrancyGuard, + SponsorshipPaymasterErrors, + ISponsorshipPaymaster +{ + using ECDSA for bytes32; + using AddressUtils for address; + using UserOperationLib for UserOperation; + + uint32 private constant PRICE_DENOMINATOR = 1e6; + + // paymasterAndData: concat of [paymasterAddress(address), paymasterId(20 bytes), validUntil(6 bytes), validAfter(6 bytes), priceMarkup(4 bytes), signature] + uint256 private constant VALID_PND_OFFSET = 20; + + // Gas used in EntryPoint._handlePostOp() method (including this#postOp() call) + uint256 private unaccountedEPGasOverhead; + + mapping(address => uint256) public paymasterIdBalances; + + address public verifyingSigner; + + address public feeCollector; + + constructor( + address _owner, + IEntryPoint _entryPoint, + address _verifyingSigner, + address _feeCollector + ) payable BasePaymaster(_owner, _entryPoint) { + if (address(_entryPoint) == address(0)) revert EntryPointCannotBeZero(); + if (_verifyingSigner == address(0)) + revert VerifyingSignerCannotBeZero(); + if (_feeCollector == address(0)) revert FeeCollectorCannotBeZero(); + assembly { + sstore(verifyingSigner.slot, _verifyingSigner) + sstore(feeCollector.slot, _feeCollector) + } + unaccountedEPGasOverhead = 18500; + } + + /** + * @dev Add a deposit for this paymaster and given paymasterId (Dapp Depositor address), used for paying for transaction fees + * @param paymasterId dapp identifier for which deposit is being made + */ + function depositFor(address paymasterId) external payable nonReentrant { + if (paymasterId == address(0)) revert PaymasterIdCannotBeZero(); + if (msg.value == 0) revert DepositCanNotBeZero(); + paymasterIdBalances[paymasterId] += msg.value; + entryPoint.depositTo{value: msg.value}(address(this)); + emit GasDeposited(paymasterId, msg.value); + } + + /** + * @dev Set a new verifying signer address. + * Can only be called by the owner of the contract. + * @param _newVerifyingSigner The new address to be set as the verifying signer. + * @notice If _newVerifyingSigner is set to zero address, it will revert with an error. + * After setting the new signer address, it will emit an event VerifyingSignerChanged. + */ + function setSigner( + address _newVerifyingSigner + ) external payable override onlyOwner { + if(_newVerifyingSigner.isContract()) revert VerifyingSignerCannotBeContract(); + if (_newVerifyingSigner == address(0)) + revert VerifyingSignerCannotBeZero(); + address oldSigner = verifyingSigner; + assembly { + sstore(verifyingSigner.slot, _newVerifyingSigner) + } + emit VerifyingSignerChanged(oldSigner, _newVerifyingSigner, msg.sender); + } + + /** + * @dev Set a new fee collector address. + * Can only be called by the owner of the contract. + * @param _newFeeCollector The new address to be set as the fee collector. + * @notice If _newFeeCollector is set to zero address, it will revert with an error. + * After setting the new fee collector address, it will emit an event FeeCollectorChanged. + */ + function setFeeCollector( + address _newFeeCollector + ) external payable onlyOwner { + if (_newFeeCollector == address(0)) revert FeeCollectorCannotBeZero(); + address oldFeeCollector = feeCollector; + assembly { + sstore(feeCollector.slot, _newFeeCollector) + } + emit FeeCollectorChanged(oldFeeCollector, _newFeeCollector, msg.sender); + } + + /** + * @dev Set a new unaccountedEPGasOverhead value. + * @param value The new value to be set as the unaccountedEPGasOverhead. + * @notice only to be called by the owner of the contract. + */ + function setUnaccountedEPGasOverhead( + uint256 value + ) external payable onlyOwner { + require(value <= 200000, "Gas overhead too high"); + uint256 oldValue = unaccountedEPGasOverhead; + unaccountedEPGasOverhead = value; + emit EPGasOverheadChanged(oldValue, value); + } + + /** + * @dev get the current deposit for paymasterId (Dapp Depositor address) + * @param paymasterId dapp identifier + */ + function getBalance( + address paymasterId + ) external view returns (uint256 balance) { + balance = paymasterIdBalances[paymasterId]; + } + + /** + @dev Override the default implementation. + */ + function deposit() public payable virtual override { + revert("Use depositFor() instead"); + } + + /** + * @dev Withdraws the specified amount of gas tokens from the paymaster's balance and transfers them to the specified address. + * @param withdrawAddress The address to which the gas tokens should be transferred. + * @param amount The amount of gas tokens to withdraw. + */ + function withdrawTo( + address payable withdrawAddress, + uint256 amount + ) public override nonReentrant { + if (withdrawAddress == address(0)) revert CanNotWithdrawToZeroAddress(); + uint256 currentBalance = paymasterIdBalances[msg.sender]; + require(amount <= currentBalance, "Sponsorship Paymaster: Insufficient funds to withdraw from gas tank"); + paymasterIdBalances[msg.sender] = currentBalance - amount; + entryPoint.withdrawTo(withdrawAddress, amount); + emit GasWithdrawn(msg.sender, withdrawAddress, amount); + } + + /** + * @dev This method is called by the off-chain service, to sign the request. + * It is called on-chain from the validatePaymasterUserOp, to validate the signature. + * @notice That this signature covers all fields of the UserOperation, except the "paymasterAndData", + * which will carry the signature itself. + * @return hash we're going to sign off-chain (and validate on-chain) + */ + function getHash( + UserOperation calldata userOp, + address paymasterId, + uint48 validUntil, + uint48 validAfter, + uint32 priceMarkup + ) public view returns (bytes32) { + //can't use userOp.hash(), since it contains also the paymasterAndData itself. + return + keccak256( + abi.encode( + userOp.getSender(), + userOp.nonce, + userOp.initCode, + userOp.callData, + userOp.callGasLimit, + userOp.verificationGasLimit, + userOp.preVerificationGas, + userOp.maxFeePerGas, + userOp.maxPriorityFeePerGas, + block.chainid, + address(this), + paymasterId, + validUntil, + validAfter, + priceMarkup + ) + ); + } + + function parsePaymasterAndData( + bytes calldata paymasterAndData + ) + public + pure + returns ( + address paymasterId, + uint48 validUntil, + uint48 validAfter, + uint32 priceMarkup, + bytes calldata signature + ) + { + paymasterId = address(bytes20(paymasterAndData[VALID_PND_OFFSET:VALID_PND_OFFSET+20])); + validUntil = uint48(bytes6(paymasterAndData[VALID_PND_OFFSET+20:VALID_PND_OFFSET+26])); + validAfter = uint48(bytes6(paymasterAndData[VALID_PND_OFFSET+26:VALID_PND_OFFSET+32])); + priceMarkup = uint32(bytes4(paymasterAndData[VALID_PND_OFFSET+32:VALID_PND_OFFSET+36])); + signature = paymasterAndData[VALID_PND_OFFSET+36:]; + } + + /** + * @dev Executes the paymaster's payment conditions + * @param context payment conditions signed by the paymaster in `validatePaymasterUserOp` + * @param actualGasCost amount to be paid to the entry point in wei + */ + function _postOp( + PostOpMode /** mode */, + bytes calldata context, + uint256 actualGasCost + ) internal virtual override { + ( + address paymasterId, + uint32 dynamicMarkup, + uint256 maxFeePerGas, + uint256 maxPriorityFeePerGas, + bytes32 userOpHash + ) = abi.decode(context, (address, uint32, uint256, uint256, bytes32)); + + uint256 effectiveGasPrice = getGasPrice( + maxFeePerGas, + maxPriorityFeePerGas + ); + + uint256 balToDeduct = actualGasCost + + unaccountedEPGasOverhead * + effectiveGasPrice; + + uint256 costIncludingPremium = (balToDeduct * dynamicMarkup) / + PRICE_DENOMINATOR; + + // deduct with premium + paymasterIdBalances[paymasterId] -= costIncludingPremium; + + uint256 actualPremium = costIncludingPremium - balToDeduct; + // "collect" premium + paymasterIdBalances[feeCollector] += actualPremium; + + emit GasBalanceDeducted(paymasterId, costIncludingPremium, userOpHash); + // Review if we should emit balToDeduct as well + emit PremiumCollected(paymasterId, actualPremium); + } + + /** + * @dev Verify that an external signer signed the paymaster data of a user operation. + * The paymaster data is expected to be the paymaster and a signature over the entire request parameters. + * @param userOp The UserOperation struct that represents the current user operation. + * userOpHash The hash of the UserOperation struct. + * @param requiredPreFund The required amount of pre-funding for the paymaster. + * @return context A context string returned by the entry point after successful validation. + * @return validationData An integer returned by the entry point after successful validation. + */ + function _validatePaymasterUserOp( + UserOperation calldata userOp, + bytes32 userOpHash, + uint256 requiredPreFund + ) internal override returns (bytes memory context, uint256 validationData) { + ( + address paymasterId, + uint48 validUntil, + uint48 validAfter, + uint32 priceMarkup, + bytes calldata signature + ) = parsePaymasterAndData(userOp.paymasterAndData); + + bytes32 hash = getHash( + userOp, + paymasterId, + validUntil, + validAfter, + priceMarkup + ); + uint256 sigLength = signature.length; + // we only "require" it here so that the revert reason on invalid signature will be of "VerifyingPaymaster", and not "ECDSA" + require(sigLength == 65, "Sponsorship Paymaster:invalid paymaster signature length"); + //don't revert on signature failure: return SIG_VALIDATION_FAILED + if ( + verifyingSigner != hash.toEthSignedMessageHash().recover(signature) + ) { + // empty context and sigFailed with time range provided + return (context, _packValidationData(true, validUntil, validAfter)); + } + + require(priceMarkup <= 2e6 && priceMarkup > 0, "Sponsorship Paymaster: Invalid markup %"); + // Send 1e6 for No markup + // Send between 0 and 1e6 for discount + + uint256 effectiveCost = (requiredPreFund * priceMarkup) / + PRICE_DENOMINATOR; + + require(effectiveCost <= paymasterIdBalances[paymasterId], "Sponsorship Paymaster: paymasterId does not have enough deposit"); + + context = abi.encode( + paymasterId, + priceMarkup, + userOp.maxFeePerGas, + userOp.maxPriorityFeePerGas, + userOpHash + ); + + return (context, _packValidationData(false, validUntil, validAfter)); + } + + // Note: do not use this in validation phase + function getGasPrice( + uint256 maxFeePerGas, + uint256 maxPriorityFeePerGas + ) internal view returns (uint256) { + if (maxFeePerGas == maxPriorityFeePerGas) { + //legacy mode (for networks that don't support basefee opcode) + return maxFeePerGas; + } + return + MathLib.minuint256( + maxFeePerGas, + maxPriorityFeePerGas + block.basefee + ); + } +} \ No newline at end of file diff --git a/contracts/test/accounts/BiconomyAccountFactory.sol b/contracts/test/accounts/BiconomyAccountFactory.sol index 9a3e532..bd12df7 100644 --- a/contracts/test/accounts/BiconomyAccountFactory.sol +++ b/contracts/test/accounts/BiconomyAccountFactory.sol @@ -1,13 +1,12 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.17; +pragma solidity ^0.8.23; // temp // Could also use published package or added submodule. -import {SmartAccountFactory} from "@biconomy-devx/account-contracts-v2/contracts/smart-account/factory/SmartAccountFactory.sol"; +// temp +import {SmartAccountFactory} from + "@biconomy-devx/account-contracts-v2/contracts/smart-account/factory/SmartAccountFactory.sol"; contract BiconomyAccountFactory is SmartAccountFactory { - constructor( - address _basicImplementation, - address _newOwner - ) SmartAccountFactory(_basicImplementation, _newOwner) {} + constructor(address _basicImplementation, address _newOwner) SmartAccountFactory(_basicImplementation, _newOwner) {} } diff --git a/contracts/test/accounts/BiconomyAccountImpl.sol b/contracts/test/accounts/BiconomyAccountImpl.sol index 2870b41..9eca396 100644 --- a/contracts/test/accounts/BiconomyAccountImpl.sol +++ b/contracts/test/accounts/BiconomyAccountImpl.sol @@ -1,8 +1,8 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.17; +pragma solidity ^0.8.23; import {IEntryPoint} from "@account-abstraction/contracts/interfaces/IEntryPoint.sol"; -import {SmartAccount} from "../../../lib/scw-contracts/contracts/smart-account/SmartAccount.sol"; +import {SmartAccount} from "@biconomy-devx/account-contracts-v2/contracts/smart-account/SmartAccount.sol"; // Note: Could also use published package or added submodule. diff --git a/contracts/test/accounts/SimpleAccount.sol b/contracts/test/accounts/SimpleAccount.sol index 6674984..4f42104 100644 --- a/contracts/test/accounts/SimpleAccount.sol +++ b/contracts/test/accounts/SimpleAccount.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.8.17; +pragma solidity ^0.8.23; /* solhint-disable avoid-low-level-calls */ /* solhint-disable no-inline-assembly */ @@ -17,22 +17,14 @@ import "@account-abstraction/contracts/samples/callback/TokenCallbackHandler.sol * has execute, eth handling methods * has a single signer that can send requests through the entryPoint. */ -contract SimpleAccount is - BaseAccount, - TokenCallbackHandler, - UUPSUpgradeable, - Initializable -{ +contract SimpleAccount is BaseAccount, TokenCallbackHandler, UUPSUpgradeable, Initializable { using ECDSA for bytes32; address public owner; IEntryPoint private immutable _entryPoint; - event SimpleAccountInitialized( - IEntryPoint indexed entryPoint, - address indexed owner - ); + event SimpleAccountInitialized(IEntryPoint indexed entryPoint, address indexed owner); modifier onlyOwner() { _onlyOwner(); @@ -54,20 +46,13 @@ contract SimpleAccount is function _onlyOwner() internal view { //directly from EOA owner, or through the account itself (which gets redirected through execute()) - require( - msg.sender == owner || msg.sender == address(this), - "only owner" - ); + require(msg.sender == owner || msg.sender == address(this), "only owner"); } /** * execute a transaction (called directly from owner, or by entryPoint) */ - function execute( - address dest, - uint256 value, - bytes calldata func - ) external { + function execute(address dest, uint256 value, bytes calldata func) external { _requireFromEntryPointOrOwner(); _call(dest, value, func); } @@ -75,10 +60,7 @@ contract SimpleAccount is /** * execute a sequence of transactions */ - function executeBatch( - address[] calldata dest, - bytes[] calldata func - ) external { + function executeBatch(address[] calldata dest, bytes[] calldata func) external { _requireFromEntryPointOrOwner(); require(dest.length == func.length, "wrong array lengths"); for (uint256 i = 0; i < dest.length; i++) { @@ -102,20 +84,20 @@ contract SimpleAccount is // Require the function call went through EntryPoint or owner function _requireFromEntryPointOrOwner() internal view { - require( - msg.sender == address(entryPoint()) || msg.sender == owner, - "account: not Owner or EntryPoint" - ); + require(msg.sender == address(entryPoint()) || msg.sender == owner, "account: not Owner or EntryPoint"); } /// implement template method of BaseAccount - function _validateSignature( - UserOperation calldata userOp, - bytes32 userOpHash - ) internal virtual override returns (uint256 validationData) { + function _validateSignature(UserOperation calldata userOp, bytes32 userOpHash) + internal + virtual + override + returns (uint256 validationData) + { bytes32 hash = userOpHash.toEthSignedMessageHash(); - if (owner != hash.recover(userOp.signature)) + if (owner != hash.recover(userOp.signature)) { return SIG_VALIDATION_FAILED; + } return 0; } @@ -147,16 +129,11 @@ contract SimpleAccount is * @param withdrawAddress target to send to * @param amount to withdraw */ - function withdrawDepositTo( - address payable withdrawAddress, - uint256 amount - ) public onlyOwner { + function withdrawDepositTo(address payable withdrawAddress, uint256 amount) public onlyOwner { entryPoint().withdrawTo(withdrawAddress, amount); } - function _authorizeUpgrade( - address newImplementation - ) internal view override { + function _authorizeUpgrade(address newImplementation) internal view override { (newImplementation); _onlyOwner(); } diff --git a/contracts/test/dex/UniV3Integration.sol b/contracts/test/dex/UniV3Integration.sol deleted file mode 100644 index e1dfc56..0000000 --- a/contracts/test/dex/UniV3Integration.sol +++ /dev/null @@ -1,37 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.17; - -import "@uniswap/v3-periphery/contracts/interfaces/ISwapRouter.sol"; - -contract UniV3Integration { - ISwapRouter router = - ISwapRouter(0xE592427A0AEce92De3Edee1F18E0157C05861564); - - // note: deployed version of this contract can be used to query necessary calldata - function prepareExactInputSingleCalldata( - address tokenIn, - address tokenOut, - uint24 fee, - address recipient, - uint256 amountIn - ) public view returns (bytes memory) { - ISwapRouter.ExactInputSingleParams memory params = ISwapRouter - .ExactInputSingleParams({ - tokenIn: tokenIn, - tokenOut: tokenOut, - fee: fee, - recipient: recipient, - deadline: block.timestamp + (2 hours), - amountIn: amountIn, - amountOutMinimum: 0, - sqrtPriceLimitX96: 0 - }); - - bytes memory _data = abi.encodeWithSelector( - ISwapRouter.exactInputSingle.selector, - params - ); - - return _data; - } -} diff --git a/contracts/test/dex/UniswapV3SwapExamples.sol b/contracts/test/dex/UniswapV3SwapExamples.sol deleted file mode 100644 index c50621c..0000000 --- a/contracts/test/dex/UniswapV3SwapExamples.sol +++ /dev/null @@ -1,125 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.17; - -// swap reference: https://solidity-by-example.org/defi/uniswap-v3-swap/ for adding tests -// https://docs.uniswap.org/contracts/v3/reference/periphery/SwapRouter - -contract UniswapV3SwapExamples { - ISwapRouter constant router = - ISwapRouter(0xE592427A0AEce92De3Edee1F18E0157C05861564); - - function swapExactInputSingleHop( - address tokenIn, - address tokenOut, - uint24 poolFee, - uint256 amountIn - ) external returns (uint256 amountOut) { - IERC20(tokenIn).transferFrom(msg.sender, address(this), amountIn); - IERC20(tokenIn).approve(address(router), amountIn); - - ISwapRouter.ExactInputSingleParams memory params = ISwapRouter - .ExactInputSingleParams({ - tokenIn: tokenIn, - tokenOut: tokenOut, - fee: poolFee, - recipient: msg.sender, - deadline: block.timestamp, - amountIn: amountIn, - amountOutMinimum: 0, - sqrtPriceLimitX96: 0 - }); - - amountOut = router.exactInputSingle(params); - } - - function swapExactInputMultiHop( - bytes calldata path, - address tokenIn, - uint256 amountIn - ) external returns (uint256 amountOut) { - IERC20(tokenIn).transferFrom(msg.sender, address(this), amountIn); - IERC20(tokenIn).approve(address(router), amountIn); - - ISwapRouter.ExactInputParams memory params = ISwapRouter - .ExactInputParams({ - path: path, - recipient: msg.sender, - deadline: block.timestamp, - amountIn: amountIn, - amountOutMinimum: 0 - }); - amountOut = router.exactInput(params); - } -} - -interface ISwapRouter { - struct ExactInputSingleParams { - address tokenIn; - address tokenOut; - uint24 fee; - address recipient; - uint256 deadline; - uint256 amountIn; - uint256 amountOutMinimum; - uint160 sqrtPriceLimitX96; - } - - /// @notice Swaps amountIn of one token for as much as possible of another token - /// @param params The parameters necessary for the swap, encoded as ExactInputSingleParams in calldata - /// @return amountOut The amount of the received token - function exactInputSingle( - ExactInputSingleParams calldata params - ) external payable returns (uint256 amountOut); - - struct ExactInputParams { - bytes path; - address recipient; - uint256 deadline; - uint256 amountIn; - uint256 amountOutMinimum; - } - - /// @notice Swaps amountIn of one token for as much as possible of another along the specified path - /// @param params The parameters necessary for the multi-hop swap, encoded as ExactInputParams in calldata - /// @return amountOut The amount of the received token - function exactInput( - ExactInputParams calldata params - ) external payable returns (uint256 amountOut); -} - -interface IERC20 { - function totalSupply() external view returns (uint256); - - function balanceOf(address account) external view returns (uint256); - - function transfer( - address recipient, - uint256 amount - ) external returns (bool); - - function allowance( - address owner, - address spender - ) external view returns (uint256); - - function approve(address spender, uint256 amount) external returns (bool); - - function transferFrom( - address sender, - address recipient, - uint256 amount - ) external returns (bool); - - event Transfer(address indexed from, address indexed to, uint256 value); - event Approval( - address indexed owner, - address indexed spender, - uint256 value - ); -} - -interface IWETH is IERC20 { - function deposit() external payable; - - function withdraw(uint256 amount) external; -} diff --git a/contracts/test/helpers/MockChainlinkAggregator.sol b/contracts/test/helpers/MockChainlinkAggregator.sol deleted file mode 100644 index 323b5b6..0000000 --- a/contracts/test/helpers/MockChainlinkAggregator.sol +++ /dev/null @@ -1,113 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.17; - -import "@openzeppelin/contracts/access/Ownable.sol"; -import "../../token/oracles/IOracleAggregator.sol"; -import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; -import "hardhat/console.sol"; - -/** - * @title Mock Oracle Aggregator contract - * @notice DO NOT use this in any environment for use - */ -contract MockChainlinkOracleAggregator is Ownable, IOracleAggregator { - struct TokenInfo { - /* Number of decimals represents the precision of the price returned by the feed. For example, - a price of $100.50 might be represented as 100500000000 in the contract, with 9 decimal places - of precision */ - uint8 decimals; - bool dataSigned; - address callAddress; - bytes callData; - } - - mapping(address => TokenInfo) internal tokensInfo; - - constructor(address _owner) { - _transferOwnership(_owner); - } - - /** - * @dev set price feed information for specific feed - * @param callAddress price feed / derived price feed address to call - * @param decimals decimals (precision) defined in this price feed - * @param callData function selector which will be used to query price data - * @param signed if the feed may return result as signed integrer - */ - function setTokenOracle( - address token, - address callAddress, - uint8 decimals, - bytes calldata callData, - bool signed - ) external onlyOwner { - require( - callAddress != address(0), - "ChainlinkOracleAggregator:: call address can not be zero" - ); - require( - token != address(0), - "ChainlinkOracleAggregator:: token address can not be zero" - ); - tokensInfo[token].callAddress = callAddress; - tokensInfo[token].decimals = decimals; - tokensInfo[token].callData = callData; - tokensInfo[token].dataSigned = signed; - } - - /** - * @dev query deciamls used by set feed for specific token - * @param token ERC20 token address - */ - function getTokenOracleDecimals( - address token - ) external view returns (uint8 _tokenOracleDecimals) { - _tokenOracleDecimals = tokensInfo[token].decimals; - } - - /** - * @dev query price feed - * @param token ERC20 token address - */ - function getTokenPrice( - address token - ) external view returns (uint256 tokenPrice) { - // usually token / native (depends on price feed) - tokenPrice = _getTokenPrice(token); - } - - /** - * @dev exchangeRate : each aggregator implements this method based on how it sources the quote/price - * @notice here it is token / native sourced from chainlink so in order to get defined exchangeRate we inverse the feed - * @param token ERC20 token address - */ - function getTokenValueOfOneNativeToken( - address token - ) external view virtual returns (uint256 exchangeRate) { - // we'd actually want eth / token - uint256 tokenPriceUnadjusted = _getTokenPrice(token); - uint8 _tokenOracleDecimals = tokensInfo[token].decimals; - exchangeRate = - ((10 ** _tokenOracleDecimals) * - (10 ** IERC20Metadata(token).decimals())) / - tokenPriceUnadjusted; - } - - // Making explicit revert or make use of stale price feed which reverts - // like done in below function and the test case - - function _getTokenPrice( - address token - ) internal view returns (uint256 tokenPriceUnadjusted) { - (bool success, bytes memory ret) = tokensInfo[token] - .callAddress - .staticcall(tokensInfo[token].callData); - - require(success, "ChainlinkOracleAggregator:: query failed"); - if (tokensInfo[token].dataSigned) { - tokenPriceUnadjusted = uint256(abi.decode(ret, (int256))); - } else { - tokenPriceUnadjusted = abi.decode(ret, (uint256)); - } - } -} diff --git a/contracts/test/helpers/MockOracle.sol b/contracts/test/helpers/MockOracle.sol new file mode 100644 index 0000000..b36a2f3 --- /dev/null +++ b/contracts/test/helpers/MockOracle.sol @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.23; + +import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol"; + +contract MockOracle is AggregatorV3Interface { + uint256 internal priceToReturn; + string internal desc; + + constructor(uint256 _fixedPrice, string memory _description) { + priceToReturn = _fixedPrice; + desc = _description; + } + + function decimals() public view returns (uint8) { + return 8; + } + + function description() public view returns (string memory) { + return desc; + } + + function version() public view returns (uint256) { + return 1; + } + + function getRoundData(uint80 _roundId) + public + view + override + returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound) + { + roundId = _roundId; + answer = int256(priceToReturn); + startedAt = 0; + updatedAt = 0; + answeredInRound = 0; + } + + function latestRoundData() + public + view + virtual + returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound) + { + roundId = 36893488147419318063; + answer = int256(priceToReturn); + startedAt = 1780336251; + updatedAt = 1780509051; + answeredInRound = 36893488147419318063; + } +} diff --git a/contracts/test/helpers/MockPriceFeed.sol b/contracts/test/helpers/MockPriceFeed.sol index b745289..05b5526 100644 --- a/contracts/test/helpers/MockPriceFeed.sol +++ b/contracts/test/helpers/MockPriceFeed.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.17; +pragma solidity ^0.8.23; import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol"; @@ -11,12 +11,8 @@ contract MockPriceFeed { constructor() { // todo // do not hard code // polygon values - priceFeed1 = AggregatorV3Interface( - 0xAB594600376Ec9fD91F8e885dADF0CE036862dE0 - ); // matic usd - priceFeed2 = AggregatorV3Interface( - 0xfE4A8cc5b5B2366C1B58Bea3858e81843581b2F7 - ); // usdc usd + priceFeed1 = AggregatorV3Interface(0xAB594600376Ec9fD91F8e885dADF0CE036862dE0); // matic usd + priceFeed2 = AggregatorV3Interface(0xfE4A8cc5b5B2366C1B58Bea3858e81843581b2F7); // usdc usd } function decimals() public view returns (uint8) { diff --git a/contracts/test/helpers/MockStaleOracle.sol b/contracts/test/helpers/MockStaleOracle.sol new file mode 100644 index 0000000..efcca4c --- /dev/null +++ b/contracts/test/helpers/MockStaleOracle.sol @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.23; + +import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol"; + +contract MockStaleOracle is AggregatorV3Interface { + uint256 internal priceToReturn; + string internal desc; + + constructor(uint256 _fixedPrice, string memory _description) { + priceToReturn = _fixedPrice; + desc = _description; + } + + function decimals() public view returns (uint8) { + return 8; + } + + function description() public view returns (string memory) { + return desc; + } + + function version() public view returns (uint256) { + return 1; + } + + function getRoundData(uint80 _roundId) + public + view + override + returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound) + { + roundId = _roundId; + answer = int256(priceToReturn); + startedAt = 0; + updatedAt = 0; + answeredInRound = 0; + } + + function latestRoundData() + public + view + virtual + returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound) + { + revert("MockStaleOracle::latestRoundData: stale price"); + } +} diff --git a/contracts/test/helpers/MockStalePriceFeed.sol b/contracts/test/helpers/MockStalePriceFeed.sol index 5558a08..f323ea7 100644 --- a/contracts/test/helpers/MockStalePriceFeed.sol +++ b/contracts/test/helpers/MockStalePriceFeed.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.17; +pragma solidity ^0.8.23; import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol"; @@ -13,12 +13,8 @@ contract MockStalePriceFeed { constructor() { // todo // do not hard code // polygon values - priceFeed1 = AggregatorV3Interface( - 0xAB594600376Ec9fD91F8e885dADF0CE036862dE0 - ); // matic usd - priceFeed2 = AggregatorV3Interface( - 0xfE4A8cc5b5B2366C1B58Bea3858e81843581b2F7 - ); // usdc usd + priceFeed1 = AggregatorV3Interface(0xAB594600376Ec9fD91F8e885dADF0CE036862dE0); // matic usd + priceFeed2 = AggregatorV3Interface(0xfE4A8cc5b5B2366C1B58Bea3858e81843581b2F7); // usdc usd } function decimals() public view returns (uint8) { diff --git a/contracts/test/helpers/MockToken.sol b/contracts/test/helpers/MockToken.sol index 876f755..75e212f 100644 --- a/contracts/test/helpers/MockToken.sol +++ b/contracts/test/helpers/MockToken.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.8.17; +pragma solidity ^0.8.23; import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; diff --git a/contracts/test/helpers/TestCounter.sol b/contracts/test/helpers/TestCounter.sol index 0ac2c88..d905524 100644 --- a/contracts/test/helpers/TestCounter.sol +++ b/contracts/test/helpers/TestCounter.sol @@ -25,7 +25,7 @@ contract TestCounter { mapping(uint256 => uint256) public xxx; uint256 public offset; - function gasWaster(uint256 repeat, string calldata /*junk*/) external { + function gasWaster(uint256 repeat, string calldata /*junk*/ ) external { for (uint256 i = 1; i <= repeat; i++) { offset++; xxx[offset] = i; diff --git a/contracts/token/BiconomyTokenPaymaster.sol b/contracts/token/BiconomyTokenPaymaster.sol index 9a780a1..9f6bed0 100644 --- a/contracts/token/BiconomyTokenPaymaster.sol +++ b/contracts/token/BiconomyTokenPaymaster.sol @@ -1,20 +1,23 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.17; +pragma solidity ^0.8.23; import {ECDSA} from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; import {ReentrancyGuard} from "@openzeppelin/contracts/security/ReentrancyGuard.sol"; import {IEntryPoint} from "@account-abstraction/contracts/interfaces/IEntryPoint.sol"; import {UserOperation} from "@account-abstraction/contracts/interfaces/UserOperation.sol"; import {UserOperationLib} from "@account-abstraction/contracts/interfaces/UserOperation.sol"; +import {IBiconomyTokenPaymaster} from "../interfaces/paymasters/IBiconomyTokenPaymaster.sol"; +import {CalldataHelper} from "../libs/CalldataHelper.sol"; import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; import {BasePaymaster} from "../BasePaymaster.sol"; -import {IOracleAggregator} from "./oracles/IOracleAggregator.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@account-abstraction/contracts/core/Helpers.sol" as Helpers; import {Math} from "@openzeppelin/contracts/utils/math/Math.sol"; import "../utils/SafeTransferLib.sol"; +import {MathLib} from "../libs/MathLib.sol"; import {TokenPaymasterErrors} from "./TokenPaymasterErrors.sol"; import "@openzeppelin/contracts/utils/Address.sol"; +import {OracleAggregator} from "./oracles/OracleAggregator.sol"; // Biconomy Token Paymaster /** @@ -29,39 +32,26 @@ import "@openzeppelin/contracts/utils/Address.sol"; * * Optionally a safe guard deposit may be used in future versions. */ + contract BiconomyTokenPaymaster is BasePaymaster, + OracleAggregator, ReentrancyGuard, - TokenPaymasterErrors + TokenPaymasterErrors, + IBiconomyTokenPaymaster { using ECDSA for bytes32; using Address for address; using UserOperationLib for UserOperation; - /** - * price source can be off-chain calculation or oracles - * for oracle based it can be based on chainlink feeds or TWAP oracles - * for ORACLE_BASED oracle aggregator address has to be passed in paymasterAndData - */ - enum ExchangeRateSource { - EXTERNAL_EXCHANGE_RATE, - ORACLE_BASED - } - - // 1. use mode and based on mode treat uint256 fee sent either as priceMarkup or flatFee - // 2. (no mode required) add extra value in paymasterandData so uint32 markup and uint224 flatFee both can be parsed - // 3. (no mode required) without extra value treat uint256 as packed uint32uint224 and use values accordingly - /*enum FeePremiumMode { - PERCENTAGE, - FLAT - }*/ - /// @notice All 'price' variable coming from outside are expected to be multiple of 1e6, and in actual calculation, /// final value is divided by PRICE_DENOMINATOR to avoid rounding up. uint32 private constant PRICE_DENOMINATOR = 1e6; // Gas used in EntryPoint._handlePostOp() method (including this#postOp() call) - uint256 public UNACCOUNTED_COST = 45000; // TBD + // postOp() with ORACLE BASED priceSource = 28420 + // max postOp() plus EP buffer + uint256 public unaccountedEPGasOverhead = 35000; // Always rely on verifyingSigner.. address public verifyingSigner; @@ -69,83 +59,31 @@ contract BiconomyTokenPaymaster is // receiver of withdrawn fee tokens address public feeReceiver; - // paymasterAndData: concat of [paymasterAddress(address), priceSource(enum 1 byte), abi.encode(validUntil, validAfter, feeToken, oracleAggregator, exchangeRate, priceMarkup): makes up 32*6 bytes, signature] + // paymasterAndData: concat of [paymasterAddress(address), priceSource(enum 1 byte), validUntil(6 byte), validAfter(6 byte), feeToken(20 bytes), exchangeRate(16 bytes), priceMarkup(4 bytes), signature] // PND offset is used to indicate offsets to decode, used along with Signature offset - uint256 private constant VALID_PND_OFFSET = 21; - - uint256 private constant SIGNATURE_OFFSET = 213; + uint256 private constant VALID_PND_OFFSET = 20; + uint256 private constant SIGNATURE_OFFSET = 73; - address private constant NATIVE_ADDRESS = - 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; - - /** - * Designed to enable the community to track change in storage variable UNACCOUNTED_COST which is used - * to maintain gas execution cost which can't be calculated within contract*/ - event EPGasOverheadChanged( - uint256 indexed _oldOverheadCost, - uint256 indexed _newOverheadCost, - address indexed _actor - ); - - /** - * Designed to enable the community to track change in storage variable verifyingSigner which is used - * to authorize any operation for this paymaster (validation stage) and provides signature*/ - event VerifyingSignerChanged( - address indexed _oldSigner, - address indexed _newSigner, - address indexed _actor - ); - - /** - * Designed to enable the community to track change in storage variable feeReceiver which is an address (self or other SCW/EOA) - * responsible for collecting all the tokens being withdrawn as fees*/ - event FeeReceiverChanged( - address indexed _oldfeeReceiver, - address indexed _newfeeReceiver, - address indexed _actor - ); - - /** - * Designed to enable tracking how much fees were charged from the sender and in which ERC20 token - * More information can be emitted like exchangeRate used, what was the source of exchangeRate etc*/ - // priceMarkup = Multiplier value to calculate markup, 1e6 means 1x multiplier = No markup - event TokenPaymasterOperation( - address indexed sender, - address indexed token, - uint256 indexed totalCharge, - address oracleAggregator, - uint32 priceMarkup, - bytes32 userOpHash, - uint256 exchangeRate, - ExchangeRateSource priceSource - ); - - /** - * Notify in case paymaster failed to withdraw tokens from sender - */ - event TokenPaymentDue( - address indexed token, - address indexed account, - uint256 indexed charge - ); - - event Received(address indexed sender, uint256 value); - - constructor( - address _owner, - IEntryPoint _entryPoint, - address _verifyingSigner - ) payable BasePaymaster(_owner, _entryPoint) { + constructor(address _owner, IEntryPoint _entryPoint, address _verifyingSigner) + payable + BasePaymaster(_owner, _entryPoint) + OracleAggregator(_owner) + { if (_owner == address(0)) revert OwnerCannotBeZero(); if (address(_entryPoint) == address(0)) revert EntryPointCannotBeZero(); - if (_verifyingSigner == address(0)) + if (_verifyingSigner == address(0)) { revert VerifyingSignerCannotBeZero(); + } assembly ("memory-safe") { sstore(verifyingSigner.slot, _verifyingSigner) sstore(feeReceiver.slot, address()) // initialize with self (could also be _owner) } } + receive() external payable { + emit Received(msg.sender, msg.value); + } + /** * @dev Set a new verifying signer address. * Can only be called by the owner of the contract. @@ -153,11 +91,10 @@ contract BiconomyTokenPaymaster is * @notice If _newVerifyingSigner is set to zero address, it will revert with an error. * After setting the new signer address, it will emit an event VerifyingSignerChanged. */ - function setVerifyingSigner( - address _newVerifyingSigner - ) external payable onlyOwner { - if (_newVerifyingSigner == address(0)) + function setVerifyingSigner(address _newVerifyingSigner) external payable onlyOwner { + if (_newVerifyingSigner == address(0)) { revert VerifyingSignerCannotBeZero(); + } address oldSigner = verifyingSigner; assembly ("memory-safe") { sstore(verifyingSigner.slot, _newVerifyingSigner) @@ -173,9 +110,7 @@ contract BiconomyTokenPaymaster is * @notice If _newFeeReceiver is set to zero address, it will revert with an error. * After setting the new address, it will emit an event FeeReceiverChanged. */ - function setFeeReceiver( - address _newFeeReceiver - ) external payable onlyOwner { + function setFeeReceiver(address _newFeeReceiver) external payable onlyOwner { if (_newFeeReceiver == address(0)) revert FeeReceiverCannotBeZero(); address oldFeeReceiver = feeReceiver; assembly ("memory-safe") { @@ -191,14 +126,11 @@ contract BiconomyTokenPaymaster is * @notice If _newOverheadCost is set to very high value, it will revert with an error. * After setting the new value, it will emit an event EPGasOverheadChanged. */ - function setUnaccountedEPGasOverhead( - uint256 _newOverheadCost - ) external payable onlyOwner { - // review if this could be high value in case of arbitrum + function setUnaccountedEPGasOverhead(uint256 _newOverheadCost) external payable onlyOwner { if (_newOverheadCost > 200000) revert CannotBeUnrealisticValue(); - uint256 oldValue = UNACCOUNTED_COST; + uint256 oldValue = unaccountedEPGasOverhead; assembly ("memory-safe") { - sstore(UNACCOUNTED_COST.slot, _newOverheadCost) + sstore(unaccountedEPGasOverhead.slot, _newOverheadCost) } emit EPGasOverheadChanged(oldValue, _newOverheadCost, msg.sender); } @@ -216,45 +148,18 @@ contract BiconomyTokenPaymaster is * @param withdrawAddress The address to which the gas tokens should be transferred. * @param amount The amount of gas tokens to withdraw. */ - function withdrawTo( - address payable withdrawAddress, - uint256 amount - ) public override onlyOwner nonReentrant { + function withdrawTo(address payable withdrawAddress, uint256 amount) public override onlyOwner nonReentrant { if (withdrawAddress == address(0)) revert CanNotWithdrawToZeroAddress(); entryPoint.withdrawTo(withdrawAddress, amount); } - /** - * @dev Returns the exchange price of the token in wei. - * @param _token ERC20 token address - * @param _oracleAggregator oracle aggregator address - */ - function exchangePrice( - address _token, - address _oracleAggregator - ) internal view virtual returns (uint256) { - try - IOracleAggregator(_oracleAggregator).getTokenValueOfOneNativeToken( - _token - ) - returns (uint256 exchangeRate) { - return exchangeRate; - } catch { - return 0; - } - } - /** * @dev pull tokens out of paymaster in case they were sent to the paymaster at any point. * @param token the token deposit to withdraw * @param target address to send to * @param amount amount to withdraw */ - function withdrawERC20( - IERC20 token, - address target, - uint256 amount - ) public payable onlyOwner nonReentrant { + function withdrawERC20(IERC20 token, address target, uint256 amount) public payable onlyOwner nonReentrant { _withdrawERC20(token, target, amount); } @@ -263,10 +168,7 @@ contract BiconomyTokenPaymaster is * @param token the token deposit to withdraw * @param target address to send to */ - function withdrawERC20Full( - IERC20 token, - address target - ) public payable onlyOwner nonReentrant { + function withdrawERC20Full(IERC20 token, address target) public payable onlyOwner nonReentrant { uint256 amount = token.balanceOf(address(this)); _withdrawERC20(token, target, amount); } @@ -277,15 +179,18 @@ contract BiconomyTokenPaymaster is * @param target address to send to * @param amount amounts to withdraw */ - function withdrawMultipleERC20( - IERC20[] calldata token, - address target, - uint256[] calldata amount - ) public payable onlyOwner nonReentrant { - if (token.length != amount.length) + function withdrawMultipleERC20(IERC20[] calldata token, address target, uint256[] calldata amount) + public + payable + onlyOwner + nonReentrant + { + uint256 tokLen = token.length; + if (tokLen != amount.length) { revert TokensAndAmountsLengthMismatch(); + } unchecked { - for (uint256 i; i < token.length; ) { + for (uint256 i; i < tokLen;) { _withdrawERC20(token[i], target, amount[i]); ++i; } @@ -297,12 +202,10 @@ contract BiconomyTokenPaymaster is * @param token the tokens deposit to withdraw * @param target address to send to */ - function withdrawMultipleERC20Full( - IERC20[] calldata token, - address target - ) public payable onlyOwner nonReentrant { + function withdrawMultipleERC20Full(IERC20[] calldata token, address target) public payable onlyOwner nonReentrant { unchecked { - for (uint256 i; i < token.length; ) { + uint256 tokLen = token.length; + for (uint256 i; i < tokLen;) { uint256 amount = token[i].balanceOf(address(this)); _withdrawERC20(token[i], target, amount); ++i; @@ -314,9 +217,7 @@ contract BiconomyTokenPaymaster is * @dev pull native tokens out of paymaster in case they were sent to the paymaster at any point * @param dest address to send to */ - function withdrawAllNative( - address dest - ) public payable onlyOwner nonReentrant { + function withdrawAllNative(address dest) public payable onlyOwner nonReentrant { uint256 _balance = address(this).balance; if (_balance == 0) revert NativeTokenBalanceZero(); if (dest == address(0)) revert CanNotWithdrawToZeroAddress(); @@ -340,39 +241,34 @@ contract BiconomyTokenPaymaster is uint48 validUntil, uint48 validAfter, address feeToken, - address oracleAggregator, - uint256 exchangeRate, + uint128 exchangeRate, uint32 priceMarkup ) public view returns (bytes32) { //can't use userOp.hash(), since it contains also the paymasterAndData itself. - return - keccak256( - abi.encode( - userOp.getSender(), - userOp.nonce, - keccak256(userOp.initCode), - keccak256(userOp.callData), - userOp.callGasLimit, - userOp.verificationGasLimit, - userOp.preVerificationGas, - userOp.maxFeePerGas, - userOp.maxPriorityFeePerGas, - block.chainid, - address(this), - priceSource, - validUntil, - validAfter, - feeToken, - oracleAggregator, - exchangeRate, - priceMarkup - ) - ); + return keccak256( + abi.encode( + userOp.getSender(), + userOp.nonce, + CalldataHelper.calldataKeccak(userOp.initCode), + CalldataHelper.calldataKeccak(userOp.callData), + userOp.callGasLimit, + userOp.verificationGasLimit, + userOp.preVerificationGas, + userOp.maxFeePerGas, + userOp.maxPriorityFeePerGas, + block.chainid, + address(this), + priceSource, + validUntil, + validAfter, + feeToken, + exchangeRate, + priceMarkup + ) + ); } - function parsePaymasterAndData( - bytes calldata paymasterAndData - ) + function parsePaymasterAndData(bytes calldata paymasterAndData) public pure returns ( @@ -380,115 +276,170 @@ contract BiconomyTokenPaymaster is uint48 validUntil, uint48 validAfter, address feeToken, - address oracleAggregator, - uint256 exchangeRate, + uint128 exchangeRate, uint32 priceMarkup, bytes calldata signature ) { // paymasterAndData.length should be at least SIGNATURE_OFFSET + 65 (checked separate) - require( - paymasterAndData.length >= SIGNATURE_OFFSET, - "BTPM: Invalid length for paymasterAndData" - ); - priceSource = ExchangeRateSource( - uint8( - bytes1(paymasterAndData[VALID_PND_OFFSET - 1:VALID_PND_OFFSET]) - ) - ); - ( - validUntil, - validAfter, - feeToken, - oracleAggregator, - exchangeRate, - priceMarkup - ) = abi.decode( - paymasterAndData[VALID_PND_OFFSET:SIGNATURE_OFFSET], - (uint48, uint48, address, address, uint256, uint32) + require(paymasterAndData.length >= SIGNATURE_OFFSET, "BTPM: Invalid length for paymasterAndData"); + priceSource = ExchangeRateSource(uint8(bytes1(paymasterAndData[VALID_PND_OFFSET:VALID_PND_OFFSET + 1]))); + validUntil = uint48(bytes6(paymasterAndData[VALID_PND_OFFSET + 1:VALID_PND_OFFSET + 7])); + validAfter = uint48(bytes6(paymasterAndData[VALID_PND_OFFSET + 7:VALID_PND_OFFSET + 13])); + feeToken = address(bytes20(paymasterAndData[VALID_PND_OFFSET + 13:VALID_PND_OFFSET + 33])); + exchangeRate = uint128(bytes16(paymasterAndData[VALID_PND_OFFSET + 33:VALID_PND_OFFSET + 49])); + priceMarkup = uint32(bytes4(paymasterAndData[VALID_PND_OFFSET + 49:VALID_PND_OFFSET + 53])); + signature = paymasterAndData[VALID_PND_OFFSET + 53:]; + } + + /** + * @dev Executes the paymaster's payment conditions + * @param mode tells whether the op succeeded, reverted, or if the op succeeded but cause the postOp to revert + * @param context payment conditions signed by the paymaster in `validatePaymasterUserOp` + * @param actualGasCost amount to be paid to the entry point in wei + */ + function _postOp(PostOpMode mode, bytes calldata context, uint256 actualGasCost) internal virtual override { + address account; + IERC20 feeToken; + ExchangeRateSource priceSource; + uint128 exchangeRate; + uint32 priceMarkup; + uint256 maxFeePerGas; + uint256 maxPriorityFeePerGas; + bytes32 userOpHash; + assembly ("memory-safe") { + let offset := context.offset + + account := calldataload(offset) + offset := add(offset, 0x20) + + feeToken := calldataload(offset) + offset := add(offset, 0x20) + + priceSource := calldataload(offset) + offset := add(offset, 0x20) + + exchangeRate := calldataload(offset) + offset := add(offset, 0x20) + + priceMarkup := calldataload(offset) + offset := add(offset, 0x20) + + maxFeePerGas := calldataload(offset) + offset := add(offset, 0x20) + + maxPriorityFeePerGas := calldataload(offset) + offset := add(offset, 0x20) + + userOpHash := calldataload(offset) + } + + uint128 effectiveExchangeRate = exchangeRate; + + if (priceSource == ExchangeRateSource.ORACLE_BASED) { + uint128 result = getTokenValueOfOneNativeToken(address(feeToken)); + if (result != 0) effectiveExchangeRate = result; + } + + uint256 effectiveGasPrice = getGasPrice( + maxFeePerGas, + maxPriorityFeePerGas ); - signature = paymasterAndData[SIGNATURE_OFFSET:]; + + // We could either touch the state for BASEFEE and calculate based on maxPriorityFee passed (to be added in context along with maxFeePerGas) or just use tx.gasprice + uint256 charge; // Final amount to be charged from user account + { + uint256 actualTokenCost = + ((actualGasCost + (unaccountedEPGasOverhead * effectiveGasPrice)) * effectiveExchangeRate) / 1e18; + charge = ((actualTokenCost * priceMarkup) / PRICE_DENOMINATOR); + } + + if (mode != PostOpMode.postOpReverted) { + SafeTransferLib.safeTransferFrom(address(feeToken), account, feeReceiver, charge); + emit TokenPaymasterOperation( + account, address(feeToken), charge, priceMarkup, userOpHash, effectiveExchangeRate, priceSource + ); + } else { + // In case transferFrom failed in first handlePostOp call, attempt to charge the tokens again + + // 1. + // but if it reverts, let it revert with ERC20: insufficient allowance + // safeTransferFrom => AA50 postOp revert + // transferFrom => AA50 postOp reverted: ERC20: insufficient allowance + + // Would be useful if paymaster already has allowance(not part of this op's exec) + // SafeTransferLib.safeTransferFrom( + // address(feeToken), + // account, + // feeReceiver, + // charge + // ); + + // 2. force revert + revert("BTPM PostOpReverted: Failed to charge tokens"); + } } - function _getRequiredPrefund( - UserOperation calldata userOp - ) internal view returns (uint256 requiredPrefund) { + function _getRequiredPrefund(UserOperation calldata userOp) internal view returns (uint256 requiredPrefund) { unchecked { - uint256 requiredGas = userOp.callGasLimit + - userOp.verificationGasLimit + - userOp.preVerificationGas + - UNACCOUNTED_COST; + uint256 requiredGas = + userOp.callGasLimit + userOp.verificationGasLimit + userOp.preVerificationGas + unaccountedEPGasOverhead; requiredPrefund = requiredGas * userOp.maxFeePerGas; } } + // Note: do not use this in validation phase + function getGasPrice( + uint256 maxFeePerGas, + uint256 maxPriorityFeePerGas + ) internal view returns (uint256) { + if (maxFeePerGas == maxPriorityFeePerGas) { + //legacy mode (for networks that don't support basefee opcode) + return maxFeePerGas; + } + return + MathLib.minuint256( + maxFeePerGas, + maxPriorityFeePerGas + block.basefee + ); + } + /** * @dev Verify that an external signer signed the paymaster data of a user operation. * The paymaster data is expected to be the paymaster address, request data and a signature over the entire request parameters. - * paymasterAndData: hexConcat([paymasterAddress, priceSource, abi.encode(validUntil, validAfter, feeToken, oracleAggregator, exchangeRate, priceMarkup), signature]) + * paymasterAndData: hexConcat([paymasterAddress, priceSource, abi.encode(validUntil, validAfter, feeToken, exchangeRate, priceMarkup), signature]) * @param userOp The UserOperation struct that represents the current user operation. * userOpHash The hash of the UserOperation struct. * @param requiredPreFund The required amount of pre-funding for the paymaster. * @return context A context string returned by the entry point after successful validation. * @return validationData An integer returned by the entry point after successful validation. */ - function _validatePaymasterUserOp( - UserOperation calldata userOp, - bytes32 userOpHash, - uint256 requiredPreFund - ) + function _validatePaymasterUserOp(UserOperation calldata userOp, bytes32 userOpHash, uint256 requiredPreFund) internal view override returns (bytes memory context, uint256 validationData) { (requiredPreFund); - // verificationGasLimit is dual-purposed, as gas limit for postOp. make sure it is high enough - // make sure that verificationGasLimit is high enough to handle postOp - require( - userOp.verificationGasLimit > UNACCOUNTED_COST, - "BTPM: gas too low for postOp" - ); - // review: in this method try to resolve stack too deep (though via-ir is good enough) ( ExchangeRateSource priceSource, uint48 validUntil, uint48 validAfter, address feeToken, - address oracleAggregator, - uint256 exchangeRate, + uint128 exchangeRate, uint32 priceMarkup, bytes calldata signature ) = parsePaymasterAndData(userOp.paymasterAndData); - // we only "require" it here so that the revert reason on invalid signature will be of "VerifyingPaymaster", and not "ECDSA" - require( - signature.length == 65, - "BTPM: invalid signature length in paymasterAndData" - ); - - bytes32 _hash = getHash( - userOp, - priceSource, - validUntil, - validAfter, - feeToken, - oracleAggregator, - exchangeRate, - priceMarkup - ).toEthSignedMessageHash(); - - context = ""; + bytes32 _hash = getHash(userOp, priceSource, validUntil, validAfter, feeToken, exchangeRate, priceMarkup) + .toEthSignedMessageHash(); //don't revert on signature failure: return SIG_VALIDATION_FAILED if (verifyingSigner != _hash.recover(signature)) { // empty context and sigFailed true - return ( - context, - Helpers._packValidationData(true, validUntil, validAfter) - ); + return (context, Helpers._packValidationData(true, validUntil, validAfter)); } address account = userOp.getSender(); @@ -498,135 +449,21 @@ contract BiconomyTokenPaymaster is uint256 btpmRequiredPrefund = _getRequiredPrefund(userOp); - uint256 tokenRequiredPreFund = (btpmRequiredPrefund * exchangeRate) / - 10 ** 18; - require( - tokenRequiredPreFund != 0, - "BTPM: calculated token charge invalid" - ); + uint256 tokenRequiredPreFund = (btpmRequiredPrefund * exchangeRate) / 10 ** 18; require(priceMarkup <= 2e6, "BTPM: price markup percentage too high"); - require(priceMarkup >= 1e6, "BTPM: price markup percentage too low"); require( - IERC20(feeToken).balanceOf(account) >= - ((tokenRequiredPreFund * priceMarkup) / PRICE_DENOMINATOR), - "BTPM: account does not have enough token balance" + IERC20(feeToken).balanceOf(account) >= ((tokenRequiredPreFund * priceMarkup) / PRICE_DENOMINATOR), + "BTPM: Insufficient token balance" ); - context = abi.encode( - account, - feeToken, - oracleAggregator, - priceSource, - exchangeRate, - priceMarkup, - userOpHash - ); + context = abi.encode(account, feeToken, priceSource, exchangeRate, priceMarkup, userOp.maxFeePerGas, userOp.maxPriorityFeePerGas, userOpHash); - return ( - context, - Helpers._packValidationData(false, validUntil, validAfter) - ); + return (context, Helpers._packValidationData(false, validUntil, validAfter)); } - /** - * @dev Executes the paymaster's payment conditions - * @param mode tells whether the op succeeded, reverted, or if the op succeeded but cause the postOp to revert - * @param context payment conditions signed by the paymaster in `validatePaymasterUserOp` - * @param actualGasCost amount to be paid to the entry point in wei - */ - function _postOp( - PostOpMode mode, - bytes calldata context, - uint256 actualGasCost - ) internal virtual override { - ( - address account, - IERC20 feeToken, - address oracleAggregator, - ExchangeRateSource priceSource, - uint256 exchangeRate, - uint32 priceMarkup, - bytes32 userOpHash - ) = abi.decode( - context, - ( - address, - IERC20, - address, - ExchangeRateSource, - uint256, - uint32, - bytes32 - ) - ); - - uint256 effectiveExchangeRate = exchangeRate; - - if ( - priceSource == ExchangeRateSource.ORACLE_BASED && - oracleAggregator != address(NATIVE_ADDRESS) && - oracleAggregator != address(0) - ) { - uint256 result = exchangePrice(address(feeToken), oracleAggregator); - if (result != 0) effectiveExchangeRate = result; - } - - // We could either touch the state for BASEFEE and calculate based on maxPriorityFee passed (to be added in context along with maxFeePerGas) or just use tx.gasprice - uint256 charge; // Final amount to be charged from user account - { - uint256 actualTokenCost = ((actualGasCost + - (UNACCOUNTED_COST * tx.gasprice)) * effectiveExchangeRate) / - 1e18; - charge = ((actualTokenCost * priceMarkup) / PRICE_DENOMINATOR); - } - - if (mode != PostOpMode.postOpReverted) { - SafeTransferLib.safeTransferFrom( - address(feeToken), - account, - feeReceiver, - charge - ); - emit TokenPaymasterOperation( - account, - address(feeToken), - charge, - oracleAggregator, - priceMarkup, - userOpHash, - effectiveExchangeRate, - priceSource - ); - } else { - // In case transferFrom failed in first handlePostOp call, attempt to charge the tokens again - bytes memory _data = abi.encodeWithSelector( - feeToken.transferFrom.selector, - account, - feeReceiver, - charge - ); - (bool success,) = address(feeToken).call( - _data - ); - if (!success) { - // In case above transferFrom failed, pay with deposit / notify at least - // Sender could be banned indefinitely or for certain period - emit TokenPaymentDue(address(feeToken), account, charge); - // Do nothing else here to not revert the whole bundle and harm reputation - } - } - } - - function _withdrawERC20( - IERC20 token, - address target, - uint256 amount - ) private { + function _withdrawERC20(IERC20 token, address target, uint256 amount) private { if (target == address(0)) revert CanNotWithdrawToZeroAddress(); SafeTransferLib.safeTransfer(address(token), target, amount); - } - - receive() external payable { - emit Received(msg.sender, msg.value); + emit TokensWithdrawn(address(token), target, amount, msg.sender); } } diff --git a/contracts/token/TokenPaymasterErrors.sol b/contracts/token/TokenPaymasterErrors.sol index 6e3e7d8..5168678 100644 --- a/contracts/token/TokenPaymasterErrors.sol +++ b/contracts/token/TokenPaymasterErrors.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: LGPL-3.0-only -pragma solidity 0.8.17; +pragma solidity ^0.8.23; contract TokenPaymasterErrors { /** @@ -55,6 +55,4 @@ contract TokenPaymasterErrors { error NativeTokensWithdrawalFailed(); error CannotBeUnrealisticValue(); - - error DEXRouterCannotBeZero(); } diff --git a/contracts/token/adapters/IUniversalRouter.sol b/contracts/token/adapters/IUniversalRouter.sol deleted file mode 100644 index 9e399f7..0000000 --- a/contracts/token/adapters/IUniversalRouter.sol +++ /dev/null @@ -1,29 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity ^0.8.17; - -import {IERC721Receiver} from "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol"; -import {IERC1155Receiver} from "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol"; - -interface IUniversalRouter is IERC721Receiver, IERC1155Receiver { - /// @notice Thrown when a required command has failed - error ExecutionFailed(uint256 commandIndex, bytes message); - - /// @notice Thrown when attempting to send ETH directly to the contract - error ETHNotAccepted(); - - /// @notice Thrown when executing commands with an expired deadline - error TransactionDeadlinePassed(); - - /// @notice Thrown when attempting to execute commands and an incorrect number of inputs are provided - error LengthMismatch(); - - /// @notice Executes encoded commands along with provided inputs. Reverts if deadline has expired. - /// @param commands A set of concatenated commands, each 1 byte in length - /// @param inputs An array of byte strings containing abi encoded inputs for each command - /// @param deadline The deadline by which the transaction must be executed - function execute( - bytes calldata commands, - bytes[] calldata inputs, - uint256 deadline - ) external payable; -} diff --git a/contracts/token/adapters/UniswapExample.sol b/contracts/token/adapters/UniswapExample.sol deleted file mode 100644 index c1d34d3..0000000 --- a/contracts/token/adapters/UniswapExample.sol +++ /dev/null @@ -1,107 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.17; -pragma abicoder v2; - -import "@uniswap/v3-periphery/contracts/interfaces/ISwapRouter.sol"; -import "@uniswap/v3-periphery/contracts/interfaces/IQuoter.sol"; - -interface IUniswapRouter is ISwapRouter { - function refundETH() external payable; -} - -contract Uniswap3 { - IUniswapRouter public constant uniswapRouter = - IUniswapRouter(0xE592427A0AEce92De3Edee1F18E0157C05861564); - IQuoter public constant quoter = - IQuoter(0xb27308f9F90D607463bb33eA1BeBb41C27CE5AB6); - address private constant multiDaiKovan = - 0x4F96Fe3b7A6Cf9725f59d353F723c1bDb64CA6Aa; - address private constant WETH9 = 0xd0A1E359811322d97991E03f863a0C30C2cF029C; - - function convertExactEthToDai() external payable { - require(msg.value > 0, "Must pass non 0 ETH amount"); - - uint256 deadline = block.timestamp + 15; // using 'now' for convenience, for mainnet pass deadline from frontend! - address tokenIn = WETH9; - address tokenOut = multiDaiKovan; - uint24 fee = 3000; - address recipient = msg.sender; - uint256 amountIn = msg.value; - uint256 amountOutMinimum = 1; - uint160 sqrtPriceLimitX96 = 0; - - ISwapRouter.ExactInputSingleParams memory params = ISwapRouter - .ExactInputSingleParams( - tokenIn, - tokenOut, - fee, - recipient, - deadline, - amountIn, - amountOutMinimum, - sqrtPriceLimitX96 - ); - - uniswapRouter.exactInputSingle{value: msg.value}(params); - uniswapRouter.refundETH(); - - // refund leftover ETH to user - (bool success, ) = msg.sender.call{value: address(this).balance}(""); - require(success, "refund failed"); - } - - function convertEthToExactDai(uint256 daiAmount) external payable { - require(daiAmount > 0, "Must pass non 0 DAI amount"); - require(msg.value > 0, "Must pass non 0 ETH amount"); - - uint256 deadline = block.timestamp + 15; // using 'now' for convenience, for mainnet pass deadline from frontend! - address tokenIn = WETH9; - address tokenOut = multiDaiKovan; - uint24 fee = 3000; - address recipient = msg.sender; - uint256 amountOut = daiAmount; - uint256 amountInMaximum = msg.value; - uint160 sqrtPriceLimitX96 = 0; - - ISwapRouter.ExactOutputSingleParams memory params = ISwapRouter - .ExactOutputSingleParams( - tokenIn, - tokenOut, - fee, - recipient, - deadline, - amountOut, - amountInMaximum, - sqrtPriceLimitX96 - ); - - uniswapRouter.exactOutputSingle{value: msg.value}(params); - uniswapRouter.refundETH(); - - // refund leftover ETH to user - (bool success, ) = msg.sender.call{value: address(this).balance}(""); - require(success, "refund failed"); - } - - // do not used on-chain, gas inefficient! - function getEstimatedETHforDAI( - uint256 daiAmount - ) external payable returns (uint256) { - address tokenIn = WETH9; - address tokenOut = multiDaiKovan; - uint24 fee = 3000; - uint160 sqrtPriceLimitX96 = 0; - - return - quoter.quoteExactOutputSingle( - tokenIn, - tokenOut, - fee, - daiAmount, - sqrtPriceLimitX96 - ); - } - - // important to receive ETH - receive() external payable {} -} diff --git a/contracts/token/feemanager/FeeManager.sol b/contracts/token/feemanager/FeeManager.sol index bbb205c..928daaa 100644 --- a/contracts/token/feemanager/FeeManager.sol +++ b/contracts/token/feemanager/FeeManager.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.17; +pragma solidity ^0.8.23; import "@openzeppelin/contracts/access/Ownable.sol"; diff --git a/contracts/token/oracles/ChainlinkOracleAggregator.sol b/contracts/token/oracles/ChainlinkOracleAggregator.sol deleted file mode 100644 index ff2a4c9..0000000 --- a/contracts/token/oracles/ChainlinkOracleAggregator.sol +++ /dev/null @@ -1,109 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.17; - -import "@openzeppelin/contracts/access/Ownable.sol"; -import "./IOracleAggregator.sol"; -import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; - -/** - * @title Primary Oracle Aggregator contract used to maintain price feeds for chainlink supported tokens. - */ -contract ChainlinkOracleAggregator is Ownable, IOracleAggregator { - struct TokenInfo { - /* Number of decimals represents the precision of the price returned by the feed. For example, - a price of $100.50 might be represented as 100500000000 in the contract, with 9 decimal places - of precision */ - uint8 decimals; - // uint8 tokenDecimals; - bool dataSigned; - address callAddress; - bytes callData; - } - - mapping(address => TokenInfo) internal tokensInfo; - - constructor(address _owner) { - _transferOwnership(_owner); - } - - /** - * @dev set price feed information for specific feed - * @param callAddress price feed / derived price feed address to call - * @param decimals decimals (precision) defined in this price feed - * @param callData function selector which will be used to query price data - * @param signed if the feed may return result as signed integrer - */ - function setTokenOracle( - address token, - address callAddress, - uint8 decimals, - bytes calldata callData, - bool signed - ) external onlyOwner { - require( - callAddress != address(0), - "ChainlinkOracleAggregator:: call address can not be zero" - ); - require( - token != address(0), - "ChainlinkOracleAggregator:: token address can not be zero" - ); - tokensInfo[token].callAddress = callAddress; - tokensInfo[token].decimals = decimals; - tokensInfo[token].callData = callData; - tokensInfo[token].dataSigned = signed; - } - - /** - * @dev query deciamls used by set feed for specific token - * @param token ERC20 token address - */ - function getTokenOracleDecimals( - address token - ) external view returns (uint8 _tokenOracleDecimals) { - _tokenOracleDecimals = tokensInfo[token].decimals; - } - - /** - * @dev query price feed - * @param token ERC20 token address - */ - function getTokenPrice( - address token - ) external view returns (uint256 tokenPrice) { - // usually token / native (depends on price feed) - tokenPrice = _getTokenPrice(token); - } - - /** - * @dev exchangeRate : each aggregator implements this method based on how it sources the quote/price - * @notice here it is token / native sourced from chainlink so in order to get defined exchangeRate we inverse the feed - * @param token ERC20 token address - */ - function getTokenValueOfOneNativeToken( - address token - ) external view virtual returns (uint256 exchangeRate) { - // we'd actually want eth / token - uint256 tokenPriceUnadjusted = _getTokenPrice(token); - uint8 _tokenOracleDecimals = tokensInfo[token].decimals; - exchangeRate = - ((10 ** _tokenOracleDecimals) * - (10 ** IERC20Metadata(token).decimals())) / - tokenPriceUnadjusted; - } - - function _getTokenPrice( - address token - ) internal view returns (uint256 tokenPriceUnadjusted) { - // Note // If the callData is for latestAnswer, it could be for latestRoundData and then validateRound and extract price then - (bool success, bytes memory ret) = tokensInfo[token] - .callAddress - .staticcall(tokensInfo[token].callData); - require(success, "ChainlinkOracleAggregator:: query failed"); - if (tokensInfo[token].dataSigned) { - tokenPriceUnadjusted = uint256(abi.decode(ret, (int256))); - } else { - tokenPriceUnadjusted = abi.decode(ret, (uint256)); - } - } -} diff --git a/contracts/token/oracles/DerivedPriceFeed.sol b/contracts/token/oracles/DerivedPriceFeed.sol index 72358d4..cae09ba 100644 --- a/contracts/token/oracles/DerivedPriceFeed.sol +++ b/contracts/token/oracles/DerivedPriceFeed.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.17; +pragma solidity ^0.8.23; import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol"; @@ -17,15 +17,13 @@ contract DerivedPriceFeed { string internal DESCRIPTION; - constructor( - address _nativeOracleAddress, - address _tokenOracleAddress, - string memory _description - ) { - if (_nativeOracleAddress == address(0)) + constructor(address _nativeOracleAddress, address _tokenOracleAddress, string memory _description) { + if (_nativeOracleAddress == address(0)) { revert OracleAddressCannotBeZero(); - if (_tokenOracleAddress == address(0)) + } + if (_tokenOracleAddress == address(0)) { revert OracleAddressCannotBeZero(); + } nativeOracle = AggregatorV3Interface(_nativeOracleAddress); tokenOracle = AggregatorV3Interface(_tokenOracleAddress); @@ -54,55 +52,32 @@ contract DerivedPriceFeed { ) internal view { if (price <= 0) revert InvalidPriceFromRound(); // 2 days old price is considered stale since the price is updated every 24 hours - if (updatedAt < block.timestamp - staleFeedThreshold) + if (updatedAt < block.timestamp - staleFeedThreshold) { revert PriceFeedStale(); - if (updatedAt == 0) revert LatestRoundIncomplete(); + } if (answeredInRound < roundId) revert PriceFeedStale(); } + // could rename to latestRoundData function getThePrice() public view returns (int256) { /** * Returns the latest price of price feed 1 */ - ( - uint80 roundID1, - int256 price1, - , - uint256 updatedAt1, - uint80 answeredInRound1 - ) = nativeOracle.latestRoundData(); + (uint80 roundID1, int256 price1,, uint256 updatedAt1, uint80 answeredInRound1) = nativeOracle.latestRoundData(); // By default 2 days old price is considered stale BUT it may vary per price feed // comapred to stable coin feeds this may have different heartbeat - validateRound( - roundID1, - price1, - updatedAt1, - answeredInRound1, - 60 * 60 * 24 * 2 - ); + validateRound(roundID1, price1, updatedAt1, answeredInRound1, 60 * 60 * 24 * 2); /** * Returns the latest price of price feed 2 */ - ( - uint80 roundID2, - int256 price2, - , - uint256 updatedAt2, - uint80 answeredInRound2 - ) = tokenOracle.latestRoundData(); + (uint80 roundID2, int256 price2,, uint256 updatedAt2, uint80 answeredInRound2) = tokenOracle.latestRoundData(); // By default 2 days old price is considered stale BUT it may vary per price feed - validateRound( - roundID2, - price2, - updatedAt2, - answeredInRound2, - 60 * 60 * 24 * 2 - ); + validateRound(roundID2, price2, updatedAt2, answeredInRound2, 60 * 60 * 24 * 2); // Always using decimals 18 for derived price feeds int256 token_native = (price2 * (10 ** 18)) / price1; diff --git a/contracts/token/oracles/FeedInterface.sol b/contracts/token/oracles/FeedInterface.sol index 78a40ce..24585e8 100644 --- a/contracts/token/oracles/FeedInterface.sol +++ b/contracts/token/oracles/FeedInterface.sol @@ -1,19 +1,13 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.17; +pragma solidity ^0.8.23; /** */ interface FeedInterface { - event AnswerUpdated( - int256 indexed current, - uint256 indexed roundId, - uint256 updatedAt - ); - event NewRound( - uint256 indexed roundId, - address indexed startedBy, - uint256 startedAt - ); + event AnswerUpdated(int256 indexed current, uint256 indexed roundId, uint256 updatedAt); + event NewRound(uint256 indexed roundId, address indexed startedBy, uint256 startedAt); + + function decimals() external view returns (uint8); function latestAnswer() external view returns (int256); @@ -24,13 +18,7 @@ interface FeedInterface { function latestRoundData() external view - returns ( - uint80 roundId, - int256 answer, - uint256 startedAt, - uint256 updatedAt, - uint80 answeredInRound - ); + returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound); function getAnswer(uint256 roundId) external view returns (int256); diff --git a/contracts/token/oracles/IOracleAggregator.sol b/contracts/token/oracles/IOracleAggregator.sol index ab04874..2b495ee 100644 --- a/contracts/token/oracles/IOracleAggregator.sol +++ b/contracts/token/oracles/IOracleAggregator.sol @@ -1,8 +1,20 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.17; +pragma solidity ^0.8.23; interface IOracleAggregator { - function getTokenValueOfOneNativeToken( - address _token - ) external view returns (uint256 exchangeRate); + struct TokenInfo { + uint8 tokenDecimals; + uint24 priceUpdateThreshold; + address tokenOracle; + address nativeOracle; + bool isDerivedFeed; + } + + error MismatchInBaseAndQuoteDecimals(); + error InvalidPriceFromRound(); + error LatestRoundIncomplete(); + error PriceFeedStale(); + error OracleAddressCannotBeZero(); + + function getTokenValueOfOneNativeToken(address _token) external view returns (uint128 exchangeRate); } diff --git a/contracts/token/oracles/IPriceOracle.sol b/contracts/token/oracles/IPriceOracle.sol new file mode 100644 index 0000000..f6260bb --- /dev/null +++ b/contracts/token/oracles/IPriceOracle.sol @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.23; + +interface IPriceOracle { + function latestRoundData() + external + view + returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound); + + function getThePrice() external view returns (int256); +} diff --git a/contracts/token/oracles/OracleAggregator.sol b/contracts/token/oracles/OracleAggregator.sol new file mode 100644 index 0000000..5eabbc4 --- /dev/null +++ b/contracts/token/oracles/OracleAggregator.sol @@ -0,0 +1,96 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.23; + +import "@openzeppelin/contracts/access/Ownable.sol"; +import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; +import "./IOracleAggregator.sol"; +import "./FeedInterface.sol"; + +abstract contract OracleAggregator is Ownable, IOracleAggregator { + mapping(address => TokenInfo) internal tokensInfo; + + constructor(address _owner) { + _transferOwnership(_owner); + } + + function setTokenOracle( + address token, + address tokenOracle, + address nativeOracle, + bool isDerivedFeed, + uint24 priceUpdateThreshold + ) external onlyOwner { + if (tokenOracle == address(0)) revert OracleAddressCannotBeZero(); + if (nativeOracle == address(0)) revert OracleAddressCannotBeZero(); + require(token != address(0), "token address can not be zero"); + uint8 decimals1 = FeedInterface(nativeOracle).decimals(); + uint8 decimals2 = FeedInterface(tokenOracle).decimals(); + if (decimals1 != decimals2) revert MismatchInBaseAndQuoteDecimals(); + tokensInfo[token].tokenOracle = tokenOracle; + tokensInfo[token].nativeOracle = nativeOracle; + tokensInfo[token].tokenDecimals = ERC20(token).decimals(); + tokensInfo[token].isDerivedFeed = isDerivedFeed; + tokensInfo[token].priceUpdateThreshold = priceUpdateThreshold; + } + + /** + * @dev exchangeRate : each aggregator implements this method based on how it sources the quote/price + * @notice here it is token / native sourced from chainlink so in order to get defined exchangeRate we inverse the feed + * @param token ERC20 token address + * @return exchangeRate : token price wrt native token + */ + function getTokenValueOfOneNativeToken(address token) public view returns (uint128 exchangeRate) { + // we'd actually want eth / token + (uint256 tokenPrice, uint8 tokenOracleDecimals, uint8 tokenDecimals, bool isError) = + _getTokenPriceAndDecimals(token); + if (isError) return 0; + exchangeRate = uint128(10 ** (tokenOracleDecimals + tokenDecimals) / tokenPrice); + } + + function _getTokenPriceAndDecimals(address token) + internal + view + returns (uint256 tokenPrice, uint8 tokenOracleDecimals, uint8 tokenDecimals, bool isError) + { + TokenInfo memory tokenInfo = tokensInfo[token]; + tokenDecimals = tokenInfo.tokenDecimals; + uint24 priceUpdateThreshold = tokenInfo.priceUpdateThreshold; + + if (tokenInfo.isDerivedFeed) { + (uint256 price1, bool isError1) = fetchPrice(FeedInterface(tokenInfo.nativeOracle), priceUpdateThreshold); + (uint256 price2, bool isError2) = fetchPrice(FeedInterface(tokenInfo.tokenOracle), priceUpdateThreshold); + isError = isError1 || isError2; + if (isError) return (0, 0, 0, isError); + tokenPrice = (price2 * (10 ** 18)) / price1; + tokenOracleDecimals = 18; + } else { + (tokenPrice, isError) = fetchPrice(FeedInterface(tokenInfo.tokenOracle), priceUpdateThreshold); + tokenOracleDecimals = FeedInterface(tokenInfo.tokenOracle).decimals(); + } + } + + /** + * @dev This function is used to get the latest price from the tokenOracle or nativeOracle. + * @notice Fetches the latest price from the given Oracle. + * @param _oracle The Oracle contract to fetch the price from. + * @param _priceUpdateThreshold The time after which the price is considered stale. + * @return price The latest price fetched from the Oracle. + */ + function fetchPrice(FeedInterface _oracle, uint24 _priceUpdateThreshold) internal view returns (uint256 price, bool isError) { + try _oracle.latestRoundData() returns ( + uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound + ) { + // validateRound + if (answer <= 0) return (0, true); + // price older than set _priceUpdateThreshold is considered stale + // _priceUpdateThreshold for oracle feed is usually heartbeat interval + block time + buffer + if (updatedAt < block.timestamp - _priceUpdateThreshold) return (0, true); + price = uint256(answer); + return (price, false); + } catch Error(string memory reason) { + return (0, true); + } catch { + return (0, true); + } + } +} diff --git a/contracts/utils/Exec.sol b/contracts/utils/Exec.sol index 3c8f927..d746246 100644 --- a/contracts/utils/Exec.sol +++ b/contracts/utils/Exec.sol @@ -1,78 +1,40 @@ // SPDX-License-Identifier: LGPL-3.0-only -pragma solidity 0.8.17; - -// solhint-disable no-inline-assembly +pragma solidity ^0.8.23; /** * Utility functions helpful when making different kinds of contract calls in Solidity. */ library Exec { - function call( - address to, - uint256 value, - bytes memory data, - uint256 txGas - ) internal returns (bool success) { + function call(address to, uint256 value, bytes memory data, uint256 txGas) internal returns (bool success) { assembly { - success := call( - txGas, - to, - value, - add(data, 0x20), - mload(data), - 0, - 0 - ) + success := call(txGas, to, value, add(data, 0x20), mload(data), 0, 0) } } - function delegateCall( - address to, - bytes memory data, - uint256 txGas - ) internal returns (bool success) { + function delegateCall(address to, bytes memory data, uint256 txGas) internal returns (bool success) { assembly { - success := delegatecall( - txGas, - to, - add(data, 0x20), - mload(data), - 0, - 0 - ) + success := delegatecall(txGas, to, add(data, 0x20), mload(data), 0, 0) } } - function callAndRevert( - address to, - bytes memory data, - uint256 maxLen - ) internal { + function callAndRevert(address to, bytes memory data, uint256 maxLen) internal { bool success = call(to, 0, data, gasleft()); if (!success) { revertWithData(getReturnData(maxLen)); } } - function staticcall( - address to, - bytes memory data, - uint256 txGas - ) internal view returns (bool success) { + function staticcall(address to, bytes memory data, uint256 txGas) internal view returns (bool success) { assembly { success := staticcall(txGas, to, add(data, 0x20), mload(data), 0, 0) } } // get returned data from last call or calldelegate - function getReturnData( - uint256 maxLen - ) internal pure returns (bytes memory returnData) { + function getReturnData(uint256 maxLen) internal pure returns (bytes memory returnData) { assembly { let len := returndatasize() - if gt(len, maxLen) { - len := maxLen - } + if gt(len, maxLen) { len := maxLen } let ptr := mload(0x40) mstore(0x40, add(ptr, add(len, 0x20))) mstore(ptr, len) diff --git a/contracts/utils/LibAddress.sol b/contracts/utils/LibAddress.sol index 5be2be0..720b443 100644 --- a/contracts/utils/LibAddress.sol +++ b/contracts/utils/LibAddress.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.17; +pragma solidity ^0.8.23; library LibAddress { /** diff --git a/contracts/utils/SafeTransferLib.sol b/contracts/utils/SafeTransferLib.sol index 1da2050..6cb57c0 100644 --- a/contracts/utils/SafeTransferLib.sol +++ b/contracts/utils/SafeTransferLib.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.17; +pragma solidity ^0.8.23; /// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values. /// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/SafeTransferLib.sol) @@ -44,12 +44,7 @@ library SafeTransferLib { /// /// The `from` account must have at least `amount` approved for /// the current contract to manage. - function safeTransferFrom( - address token, - address from, - address to, - uint256 amount - ) internal { + function safeTransferFrom(address token, address from, address to, uint256 amount) internal { /// @solidity memory-safe-assembly assembly { let m := mload(0x40) // Cache the free memory pointer. @@ -85,11 +80,7 @@ library SafeTransferLib { /// /// The `from` account must have at least `amount` approved for /// the current contract to manage. - function safeTransferAllFrom( - address token, - address from, - address to - ) internal returns (uint256 amount) { + function safeTransferAllFrom(address token, address from, address to) internal returns (uint256 amount) { /// @solidity memory-safe-assembly assembly { let m := mload(0x40) // Cache the free memory pointer. @@ -167,10 +158,7 @@ library SafeTransferLib { /// @dev Sends all of ERC20 `token` from the current contract to `to`. /// Reverts upon failure. - function safeTransferAll( - address token, - address to - ) internal returns (uint256 amount) { + function safeTransferAll(address token, address to) internal returns (uint256 amount) { /// @solidity memory-safe-assembly assembly { mstore(0x00, 0x70a08231) // Store the function selector of `balanceOf(address)`. @@ -244,23 +232,21 @@ library SafeTransferLib { /// @dev Returns the amount of ERC20 `token` owned by `account`. /// Returns zero if the `token` does not exist. - function balanceOf( - address token, - address account - ) internal view returns (uint256 amount) { + function balanceOf(address token, address account) internal view returns (uint256 amount) { /// @solidity memory-safe-assembly assembly { mstore(0x14, account) // Store the `account` argument. // Store the function selector of `balanceOf(address)`. mstore(0x00, 0x70a08231000000000000000000000000) - amount := mul( - mload(0x20), - and( - // The arguments of `and` are evaluated from right to left. - gt(returndatasize(), 0x1f), // At least 32 bytes returned. - staticcall(gas(), token, 0x10, 0x24, 0x20, 0x20) + amount := + mul( + mload(0x20), + and( + // The arguments of `and` are evaluated from right to left. + gt(returndatasize(), 0x1f), // At least 32 bytes returned. + staticcall(gas(), token, 0x10, 0x24, 0x20, 0x20) + ) ) - ) } } } diff --git a/contracts/verifying/VerifyingSingletonPaymaster.sol b/contracts/verifying/VerifyingSingletonPaymaster.sol deleted file mode 100644 index 567c0c3..0000000 --- a/contracts/verifying/VerifyingSingletonPaymaster.sol +++ /dev/null @@ -1,281 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.8.17; - -/* solhint-disable reason-string */ -/* solhint-disable no-inline-assembly */ -import {ECDSA} from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; -import {ReentrancyGuard} from "@openzeppelin/contracts/security/ReentrancyGuard.sol"; -import {UserOperation, UserOperationLib} from "@account-abstraction/contracts/interfaces/UserOperation.sol"; -import "../BasePaymaster.sol"; -import {PaymasterHelpers, PaymasterData, PaymasterContext} from "./PaymasterHelpers.sol"; -import {VerifyingPaymasterErrors} from "../common/Errors.sol"; - -/** - * @title A sample paymaster that uses external service to decide whether to pay for the UserOp. - * @dev The paymaster trusts an external signer to sign the transaction. - * The calling user must pass the UserOp to that external signer first, which performs whatever - * off-chain verification before signing the UserOp. - * @notice That this signature is NOT a replacement for wallet signature: - * - The paymaster signs to agree to PAY for GAS. - * - The wallet signs to prove identity and wallet ownership. - */ -contract VerifyingSingletonPaymaster is - BasePaymaster, - ReentrancyGuard, - VerifyingPaymasterErrors -{ - using ECDSA for bytes32; - using UserOperationLib for UserOperation; - using PaymasterHelpers for UserOperation; - using PaymasterHelpers for bytes; - using PaymasterHelpers for PaymasterData; - - // Gas used in EntryPoint._handlePostOp() method (including this#postOp() call) - uint256 private unaccountedEPGasOverhead; - mapping(address => uint256) public paymasterIdBalances; - - address public verifyingSigner; - - event EPGasOverheadChanged( - uint256 indexed _oldValue, - uint256 indexed _newValue - ); - - event VerifyingSignerChanged( - address indexed _oldSigner, - address indexed _newSigner, - address indexed _actor - ); - event GasDeposited(address indexed _paymasterId, uint256 indexed _value); - event GasWithdrawn( - address indexed _paymasterId, - address indexed _to, - uint256 indexed _value - ); - event GasBalanceDeducted( - address indexed _paymasterId, - uint256 indexed _charge - ); - - constructor( - address _owner, - IEntryPoint _entryPoint, - address _verifyingSigner - ) payable BasePaymaster(_owner, _entryPoint) { - if (address(_entryPoint) == address(0)) revert EntryPointCannotBeZero(); - if (_verifyingSigner == address(0)) - revert VerifyingSignerCannotBeZero(); - assembly { - sstore(verifyingSigner.slot, _verifyingSigner) - } - unaccountedEPGasOverhead = 12000; - } - - /** - * @dev Add a deposit for this paymaster and given paymasterId (Dapp Depositor address), used for paying for transaction fees - * @param paymasterId dapp identifier for which deposit is being made - */ - function depositFor(address paymasterId) external payable nonReentrant { - if (paymasterId == address(0)) revert PaymasterIdCannotBeZero(); - if (msg.value == 0) revert DepositCanNotBeZero(); - paymasterIdBalances[paymasterId] = - paymasterIdBalances[paymasterId] + - msg.value; - entryPoint.depositTo{value: msg.value}(address(this)); - emit GasDeposited(paymasterId, msg.value); - } - - /** - * @dev Set a new verifying signer address. - * Can only be called by the owner of the contract. - * @param _newVerifyingSigner The new address to be set as the verifying signer. - * @notice If _newVerifyingSigner is set to zero address, it will revert with an error. - * After setting the new signer address, it will emit an event VerifyingSignerChanged. - */ - function setSigner(address _newVerifyingSigner) external payable onlyOwner { - if (_newVerifyingSigner == address(0)) - revert VerifyingSignerCannotBeZero(); - address oldSigner = verifyingSigner; - assembly { - sstore(verifyingSigner.slot, _newVerifyingSigner) - } - emit VerifyingSignerChanged(oldSigner, _newVerifyingSigner, msg.sender); - } - - function setUnaccountedEPGasOverhead(uint256 value) external onlyOwner { - uint256 oldValue = unaccountedEPGasOverhead; - unaccountedEPGasOverhead = value; - emit EPGasOverheadChanged(oldValue, value); - } - - /** - * @dev get the current deposit for paymasterId (Dapp Depositor address) - * @param paymasterId dapp identifier - */ - function getBalance( - address paymasterId - ) external view returns (uint256 balance) { - balance = paymasterIdBalances[paymasterId]; - } - - /** - * @dev Withdraws the specified amount of gas tokens from the paymaster's balance and transfers them to the specified address. - * @param withdrawAddress The address to which the gas tokens should be transferred. - * @param amount The amount of gas tokens to withdraw. - */ - function withdrawTo( - address payable withdrawAddress, - uint256 amount - ) public override nonReentrant { - if (withdrawAddress == address(0)) revert CanNotWithdrawToZeroAddress(); - uint256 currentBalance = paymasterIdBalances[msg.sender]; - if (amount > currentBalance) - revert InsufficientBalance(amount, currentBalance); - paymasterIdBalances[msg.sender] = - paymasterIdBalances[msg.sender] - - amount; - entryPoint.withdrawTo(withdrawAddress, amount); - emit GasWithdrawn(msg.sender, withdrawAddress, amount); - } - - /** - @dev Override the default implementation. - */ - function deposit() public payable virtual override { - revert("user DepositFor instead"); - } - - /** - * @dev This method is called by the off-chain service, to sign the request. - * It is called on-chain from the validatePaymasterUserOp, to validate the signature. - * @notice That this signature covers all fields of the UserOperation, except the "paymasterAndData", - * which will carry the signature itself. - * @return hash we're going to sign off-chain (and validate on-chain) - */ - function getHash( - UserOperation calldata userOp, - address paymasterId, - uint48 validUntil, - uint48 validAfter - ) public view returns (bytes32) { - //can't use userOp.hash(), since it contains also the paymasterAndData itself. - address sender = userOp.getSender(); - return - keccak256( - abi.encode( - sender, - userOp.nonce, - keccak256(userOp.initCode), - keccak256(userOp.callData), - userOp.callGasLimit, - userOp.verificationGasLimit, - userOp.preVerificationGas, - userOp.maxFeePerGas, - userOp.maxPriorityFeePerGas, - block.chainid, - address(this), - paymasterId, - validUntil, - validAfter - ) - ); - } - - /** - * @dev Executes the paymaster's payment conditions - * @param context payment conditions signed by the paymaster in `validatePaymasterUserOp` - * @param actualGasCost amount to be paid to the entry point in wei - */ - function _postOp( - PostOpMode /** mode */, - bytes calldata context, - uint256 actualGasCost - ) internal virtual override { - PaymasterContext memory data = context._decodePaymasterContext(); - address extractedPaymasterId = data.paymasterId; - uint256 effectiveGasPrice = getGasPrice( - data.maxFeePerGas, - data.maxPriorityFeePerGas - ); - uint256 balToDeduct = actualGasCost + - unaccountedEPGasOverhead * - effectiveGasPrice; - paymasterIdBalances[extractedPaymasterId] = - paymasterIdBalances[extractedPaymasterId] - - balToDeduct; - emit GasBalanceDeducted(extractedPaymasterId, balToDeduct); - } - - /** - * @dev Verify that an external signer signed the paymaster data of a user operation. - * The paymaster data is expected to be the paymaster and a signature over the entire request parameters. - * @param userOp The UserOperation struct that represents the current user operation. - * userOpHash The hash of the UserOperation struct. - * @param requiredPreFund The required amount of pre-funding for the paymaster. - * @return context A context string returned by the entry point after successful validation. - * @return validationData An integer returned by the entry point after successful validation. - */ - function _validatePaymasterUserOp( - UserOperation calldata userOp, - bytes32 /*userOpHash*/, - uint256 requiredPreFund - ) internal override view returns (bytes memory context, uint256 validationData) { - PaymasterData memory paymasterData = userOp._decodePaymasterData(); - bytes32 hash = getHash( - userOp, - paymasterData.paymasterId, - paymasterData.validUntil, - paymasterData.validAfter - ); - uint256 sigLength = paymasterData.signatureLength; - // "require" is here so for the revert reason on invalid signature will be of "VerifyingPaymaster", and not "ECDSA" - if (sigLength != 65) revert InvalidPaymasterSignatureLength(sigLength); - //don't revert on signature failure: return SIG_VALIDATION_FAILED - if ( - verifyingSigner != - hash.toEthSignedMessageHash().recover(paymasterData.signature) - ) { - // empty context and sigFailed with time range provided - return ( - "", - _packValidationData( - true, - paymasterData.validUntil, - paymasterData.validAfter - ) - ); - } - if (requiredPreFund > paymasterIdBalances[paymasterData.paymasterId]) - revert InsufficientBalance( - requiredPreFund, - paymasterIdBalances[paymasterData.paymasterId] - ); - return ( - userOp.paymasterContext( - paymasterData, - userOp.maxFeePerGas, - userOp.maxPriorityFeePerGas - ), - _packValidationData( - false, - paymasterData.validUntil, - paymasterData.validAfter - ) - ); - } - - function getGasPrice( - uint256 maxFeePerGas, - uint256 maxPriorityFeePerGas - ) internal view returns (uint256) { - if (maxFeePerGas == maxPriorityFeePerGas) { - //legacy mode (for networks that don't support basefee opcode) - return maxFeePerGas; - } - return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee); - } - - function min(uint256 a, uint256 b) internal pure returns (uint256) { - return a < b ? a : b; - } -} diff --git a/foundry.toml b/foundry.toml index 7f69fd6..4acd029 100644 --- a/foundry.toml +++ b/foundry.toml @@ -2,7 +2,9 @@ src = 'contracts' out = 'out' libs = ['node_modules', 'lib'] -test = 'test' -cache_path = 'forge-cache' +test = 'test/foundry' +cache_path = 'forge-cache' viaIr = true +evm_version = "paris" +auto_detect_solc = true # See more config options https://book.getfoundry.sh/reference/config.html diff --git a/hardhat.config.ts b/hardhat.config.ts index 82b0711..17a86e1 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -21,9 +21,10 @@ const config: HardhatUserConfig = { solidity: { compilers: [ { - version: "0.8.17", + version: "0.8.23", settings: { optimizer: { enabled: true, runs: 800 }, + evmVersion: "paris", viaIR: true, }, }, diff --git a/lib/account-abstraction b/lib/account-abstraction index abff2ac..048d8b0 160000 --- a/lib/account-abstraction +++ b/lib/account-abstraction @@ -1 +1 @@ -Subproject commit abff2aca61a8f0934e533d0d352978055fddbd96 +Subproject commit 048d8b0fc9eb681f8a267a8de55bfb45ea4cfc2d diff --git a/lib/forge-std b/lib/forge-std index f73c73d..1d0766b 160000 --- a/lib/forge-std +++ b/lib/forge-std @@ -1 +1 @@ -Subproject commit f73c73d2018eb6a111f35e4dae7b4f27401e9421 +Subproject commit 1d0766bc5d814f117c7b1e643828f7d85024fb51 diff --git a/lib/scw-contracts b/lib/scw-contracts index b5be539..44fdb23 160000 --- a/lib/scw-contracts +++ b/lib/scw-contracts @@ -1 +1 @@ -Subproject commit b5be5399ef0e411b62b4342e12a15e34c35bb83c +Subproject commit 44fdb23b2d811d78523a6767ce8da7fdd2879412 diff --git a/package.json b/package.json index c1a39e3..a410e00 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "scripts": { "test": "yarn test:hardhat && yarn test:foundry", "clean": "yarn hardhat clean && forge clean", - "build": "yarn hardhat compile && yarn hardhat typechain && yarn prepare-typechain && yarn build:foundry", + "build": "yarn hardhat compile && yarn hardhat typechain && yarn prepare-typechain && yarn prepare-sa && yarn build:foundry", "clean:build": "yarn clean && yarn build", "build:foundry": "forge build --via-ir", "build:hardhat": "yarn hardhat compile", @@ -25,6 +25,7 @@ "postpack": "pinst --enable && ./scripts/postpack-contracts.sh", "coverage": "COVERAGE=1 DISABLE_VIA_IR=true hardhat coverage", "prepare-typechain": "cd lib/account-abstraction && yarn install && yarn hardhat typechain", + "prepare-sa": "cd lib/scw-contracts && git checkout develop && yarn install", "prepare": "husky install" }, "repository": { @@ -45,7 +46,7 @@ "devDependencies": { "@chainlink/contracts": "^0.6.0", "@nomicfoundation/hardhat-chai-matchers": "^1.0.6", - "@nomicfoundation/hardhat-foundry": "^1.0.0", + "@nomicfoundation/hardhat-foundry": "^1.1.1", "@nomicfoundation/hardhat-network-helpers": "^1.0.8", "@nomicfoundation/hardhat-toolbox": "^2.0.2", "@nomiclabs/hardhat-ethers": "^2.2.3", @@ -87,19 +88,12 @@ "typescript": "^5.2.2" }, "dependencies": { - "@account-abstraction/contracts": "^0.6.0", - "@biconomy-devx/account-contracts-v2": "^2.0.2", - "@biconomy/account-contracts": "^2.0.0", + "@account-abstraction/contracts": "0.6.0", + "@biconomy-devx/account-contracts-v2": "^2.0.3", "@chainlink/contracts": "^0.6.0", "@ethersproject/abstract-signer": "^5.6.2", "@ethersproject/constants": "^5.6.1", - "@mean-finance/uniswap-v3-oracle": "^1.0.3", - "@openzeppelin/contracts": "4.8.1", - "@openzeppelin/contracts-upgradeable": "4.8.1", - "@pimlico/erc20-paymaster": "^0.0.1", - "@uniswap/sdk-core": "^3.2.2", - "@uniswap/universal-router": "^1.4.1", - "@uniswap/v3-periphery": "^1.4.3", + "@openzeppelin/contracts": "4.9.3", "axios": "^1.4.0", "chai-as-promised": "^7.1.1", "chai-string": "^1.5.0", diff --git a/remappings.txt b/remappings.txt index 845bd0a..101c198 100644 --- a/remappings.txt +++ b/remappings.txt @@ -1,2 +1,3 @@ ds-test/=lib/forge-std/lib/ds-test/src/ forge-std/=lib/forge-std/src/ +@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/ diff --git a/scripts/1-deploy-token-paymaster.ts b/scripts/1-deploy-token-paymaster.ts index 77db8bf..9e87583 100644 --- a/scripts/1-deploy-token-paymaster.ts +++ b/scripts/1-deploy-token-paymaster.ts @@ -4,6 +4,7 @@ import { DEPLOYMENT_SALTS, encodeParam, isContract, + delay, } from "./utils"; import { Deployer, Deployer__factory } from "../typechain-types"; @@ -15,21 +16,13 @@ const verifyingSigner = process.env.PAYMASTER_SIGNER_ADDRESS_PROD || ""; const DEPLOYER_CONTRACT_ADDRESS = process.env.DEPLOYER_CONTRACT_ADDRESS_PROD || ""; -function delay(ms: number) { - return new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, ms); - }); -} - async function deployTokenPaymasterContract( deployerInstance: Deployer, earlyOwnerAddress: string ): Promise { try { const salt = ethers.utils.keccak256( - ethers.utils.toUtf8Bytes(DEPLOYMENT_SALTS.TOKEN_PAYMASTER) + ethers.utils.toUtf8Bytes(DEPLOYMENT_SALTS.TOKEN_PAYMASTER_V2) ); const BiconomyTokenPaymaster = await ethers.getContractFactory( @@ -107,6 +100,9 @@ async function getPredeployedDeployerContractInstance(): Promise { async function main() { const accounts = await ethers.getSigners(); const earlyOwner = await accounts[0].getAddress(); + if (earlyOwner === undefined) { + throw new Error("earlyOwner is undefined"); + } const deployerInstance = await getPredeployedDeployerContractInstance(); console.log("========================================="); diff --git a/scripts/2-deploy-oracle-aggregator.ts b/scripts/2-deploy-oracle-aggregator.ts deleted file mode 100644 index 1f0a83e..0000000 --- a/scripts/2-deploy-oracle-aggregator.ts +++ /dev/null @@ -1,123 +0,0 @@ -import { ethers, run } from "hardhat"; -import { - deployContract, - DEPLOYMENT_SALTS, - encodeParam, - isContract, -} from "./utils"; -import { Deployer, Deployer__factory } from "../typechain-types"; - -const provider = ethers.provider; -const DEPLOYER_CONTRACT_ADDRESS = - process.env.DEPLOYER_CONTRACT_ADDRESS_PROD || ""; - -function delay(ms: number) { - return new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, ms); - }); -} - -async function deployChainlinkOracleAggregatorContract( - deployerInstance: Deployer, - earlyOwnerAddress: string -): Promise { - try { - const ORACLE_AGGREGATOR_SALT = ethers.utils.keccak256( - ethers.utils.toUtf8Bytes(DEPLOYMENT_SALTS.ORACLE_AGGREGATOR) - ); - - const OracleAggregator = await ethers.getContractFactory( - "ChainlinkOracleAggregator" - ); - const oracleAggregatorBytecode = `${OracleAggregator.bytecode}${encodeParam( - "address", - earlyOwnerAddress - ).slice(2)}`; - const oracleAggregatorComputedAddr = await deployerInstance.addressOf( - ORACLE_AGGREGATOR_SALT - ); - console.log( - "Chainlink Oracle Aggregator Computed Address: ", - oracleAggregatorComputedAddr - ); - - const isOracleAggregatorDeployed = await isContract( - oracleAggregatorComputedAddr, - provider - ); // true (deployed on-chain) - - if (!isOracleAggregatorDeployed) { - await deployContract( - DEPLOYMENT_SALTS.ORACLE_AGGREGATOR, - oracleAggregatorComputedAddr, - ORACLE_AGGREGATOR_SALT, - oracleAggregatorBytecode, - deployerInstance - ); - await delay(10000); - await run(`verify:verify`, { - address: oracleAggregatorComputedAddr, - constructorArguments: [earlyOwnerAddress], - }); - } else { - console.log( - "Chainlink Oracle Aggregator is already deployed with address ", - oracleAggregatorComputedAddr - ); - } - return oracleAggregatorComputedAddr; - } catch (err) { - console.log(err); - } -} - -/* - * This function is added to support the flow with pre-deploying the deployer contract - * using the `deployer-contract.deploy.ts` script. - */ -async function getPredeployedDeployerContractInstance(): Promise { - const code = await provider.getCode(DEPLOYER_CONTRACT_ADDRESS); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Deployer not deployed on chain ${chainId}, deploy it with deployer-contract.deploy.ts script before using this script.` - ); - throw new Error("Deployer not deployed"); - } else { - console.log( - "Deploying with EOA %s through Deployer Contract %s", - signer.address, - DEPLOYER_CONTRACT_ADDRESS - ); - return Deployer__factory.connect(DEPLOYER_CONTRACT_ADDRESS, signer); - } -} - -async function main() { - const accounts = await ethers.getSigners(); - const earlyOwner = await accounts[0].getAddress(); - - const deployerInstance = await getPredeployedDeployerContractInstance(); - console.log("========================================="); - - // Deploy Chainlink Oracle Aggregator - // @note: owner is kept the deployer because we need to perform more actions on this contract using owner as part of other scripts - // @note: ownership should be transferred at the end - const oracleAggregatorAddress = await deployChainlinkOracleAggregatorContract( - deployerInstance, - earlyOwner - ); - console.log( - "==================oracleAggregatorAddress=======================", - oracleAggregatorAddress - ); -} - -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); diff --git a/scripts/3-deploy-derived-price-feeds.ts b/scripts/3-deploy-derived-price-feeds.ts deleted file mode 100644 index 5af3485..0000000 --- a/scripts/3-deploy-derived-price-feeds.ts +++ /dev/null @@ -1,7 +0,0 @@ -// Should be able to specify array of symbols for which you need to run this script - -// Deploy price feeds using appropritae salts from config. Could be a way to fetch salt using the symbol. - -// If price feed is supposed to be derived then go ahead and deploy the derived feed - -// TODO: passing the array of symbols and chainId - based on chainId config file is fetched, only run on required symbols diff --git a/scripts/4-set-token-oracles.ts b/scripts/4-set-token-oracles.ts deleted file mode 100644 index 789e366..0000000 --- a/scripts/4-set-token-oracles.ts +++ /dev/null @@ -1,11 +0,0 @@ -// Connect and return instance with given EOA signer and provided address - -// Should be able to specify array of symbols for which you need to run this script - -// Fetch price feed addresses and priceFeedFunction - -// Set token oracles using the current owner - -// Transfer ownership back to intended owner if ownership was transferred back to run the script - -// TODO: passing the array of symbols and chainId - based on chainId config file is fetched, only run on required symbols diff --git a/scripts/8-deploy-verifying-paymaster.ts b/scripts/8-deploy-sponsorship-paymaster.ts similarity index 63% rename from scripts/8-deploy-verifying-paymaster.ts rename to scripts/8-deploy-sponsorship-paymaster.ts index 1cd76e9..0dbc13f 100644 --- a/scripts/8-deploy-verifying-paymaster.ts +++ b/scripts/8-deploy-sponsorship-paymaster.ts @@ -4,6 +4,7 @@ import { DEPLOYMENT_SALTS, encodeParam, isContract, + delay, } from "./utils"; import { Deployer, Deployer__factory } from "../typechain-types"; @@ -12,71 +13,78 @@ const entryPointAddress = process.env.ENTRY_POINT_ADDRESS || "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789"; const verifyingSigner = process.env.PAYMASTER_SIGNER_ADDRESS_PROD || ""; +const feeCollector = process.env.SPONSORSHIP_FEE_COLLECTOR_ADDRESS_PROD || ""; const DEPLOYER_CONTRACT_ADDRESS = process.env.DEPLOYER_CONTRACT_ADDRESS_PROD || ""; -function delay(ms: number) { - return new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, ms); - }); -} - -async function deployVerifyingPaymasterContract( +async function deploySponsorshipPaymasterContract( deployerInstance: Deployer, earlyOwnerAddress: string ): Promise { try { const salt = ethers.utils.keccak256( - ethers.utils.toUtf8Bytes(DEPLOYMENT_SALTS.SINGELTON_PAYMASTER) + ethers.utils.toUtf8Bytes(DEPLOYMENT_SALTS.SPONSORSHIP_PAYMASTER) ); - const BiconomyVerifyingPaymaster = await ethers.getContractFactory( - "VerifyingSingletonPaymaster" + const SponsorshipPaymaster = await ethers.getContractFactory( + "SponsorshipPaymaster" ); - const verifyingPaymasterBytecode = `${ - BiconomyVerifyingPaymaster.bytecode + + const sponsorshipPaymasterBytecode = `${ + SponsorshipPaymaster.bytecode }${encodeParam("address", earlyOwnerAddress).slice(2)}${encodeParam( "address", entryPointAddress - ).slice(2)}${encodeParam("address", verifyingSigner).slice(2)}`; + ).slice(2)}${encodeParam("address", verifyingSigner).slice(2)}${encodeParam( + "address", + feeCollector + ).slice(2)}`; - const verifyingPaymasterComputedAddr = await deployerInstance.addressOf( + const sponsorshipPaymasterComputedAddr = await deployerInstance.addressOf( salt ); console.log( - "Verifying paymaster Computed Address: ", - verifyingPaymasterComputedAddr + "Sponsorship paymaster Computed Address: ", + sponsorshipPaymasterComputedAddr ); const isContractDeployed = await isContract( - verifyingPaymasterComputedAddr, + sponsorshipPaymasterComputedAddr, provider ); if (!isContractDeployed) { await deployContract( - DEPLOYMENT_SALTS.SINGELTON_PAYMASTER, - verifyingPaymasterComputedAddr, + DEPLOYMENT_SALTS.SPONSORSHIP_PAYMASTER, + sponsorshipPaymasterComputedAddr, salt, - verifyingPaymasterBytecode, + sponsorshipPaymasterBytecode, deployerInstance ); await delay(5000); await run(`verify:verify`, { - address: verifyingPaymasterComputedAddr, + address: sponsorshipPaymasterComputedAddr, constructorArguments: [ earlyOwnerAddress, entryPointAddress, verifyingSigner, + feeCollector, ], }); } else { + await run(`verify:verify`, { + address: sponsorshipPaymasterComputedAddr, + constructorArguments: [ + earlyOwnerAddress, + entryPointAddress, + verifyingSigner, + feeCollector, + ], + }); console.log( - "Verifying Paymaster is Already deployed with address ", - verifyingPaymasterComputedAddr + "Sponsorship Paymaster is Already deployed with address ", + sponsorshipPaymasterComputedAddr ); } - return verifyingPaymasterComputedAddr; + return sponsorshipPaymasterComputedAddr; } catch (err) { console.log(err); } @@ -109,18 +117,21 @@ async function getPredeployedDeployerContractInstance(): Promise { async function main() { const accounts = await ethers.getSigners(); const earlyOwner = await accounts[0].getAddress(); + if (earlyOwner === undefined) { + throw new Error("earlyOwner is undefined"); + } const deployerInstance = await getPredeployedDeployerContractInstance(); console.log("========================================="); // Deploy Verifying paymaster - const verifyingPaymasterAddress = await deployVerifyingPaymasterContract( + const sponsorshipPaymasterAddress = await deploySponsorshipPaymasterContract( deployerInstance, earlyOwner ); console.log( - "==================verifyingPaymasterAddress=======================", - verifyingPaymasterAddress + "==================sponsorshipPaymasterAddress=======================", + sponsorshipPaymasterAddress ); } diff --git a/scripts/configs/dev/token-config-arbitrum-goerli.json b/scripts/configs/dev/token-config-arbitrum-goerli.json index 6bd43d2..f306d29 100644 --- a/scripts/configs/dev/token-config-arbitrum-goerli.json +++ b/scripts/configs/dev/token-config-arbitrum-goerli.json @@ -5,10 +5,6 @@ "address": "0x9Ff2A6b0cdc4aB06BBE231327edfE493f130A994", "nativeOracleAddress": "0x62CAe0FA2da220f43a51F86Db2EDb36DcA9A5A08", "tokenOracleAddress": "0x1692Bdd32F31b831caAc1b0c9fAF68613682813b", - "description": "USDC / ETH", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x000005ABaE3DEAdbe1FBD12105F950efbA9eaec4", - "feedSalt": "DEVX_PRICE_FEED_USDC_V0_27062023_uiaqdyv", "derivedFeed": true }, { @@ -16,21 +12,13 @@ "address": "0x466cd6F70015e11dc53e5757B4bcFeCcD7C31139", "nativeOracleAddress": "0x62CAe0FA2da220f43a51F86Db2EDb36DcA9A5A08", "tokenOracleAddress": "0x0a023a3423D9b27A0BE48c768CCF2dD7877fEf5E", - "description": "USDT / ETH", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x000001E2C2B39542c30A3fE57c4487030bC03adF", - "feedSalt": "DEVX_PRICE_FEED_USDT_V0_27062023_dIos1Nw", "derivedFeed": true }, { "symbol": "LINK", "address": "0x6bDB7FE59ec323b6A9bC96a988a971EEDA3958d9", - "nativeOracleAddress": "", - "tokenOracleAddress": "", - "description": "LINK / ETH", - "priceFeedFunction": "latestAnswer()", - "priceFeedAddress": "0x1AdDb2368414B3b4cF1BCe7A887d2De7Bfb6886f", - "feedSalt": "DEVX_PRICE_FEED_LINK_V0_27062023_JHIxs6o", + "nativeOracleAddress": "0x62CAe0FA2da220f43a51F86Db2EDb36DcA9A5A08", + "tokenOracleAddress": "0x1AdDb2368414B3b4cF1BCe7A887d2De7Bfb6886f", "derivedFeed": false } ] diff --git a/scripts/configs/dev/token-config-bnb-mainnet.json b/scripts/configs/dev/token-config-bnb-mainnet.json index 8b46861..41d14bb 100644 --- a/scripts/configs/dev/token-config-bnb-mainnet.json +++ b/scripts/configs/dev/token-config-bnb-mainnet.json @@ -3,67 +3,43 @@ { "symbol": "USDC", "address": "0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d", - "nativeOracleAddress": "", - "tokenOracleAddress": "", - "description": "USDC / BNB", - "priceFeedFunction": "latestAnswer()", - "priceFeedAddress": "0x45f86CA2A8BC9EBD757225B19a1A0D7051bE46Db", - "feedSalt": "DEVX_PRICE_FEED_USDC_V0_27062023_uiaqdyv", + "nativeOracleAddress": "0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE", + "tokenOracleAddress": "0x45f86CA2A8BC9EBD757225B19a1A0D7051bE46Db", "derivedFeed": false }, { "symbol": "USDT", "address": "0x55d398326f99059fF775485246999027B3197955", - "nativeOracleAddress": "", - "tokenOracleAddress": "", - "description": "USDT / BNB", - "priceFeedFunction": "latestAnswer()", - "priceFeedAddress": "0xD5c40f5144848Bd4EF08a9605d860e727b991513", - "feedSalt": "DEVX_PRICE_FEED_USDT_V0_27062023_dIos1Nw", + "nativeOracleAddress": "0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE", + "tokenOracleAddress": "0xD5c40f5144848Bd4EF08a9605d860e727b991513", "derivedFeed": false }, { "symbol": "DAI", "address": "0x1AF3F329e8BE154074D8769D1FFa4eE058B1DBc3", - "nativeOracleAddress": "", - "tokenOracleAddress": "", - "description": "DAI / BNB", - "priceFeedFunction": "latestAnswer()", - "priceFeedAddress": "0x8EC213E7191488C7873cEC6daC8e97cdbAdb7B35", - "feedSalt": "DEVX_PRICE_FEED_DAI_V0_27062023_1m7JNWQ", + "nativeOracleAddress": "0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE", + "tokenOracleAddress": "0x8EC213E7191488C7873cEC6daC8e97cdbAdb7B35", "derivedFeed": false }, { "symbol": "TWT", "address": "0x4b0f1812e5df2a09796481ff14017e6005508003", - "nativeOracleAddress": "", - "tokenOracleAddress": "", - "description": "TWT / BNB", - "priceFeedFunction": "latestAnswer()", - "priceFeedAddress": "0x7E728dFA6bCa9023d9aBeE759fDF56BEAb8aC7aD", - "feedSalt": "DEVX_PRICE_FEED_TWT_V0_27062023_92Xklvq", + "nativeOracleAddress": "0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE", + "tokenOracleAddress": "0x7E728dFA6bCa9023d9aBeE759fDF56BEAb8aC7aDx", "derivedFeed": false }, { "symbol": "CAKE", "address": "0x0E09FaBB73Bd3Ade0a17ECC321fD13a19e81cE82", - "nativeOracleAddress": "", - "tokenOracleAddress": "", - "description": "CAKE / BNB", - "priceFeedFunction": "latestAnswer()", - "priceFeedAddress": "0xcB23da9EA243f53194CBc2380A6d4d9bC046161f", - "feedSalt": "DEVX_PRICE_FEED_CAKE_V0_27062023_1BKpzde", + "nativeOracleAddress": "0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE", + "tokenOracleAddress": "0xcB23da9EA243f53194CBc2380A6d4d9bC046161f", "derivedFeed": false }, { "symbol": "LINK", "address": "0xF8A0BF9cF54Bb92F17374d9e9A321E6a111a51bD", - "nativeOracleAddress": "", - "tokenOracleAddress": "", - "description": "LINK / BNB", - "priceFeedFunction": "latestAnswer()", - "priceFeedAddress": "0xB38722F6A608646a538E882Ee9972D15c86Fc597", - "feedSalt": "DEVX_PRICE_FEED_LINK_V0_27062023_JHIxs6o", + "nativeOracleAddress": "0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE", + "tokenOracleAddress": "0xB38722F6A608646a538E882Ee9972D15c86Fc597", "derivedFeed": false }, { @@ -71,10 +47,6 @@ "address": "0x111111111117dC0aa78b770fA6A738034120C302", "nativeOracleAddress": "0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE", "tokenOracleAddress": "0x1B329402Cb1825C6F30A0d92aB9E2862BE47333f", - "description": "1INCH / BNB", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x00000C451fA0b0a79a36c82820F061683E26714c", - "feedSalt": "DEVX_PRICE_FEED_1INCH_V0_27062023_XhXA3sd", "derivedFeed": true }, { @@ -82,10 +54,6 @@ "address": "0xfb6115445Bff7b52FeB98650C87f44907E58f802", "nativeOracleAddress": "0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE", "tokenOracleAddress": "0xA8357BF572460fC40f4B0aCacbB2a6A61c89f475", - "description": "AAVE / BNB", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x0000AF22A276F86B405835c18863e1C2A679D9e3", - "feedSalt": "DEVX_PRICE_FEED_AAVE_V0_28062023_HsugnpY", "derivedFeed": true } ] diff --git a/scripts/configs/dev/token-config-bnb-testnet.json b/scripts/configs/dev/token-config-bnb-testnet.json index f841b8e..4fb655b 100644 --- a/scripts/configs/dev/token-config-bnb-testnet.json +++ b/scripts/configs/dev/token-config-bnb-testnet.json @@ -5,10 +5,6 @@ "address": "0x1ffa9c87ead57adc9e4f9a7d26ec3a52150db3b0", "nativeOracleAddress": "0x2514895c72f50D8bd4B4F9b1110F0D6bD2c97526", "tokenOracleAddress": "0x90c069C4538adAc136E051052E14c1cD799C41B7", - "description": "USDC / BNB", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x000005abae3deadbe1fbd12105f950efba9eaec4", - "feedSalt": "DEVX_PRICE_FEED_USDC_V0_27062023_uiaqdyv", "derivedFeed": true }, { @@ -16,10 +12,6 @@ "address": "0x03bbb5660b8687c2aa453a0e42dcb6e0732b1266", "nativeOracleAddress": "0x2514895c72f50D8bd4B4F9b1110F0D6bD2c97526", "tokenOracleAddress": "0xEca2605f0BCF2BA5966372C99837b1F182d3D620", - "description": "USDT / BNB", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x000001e2c2b39542c30a3fe57c4487030bc03adf", - "feedSalt": "DEVX_PRICE_FEED_USDT_V0_27062023_dIos1Nw", "derivedFeed": true }, { @@ -27,10 +19,6 @@ "address": "0x355c8c8395fadf2eaa6bb27f86e53e432e3de4e6", "nativeOracleAddress": "0x2514895c72f50D8bd4B4F9b1110F0D6bD2c97526", "tokenOracleAddress": "0xE4eE17114774713d2De0eC0f035d4F7665fc025D", - "description": "DAI / BNB", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x000000d2da196474046c7a4d94ab0e566b26d054", - "feedSalt": "DEVX_PRICE_FEED_DAI_V0_27062023_1m7JNWQ", "derivedFeed": true }, { @@ -38,10 +26,6 @@ "address": "0xc1537ab4f2e0b1c578baea06b5baae8f87ce971c", "nativeOracleAddress": "0x2514895c72f50D8bd4B4F9b1110F0D6bD2c97526", "tokenOracleAddress": "0x298619601ebCd58d0b526963Deb2365B485Edc74", - "description": "AAVE / BNB", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x0000AF22A276F86B405835c18863e1C2A679D9e3", - "feedSalt": "DEVX_PRICE_FEED_AAVE_V0_28062023_HsugnpY", "derivedFeed": true }, { @@ -49,10 +33,6 @@ "address": "0x81f9e7a56f6869a9a8c385d1e0701b312439501f", "nativeOracleAddress": "0x2514895c72f50D8bd4B4F9b1110F0D6bD2c97526", "tokenOracleAddress": "0x81faeDDfeBc2F8Ac524327d70Cf913001732224C", - "description": "CAKE / BNB", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x000007198738f877c01d9b7e4a4e1bd17e46e4a8", - "feedSalt": "DEVX_PRICE_FEED_CAKE_V0_27062023_1BKpzde", "derivedFeed": true }, { @@ -60,10 +40,6 @@ "address": "0xdeb12ea437c116ed823ab49244cafec4e41704cb", "nativeOracleAddress": "0x2514895c72f50D8bd4B4F9b1110F0D6bD2c97526", "tokenOracleAddress": "0x1B329402Cb1825C6F30A0d92aB9E2862BE47333f", - "description": "LINK / BNB", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x00000da809fe7be1297ee731f998141ba352778d", - "feedSalt": "DEVX_PRICE_FEED_LINK_V0_27062023_JHIxs6o", "derivedFeed": true } ] diff --git a/scripts/configs/dev/token-config-goerli.json b/scripts/configs/dev/token-config-goerli.json index 9cd4674..0a6dfb7 100644 --- a/scripts/configs/dev/token-config-goerli.json +++ b/scripts/configs/dev/token-config-goerli.json @@ -5,10 +5,6 @@ "address": "0xb5B640E6414b6DeF4FC9B3C1EeF373925effeCcF", "nativeOracleAddress": "0xD4a33860578De61DBAbDc8BFdb98FD742fA7028e", "tokenOracleAddress": "0xAb5c49580294Aff77670F839ea425f5b78ab3Ae7", - "description": "USDC / ETH", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x000005ABaE3DEAdbe1FBD12105F950efbA9eaec4", - "feedSalt": "DEVX_PRICE_FEED_USDC_V0_27062023_uiaqdyv", "derivedFeed": true } ] diff --git a/scripts/configs/dev/token-config-mumbai.json b/scripts/configs/dev/token-config-mumbai.json index d83dd9f..14e1859 100644 --- a/scripts/configs/dev/token-config-mumbai.json +++ b/scripts/configs/dev/token-config-mumbai.json @@ -5,10 +5,6 @@ "address": "0xdA5289fCAAF71d52a80A254da614a192b693e977", "nativeOracleAddress": "0xd0D5e3DB44DE05E9F294BB0a3bEEaF030DE24Ada", "tokenOracleAddress": "0x572dDec9087154dC5dfBB1546Bb62713147e0Ab0", - "description": "USDC / MATIC", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x000005abae3deadbe1fbd12105f950efba9eaec4", - "feedSalt": "DEVX_PRICE_FEED_USDC_V0_27062023_uiaqdyv", "derivedFeed": true }, { @@ -16,10 +12,6 @@ "address": "0xeaBc4b91d9375796AA4F69cC764A4aB509080A58", "nativeOracleAddress": "0xd0D5e3DB44DE05E9F294BB0a3bEEaF030DE24Ada", "tokenOracleAddress": "0x92C09849638959196E976289418e5973CC96d645", - "description": "USDT / MATIC", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x000001e2c2b39542c30a3fe57c4487030bc03adf", - "feedSalt": "DEVX_PRICE_FEED_USDT_V0_27062023_dIos1Nw", "derivedFeed": true }, { @@ -27,10 +19,6 @@ "address": "0x27a44456bEDb94DbD59D0f0A14fE977c777fC5C3", "nativeOracleAddress": "0xd0D5e3DB44DE05E9F294BB0a3bEEaF030DE24Ada", "tokenOracleAddress": "0x0FCAa9c899EC5A91eBc3D5Dd869De833b06fB046", - "description": "DAI / MATIC", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x000000d2da196474046c7a4d94ab0e566b26d054", - "feedSalt": "DEVX_PRICE_FEED_DAI_V0_27062023_1m7JNWQ", "derivedFeed": true }, { @@ -38,10 +26,6 @@ "address": "0xE03489D4E90b22c59c5e23d45DFd59Fc0dB8a025", "nativeOracleAddress": "0xd0D5e3DB44DE05E9F294BB0a3bEEaF030DE24Ada", "tokenOracleAddress": "0x9dd18534b8f456557d11B9DDB14dA89b2e52e308", - "description": "SAND / MATIC", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x00000980455efb131c1908efa908c1eaf19db352", - "feedSalt": "DEVX_PRICE_FEED_SAND_V0_27062023_eHPqgeR", "derivedFeed": true } ] diff --git a/scripts/configs/dev/token-config-optimism-goerli.json b/scripts/configs/dev/token-config-optimism-goerli.json index 88e324f..8eb68f3 100644 --- a/scripts/configs/dev/token-config-optimism-goerli.json +++ b/scripts/configs/dev/token-config-optimism-goerli.json @@ -5,10 +5,6 @@ "address": "0xe01435b1767aED7c25C943faCbdB582b6278650f", "nativeOracleAddress": "0x57241A37733983F97C4Ab06448F244A1E0Ca0ba8", "tokenOracleAddress": "0x2636B223652d388721A0ED2861792DA9062D8C73", - "description": "USDC / ETH", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x000005ABaE3DEAdbe1FBD12105F950efbA9eaec4", - "feedSalt": "DEVX_PRICE_FEED_USDC_V0_27062023_uiaqdyv", "derivedFeed": true }, { @@ -16,10 +12,6 @@ "address": "0x7c81B296d84802ec2d5e63846912011f2Cd3C31C", "nativeOracleAddress": "0x57241A37733983F97C4Ab06448F244A1E0Ca0ba8", "tokenOracleAddress": "0x31856c9a2A73aAee6100Aed852650f75c5F539D0", - "description": "DAI / ETH", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x000000d2Da196474046c7a4D94Ab0E566B26d054", - "feedSalt": "DEVX_PRICE_FEED_DAI_V0_27062023_1m7JNWQ", "derivedFeed": true }, { @@ -27,21 +19,13 @@ "address": "0xD6a8c1eee4D4e4EF998b911B03d52bc301d9b332", "nativeOracleAddress": "0x57241A37733983F97C4Ab06448F244A1E0Ca0ba8", "tokenOracleAddress": "0x0A024aa48E09e151090637d2b68162b1Caf7BdbA", - "description": "UNI / ETH", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x0000095CcE092E83E5826cFeb0f03cFa74915b41", - "feedSalt": "DEVX_PRICE_FEED_UNI_V0_27062023_PBQ6vdq", "derivedFeed": true }, { "symbol": "LINK", "address": "0x6EB5be4c0D6da4ca582e9912F212c0DB1d96fC3d", - "nativeOracleAddress": "", - "tokenOracleAddress": "", - "description": "LINK / ETH", - "priceFeedFunction": "latestAnswer()", - "priceFeedAddress": "0x37410D317b96E1fED1814473E1CcD323D0eB4Eb1", - "feedSalt": "DEVX_PRICE_FEED_LINK_V0_27062023_JHIxs6o", + "nativeOracleAddress": "0x57241A37733983F97C4Ab06448F244A1E0Ca0ba8", + "tokenOracleAddress": "0x37410D317b96E1fED1814473E1CcD323D0eB4Eb1", "derivedFeed": false } ] diff --git a/scripts/configs/dev/token-config-polygon-mainnet.json b/scripts/configs/dev/token-config-polygon-mainnet.json index 4ba328a..8e481fc 100644 --- a/scripts/configs/dev/token-config-polygon-mainnet.json +++ b/scripts/configs/dev/token-config-polygon-mainnet.json @@ -5,10 +5,6 @@ "address": "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174", "nativeOracleAddress": "0xAB594600376Ec9fD91F8e885dADF0CE036862dE0", "tokenOracleAddress": "0xfE4A8cc5b5B2366C1B58Bea3858e81843581b2F7", - "description": "USDC / MATIC", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x000005ABaE3DEAdbe1FBD12105F950efbA9eaec4", - "feedSalt": "DEVX_PRICE_FEED_USDC_V0_27062023_uiaqdyv", "derivedFeed": true }, { @@ -16,10 +12,6 @@ "address": "0xc2132D05D31c914a87C6611C10748AEb04B58e8F", "nativeOracleAddress": "0xAB594600376Ec9fD91F8e885dADF0CE036862dE0", "tokenOracleAddress": "0x0A6513e40db6EB1b165753AD52E80663aeA50545", - "description": "USDT / MATIC", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x000001E2C2B39542c30A3fE57c4487030bC03adF", - "feedSalt": "DEVX_PRICE_FEED_USDT_V0_27062023_dIos1Nw", "derivedFeed": true }, { @@ -27,10 +19,6 @@ "address": "0x8f3Cf7ad23Cd3CaDbD9735AFf958023239c6A063", "nativeOracleAddress": "0xAB594600376Ec9fD91F8e885dADF0CE036862dE0", "tokenOracleAddress": "0x4746DeC9e833A82EC7C2C1356372CcF2cfcD2F3D", - "description": "DAI / MATIC", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x000000d2Da196474046c7a4D94Ab0E566B26d054", - "feedSalt": "DEVX_PRICE_FEED_DAI_V0_27062023_1m7JNWQ", "derivedFeed": true }, { @@ -38,10 +26,6 @@ "address": "0xBbba073C31bF03b8ACf7c28EF0738DeCF3695683", "nativeOracleAddress": "0xAB594600376Ec9fD91F8e885dADF0CE036862dE0", "tokenOracleAddress": "0x3D49406EDd4D52Fb7FFd25485f32E073b529C924", - "description": "SAND / MATIC", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x00000980455EFB131c1908eFa908c1eaF19db352", - "feedSalt": "DEVX_PRICE_FEED_SAND_V0_27062023_eHPqgeR", "derivedFeed": true } ] diff --git a/scripts/configs/dev/token-config-sepolia.json b/scripts/configs/dev/token-config-sepolia.json index f998f15..5069e60 100644 --- a/scripts/configs/dev/token-config-sepolia.json +++ b/scripts/configs/dev/token-config-sepolia.json @@ -5,10 +5,6 @@ "address": "0x9C73373C70F23920EA54F7883dCB1F85b162Df40", "nativeOracleAddress": "0x694AA1769357215DE4FAC081bf1f309aDC325306", "tokenOracleAddress": "0xA2F78ab2355fe2f984D808B5CeE7FD0A93D5270E", - "description": "USDC / ETH", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x000005ABaE3DEAdbe1FBD12105F950efbA9eaec4", - "feedSalt": "DEVX_PRICE_FEED_USDC_V0_27062023_uiaqdyv", "derivedFeed": true }, { @@ -16,10 +12,6 @@ "address": "0x5Bc7c8cFC6d54c055547Fcd8f6Ee4f2eDcda613e", "nativeOracleAddress": "0x694AA1769357215DE4FAC081bf1f309aDC325306", "tokenOracleAddress": "0x14866185B1962B63C3Ea9E03Bc1da838bab34C19", - "description": "DAI / ETH", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x000000d2da196474046c7a4d94ab0e566b26d054", - "feedSalt": "DEVX_PRICE_FEED_DAI_V0_27062023_1m7JNWQ", "derivedFeed": true } ] diff --git a/scripts/configs/prod/token-config-arbitrum-goerli.json b/scripts/configs/prod/token-config-arbitrum-goerli.json index 6bd43d2..f306d29 100644 --- a/scripts/configs/prod/token-config-arbitrum-goerli.json +++ b/scripts/configs/prod/token-config-arbitrum-goerli.json @@ -5,10 +5,6 @@ "address": "0x9Ff2A6b0cdc4aB06BBE231327edfE493f130A994", "nativeOracleAddress": "0x62CAe0FA2da220f43a51F86Db2EDb36DcA9A5A08", "tokenOracleAddress": "0x1692Bdd32F31b831caAc1b0c9fAF68613682813b", - "description": "USDC / ETH", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x000005ABaE3DEAdbe1FBD12105F950efbA9eaec4", - "feedSalt": "DEVX_PRICE_FEED_USDC_V0_27062023_uiaqdyv", "derivedFeed": true }, { @@ -16,21 +12,13 @@ "address": "0x466cd6F70015e11dc53e5757B4bcFeCcD7C31139", "nativeOracleAddress": "0x62CAe0FA2da220f43a51F86Db2EDb36DcA9A5A08", "tokenOracleAddress": "0x0a023a3423D9b27A0BE48c768CCF2dD7877fEf5E", - "description": "USDT / ETH", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x000001E2C2B39542c30A3fE57c4487030bC03adF", - "feedSalt": "DEVX_PRICE_FEED_USDT_V0_27062023_dIos1Nw", "derivedFeed": true }, { "symbol": "LINK", "address": "0x6bDB7FE59ec323b6A9bC96a988a971EEDA3958d9", - "nativeOracleAddress": "", - "tokenOracleAddress": "", - "description": "LINK / ETH", - "priceFeedFunction": "latestAnswer()", - "priceFeedAddress": "0x1AdDb2368414B3b4cF1BCe7A887d2De7Bfb6886f", - "feedSalt": "DEVX_PRICE_FEED_LINK_V0_27062023_JHIxs6o", + "nativeOracleAddress": "0x62CAe0FA2da220f43a51F86Db2EDb36DcA9A5A08", + "tokenOracleAddress": "0x1AdDb2368414B3b4cF1BCe7A887d2De7Bfb6886f", "derivedFeed": false } ] diff --git a/scripts/configs/prod/token-config-arbitrum-one.json b/scripts/configs/prod/token-config-arbitrum-one.json index 4d2891d..562ed4b 100644 --- a/scripts/configs/prod/token-config-arbitrum-one.json +++ b/scripts/configs/prod/token-config-arbitrum-one.json @@ -5,10 +5,6 @@ "address": "0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9", "nativeOracleAddress": "0x639Fe6ab55C921f74e7fac1ee960C0B6293ba612", "tokenOracleAddress": "0x3f3f5dF88dC9F13eac63DF89EC16ef6e7E25DdE7", - "description": "USDT / ETH", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x000001E2C2B39542c30A3fE57c4487030bC03adF", - "feedSalt": "DEVX_PRICE_FEED_USDT_V0_27062023_dIos1Nw", "derivedFeed": true }, { @@ -16,10 +12,6 @@ "address": "0x2f2a2543B76A4166549F7aaB2e75Bef0aefC5B0f", "nativeOracleAddress": "0x639Fe6ab55C921f74e7fac1ee960C0B6293ba612", "tokenOracleAddress": "0xd0C7101eACbB49F3deCcCc166d238410D6D46d57", - "description": "WBTC / ETH", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x00002D444779516f9D60368f3fa1E2b036BCCc7D", - "feedSalt": "DEVX_PRICE_FEED_WBTC_V0_27062023_z41FLvK", "derivedFeed": true }, { @@ -27,21 +19,13 @@ "address": "0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1", "nativeOracleAddress": "0x639Fe6ab55C921f74e7fac1ee960C0B6293ba612", "tokenOracleAddress": "0xc5C8E77B397E531B8EC06BFb0048328B30E9eCfB", - "description": "DAI / ETH", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x000000d2Da196474046c7a4D94Ab0E566B26d054", - "feedSalt": "DEVX_PRICE_FEED_DAI_V0_27062023_1m7JNWQ", "derivedFeed": true }, { "symbol": "wstETH", "address": "0x5979D7b546E38E414F7E9822514be443A4800529", - "nativeOracleAddress": "", - "tokenOracleAddress": "", - "description": "wstETH / ETH", - "priceFeedFunction": "latestAnswer()", - "priceFeedAddress": "0xb523AE262D20A936BC152e6023996e46FDC2A95D", - "feedSalt": "DEVX_PRICE_FEED_WSTETH_V0_27062023_mg8XpNM", + "nativeOracleAddress": "0x639Fe6ab55C921f74e7fac1ee960C0B6293ba612", + "tokenOracleAddress": "0xb523AE262D20A936BC152e6023996e46FDC2A95D", "derivedFeed": false }, { @@ -49,10 +33,6 @@ "address": "0x912CE59144191C1204E64559FE8253a0e49E6548", "nativeOracleAddress": "0x639Fe6ab55C921f74e7fac1ee960C0B6293ba612", "tokenOracleAddress": "0xb2A824043730FE05F3DA2efaFa1CBbe83fa548D6", - "description": "ARB / ETH", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x00003eCC9947e6E5128427290DEBBCAaE8199B3F", - "feedSalt": "DEVX_PRICE_FEED_ARB_V0_27062023_3wuHuct", "derivedFeed": true }, { @@ -60,10 +40,6 @@ "address": "0xaf88d065e77c8cC2239327C5EDb3A432268e5831", "nativeOracleAddress": "0x639Fe6ab55C921f74e7fac1ee960C0B6293ba612", "tokenOracleAddress": "0x50834F3163758fcC1Df9973b6e91f0F0F0434aD3", - "description": "USDC / ETH", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x000005ABaE3DEAdbe1FBD12105F950efbA9eaec4", - "feedSalt": "DEVX_PRICE_FEED_USDC_V0_27062023_uiaqdyv", "derivedFeed": true }, { @@ -71,10 +47,6 @@ "address": "0xfc5A1A6EB076a2C7aD06eD22C90d7E710E35ad0a", "nativeOracleAddress": "0x639Fe6ab55C921f74e7fac1ee960C0B6293ba612", "tokenOracleAddress": "0xDB98056FecFff59D032aB628337A4887110df3dB", - "description": "GMX / ETH", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x00001BC10BaB33fb8c0f93330e16153894F02a61", - "feedSalt": "DEVX_PRICE_FEED_GMX_V0_27062023_qKe9UwO", "derivedFeed": true }, { @@ -82,10 +54,6 @@ "address": "0xFa7F8980b0f1E64A2062791cc3b0871572f1F7f0", "nativeOracleAddress": "0x639Fe6ab55C921f74e7fac1ee960C0B6293ba612", "tokenOracleAddress": "0x9C917083fDb403ab5ADbEC26Ee294f6EcAda2720", - "description": "UNI / ETH", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x0000095CcE092E83E5826cFeb0f03cFa74915b41", - "feedSalt": "DEVX_PRICE_FEED_UNI_V0_27062023_PBQ6vdq", "derivedFeed": true }, { @@ -93,10 +61,6 @@ "address": "0x6C2C06790b3E3E3c38e12Ee22F8183b37a13EE55", "nativeOracleAddress": "0x639Fe6ab55C921f74e7fac1ee960C0B6293ba612", "tokenOracleAddress": "0xc373B9DB0707fD451Bc56bA5E9b029ba26629DF0", - "description": "DPX / ETH", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x00003e7f4BB63a6B24f2b45AFc698A20D7eFED65", - "feedSalt": "DEVX_PRICE_FEED_DPX_V0_27062023_5Y1OOrG", "derivedFeed": true }, { @@ -104,10 +68,6 @@ "address": "0x371c7ec6D8039ff7933a2AA28EB827Ffe1F52f07", "nativeOracleAddress": "0x639Fe6ab55C921f74e7fac1ee960C0B6293ba612", "tokenOracleAddress": "0x04180965a782E487d0632013ABa488A472243542", - "description": "JOE / ETH", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x000074df2B9Ad8a7Be4d07a85F278ca0017513d3", - "feedSalt": "DEVX_PRICE_FEED_JOE_V0_27062023_XxQWl65", "derivedFeed": true }, { @@ -115,10 +75,6 @@ "address": "0x040d1EdC9569d4Bab2D15287Dc5A4F10F56a56B8", "nativeOracleAddress": "0x639Fe6ab55C921f74e7fac1ee960C0B6293ba612", "tokenOracleAddress": "0xBE5eA816870D11239c543F84b71439511D70B94f", - "description": "BAL / ETH", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "", - "feedSalt": "DEVX_PRICE_FEED_BAL_V0_27062023_IzEMruz", "derivedFeed": true }, { @@ -126,10 +82,6 @@ "address": "0x354A6dA3fcde098F8389cad84b0182725c6C91dE", "nativeOracleAddress": "0x639Fe6ab55C921f74e7fac1ee960C0B6293ba612", "tokenOracleAddress": "0xe7C53FFd03Eb6ceF7d208bC4C13446c76d1E5884", - "description": "COMP / ETH", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "", - "feedSalt": "DEVX_PRICE_FEED_COMP_V0_27062023_54gIpet", "derivedFeed": true }, { @@ -137,21 +89,13 @@ "address": "0x11cDb42B0EB46D95f990BeDD4695A6e3fA034978", "nativeOracleAddress": "0x639Fe6ab55C921f74e7fac1ee960C0B6293ba612", "tokenOracleAddress": "0xaebDA2c976cfd1eE1977Eac079B4382acb849325", - "description": "CRV / ETH", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "", - "feedSalt": "DEVX_PRICE_FEED_CRV_V0_27062023_GrIWEtf", "derivedFeed": true }, { "symbol": "LINK", "address": "0xf97f4df75117a78c1A5a0DBb814Af92458539FB4", "nativeOracleAddress": "0x639Fe6ab55C921f74e7fac1ee960C0B6293ba612", - "tokenOracleAddress": "0x86E53CF1B870786351Da77A57575e79CB55812CB", - "description": "LINK / ETH", - "priceFeedFunction": "latestAnswer()", - "priceFeedAddress": "0xb7c8Fb1dB45007F98A68Da0588e1AA524C317f27", - "feedSalt": "DEVX_PRICE_FEED_LINK_V0_27062023_JHIxs6o", + "tokenOracleAddress": "0xb7c8Fb1dB45007F98A68Da0588e1AA524C317f27", "derivedFeed": false }, { @@ -159,10 +103,6 @@ "address": "0x2e9a6Df78E42a30712c10a9Dc4b1C8656f8F2879", "nativeOracleAddress": "0x639Fe6ab55C921f74e7fac1ee960C0B6293ba612", "tokenOracleAddress": "0xdE9f0894670c4EFcacF370426F10C3AD2Cdf147e", - "description": "MKR / ETH", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "", - "feedSalt": "DEVX_PRICE_FEED_MKR_V0_24072023_2Chh0Sh", "derivedFeed": true }, { @@ -170,10 +110,6 @@ "address": "0xd4d42F0b6DEF4CE0383636770eF773390d85c61A", "nativeOracleAddress": "0x639Fe6ab55C921f74e7fac1ee960C0B6293ba612", "tokenOracleAddress": "0xb2A8BA74cbca38508BA1632761b56C897060147C", - "description": "SUSHI / ETH", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "", - "feedSalt": "DEVX_PRICE_FEED_SUSHI_V0_27062023_dyZta4I", "derivedFeed": true }, { @@ -181,10 +117,6 @@ "address": "0x3E6648C5a70A150A88bCE65F4aD4d506Fe15d2AF", "nativeOracleAddress": "0x639Fe6ab55C921f74e7fac1ee960C0B6293ba612", "tokenOracleAddress": "0x383b3624478124697BEF675F07cA37570b73992f", - "description": "SPELL / ETH", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "", - "feedSalt": "DEVX_PRICE_FEED_SPELL_V0_24072023_v0CCYNa", "derivedFeed": true }, { @@ -192,10 +124,6 @@ "address": "0x17FC002b466eEc40DaE837Fc4bE5c67993ddBd6F", "nativeOracleAddress": "0x639Fe6ab55C921f74e7fac1ee960C0B6293ba612", "tokenOracleAddress": "0x0809E3d38d1B4214958faf06D8b1B1a2b73f2ab8", - "description": "FRAX / ETH", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "", - "feedSalt": "DEVX_PRICE_FEED_FRAX_V0_27062023_MmgkOOQ", "derivedFeed": true }, { @@ -203,10 +131,6 @@ "address": "0x3082CC23568eA640225c2467653dB90e9250AaA0", "nativeOracleAddress": "0x639Fe6ab55C921f74e7fac1ee960C0B6293ba612", "tokenOracleAddress": "0x20d0Fcab0ECFD078B036b6CAf1FaC69A6453b352", - "description": "RDNT / ETH", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "", - "feedSalt": "DEVX_PRICE_FEED_RDNT_V0_27062023_CE7LvWZ", "derivedFeed": true } ] diff --git a/scripts/configs/prod/token-config-avalanche-mainnet.json b/scripts/configs/prod/token-config-avalanche-mainnet.json index 0c224ad..d1556df 100644 --- a/scripts/configs/prod/token-config-avalanche-mainnet.json +++ b/scripts/configs/prod/token-config-avalanche-mainnet.json @@ -5,10 +5,6 @@ "address": "0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E", "nativeOracleAddress": "0x0A77230d17318075983913bC2145DB16C7366156", "tokenOracleAddress": "0xF096872672F44d6EBA71458D74fe67F9a77a23B9", - "description": "USDC / AVAX", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x000005ABaE3DEAdbe1FBD12105F950efbA9eaec4", - "feedSalt": "DEVX_PRICE_FEED_USDC_V0_27062023_uiaqdyv", "derivedFeed": true }, { @@ -16,10 +12,6 @@ "address": "0xc7198437980c041c805A1EDcbA50c1Ce5db95118", "nativeOracleAddress": "0x0A77230d17318075983913bC2145DB16C7366156", "tokenOracleAddress": "0xEBE676ee90Fe1112671f19b6B7459bC678B67e8a", - "description": "USDT / AVAX", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x000001E2C2B39542c30A3fE57c4487030bC03adF", - "feedSalt": "DEVX_PRICE_FEED_USDT_V0_27062023_dIos1Nw", "derivedFeed": true }, { @@ -27,10 +19,6 @@ "address": "0xd586E7F844cEa2F87f50152665BCbc2C279D8d70", "nativeOracleAddress": "0x0A77230d17318075983913bC2145DB16C7366156", "tokenOracleAddress": "0x51D7180edA2260cc4F6e4EebB82FEF5c3c2B8300", - "description": "DAI / AVAX", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x000000d2Da196474046c7a4D94Ab0E566B26d054", - "feedSalt": "DEVX_PRICE_FEED_DAI_V0_27062023_1m7JNWQ", "derivedFeed": true }, { @@ -38,10 +26,6 @@ "address": "0x49D5c2BdFfac6CE2BFdB6640F4F80f226bc10bAB", "nativeOracleAddress": "0x0A77230d17318075983913bC2145DB16C7366156", "tokenOracleAddress": "0x976B3D034E162d8bD72D6b9C989d545b839003b0", - "description": "WETH / AVAX", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x00008cC9D5BF9F97AE2879163011707812561b42", - "feedSalt": "DEVX_PRICE_FEED_ETH_V0_27062023_jZ9Dvxh", "derivedFeed": true }, { @@ -49,10 +33,6 @@ "address": "0x50b7545627a5162F82A992c33b87aDc75187B218", "nativeOracleAddress": "0x0A77230d17318075983913bC2145DB16C7366156", "tokenOracleAddress": "0x86442E3a98558357d46E6182F4b262f76c4fa26F", - "description": "WBTC / AVAX", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x00002D444779516f9D60368f3fa1E2b036BCCc7D", - "feedSalt": "DEVX_PRICE_FEED_WBTC_V0_27062023_z41FLvK", "derivedFeed": true }, { @@ -60,10 +40,6 @@ "address": "0x19860CCB0A68fd4213aB9D8266F7bBf05A8dDe98", "nativeOracleAddress": "0x0A77230d17318075983913bC2145DB16C7366156", "tokenOracleAddress": "0x827f8a0dC5c943F7524Dda178E2e7F275AAd743f", - "description": "BUSD / AVAX", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x000020c39775542112E3DB0DbAD0d47A44bEB49A", - "feedSalt": "DEVX_PRICE_FEED_BUSD_V0_27062023_J8nJR8O", "derivedFeed": true }, { @@ -71,10 +47,6 @@ "address": "0x1C20E891Bab6b1727d14Da358FAe2984Ed9B59EB", "nativeOracleAddress": "0x0A77230d17318075983913bC2145DB16C7366156", "tokenOracleAddress": "0x9Cf3Ef104A973b351B2c032AA6793c3A6F76b448", - "description": "TUSD / AVAX", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x000064b138eDB97Ac8a3F4564E14d9a331288a6B", - "feedSalt": "DEVX_PRICE_FEED_TUSD_V0_27062023_QHVx0oQ", "derivedFeed": true }, { @@ -82,10 +54,6 @@ "address": "0x63a72806098Bd3D9520cC43356dD78afe5D386D9", "nativeOracleAddress": "0x0A77230d17318075983913bC2145DB16C7366156", "tokenOracleAddress": "0x3CA13391E9fb38a75330fb28f8cc2eB3D9ceceED", - "description": "AAVE / AVAX", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x0000AF22A276F86B405835c18863e1C2A679D9e3", - "feedSalt": "DEVX_PRICE_FEED_AAVE_V0_28062023_HsugnpY", "derivedFeed": true }, { @@ -93,10 +61,6 @@ "address": "0xd1c3f94DE7e5B45fa4eDBBA472491a9f4B166FC4", "nativeOracleAddress": "0x0A77230d17318075983913bC2145DB16C7366156", "tokenOracleAddress": "0x4Cf57DC9028187b9DAaF773c8ecA941036989238", - "description": "XAVA / AVAX", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x0000CcE0a6DD4eec1137D9395D676272D5D1135e", - "feedSalt": "DEVX_PRICE_FEED_XAVA_V0_24072023_cGSh9uO", "derivedFeed": true }, { @@ -104,10 +68,6 @@ "address": "0x8729438EB15e2C8B576fCc6AeCdA6A148776C0F5", "nativeOracleAddress": "0x0A77230d17318075983913bC2145DB16C7366156", "tokenOracleAddress": "0x36E039e6391A5E7A7267650979fdf613f659be5D", - "description": "QI / AVAX", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x00006c81322356756CEE17B157a743a794b33426", - "feedSalt": "DEVX_PRICE_FEED_QI_V0_24072023_GQDedut", "derivedFeed": true }, { @@ -115,10 +75,6 @@ "address": "0x6e84a6216eA6dACC71eE8E6b0a5B7322EEbC0fDd", "nativeOracleAddress": "0x0A77230d17318075983913bC2145DB16C7366156", "tokenOracleAddress": "0x02D35d3a8aC3e1626d3eE09A78Dd87286F5E8e3a", - "description": "JOE / AVAX", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x000074df2B9Ad8a7Be4d07a85F278ca0017513d3", - "feedSalt": "DEVX_PRICE_FEED_JOE_V0_27062023_XxQWl65", "derivedFeed": true }, { @@ -126,10 +82,6 @@ "address": "0xCE1bFFBD5374Dac86a2893119683F4911a2F7814", "nativeOracleAddress": "0x0A77230d17318075983913bC2145DB16C7366156", "tokenOracleAddress": "0x4F3ddF9378a4865cf4f28BE51E10AECb83B7daeE", - "description": "SPELL / AVAX", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x000015e3b3B1023570DAE19c620073EB2acd1513", - "feedSalt": "DEVX_PRICE_FEED_SPELL_V0_24072023_v0CCYNa", "derivedFeed": true }, { @@ -137,10 +89,6 @@ "address": "0x214DB107654fF987AD859F34125307783fC8e387", "nativeOracleAddress": "0x0A77230d17318075983913bC2145DB16C7366156", "tokenOracleAddress": "0x12Af94c3716bbf339Aa26BfD927DDdE63B27D50C", - "description": "FXS / AVAX", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x00002f9671412725CEB1A283f72CBb44ba3D1893", - "feedSalt": "DEVX_PRICE_FEED_FXS_V0_24072023_WCKMhk1", "derivedFeed": true }, { @@ -148,21 +96,13 @@ "address": "0x2147EFFF675e4A4eE1C2f918d181cDBd7a8E208f", "nativeOracleAddress": "0x0A77230d17318075983913bC2145DB16C7366156", "tokenOracleAddress": "0x7B0ca9A6D03FE0467A31Ca850f5bcA51e027B3aF", - "description": "ALPHA / AVAX", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x0000343Be957FC284F4df64d38cBaa7e065DD984", - "feedSalt": "DEVX_PRICE_FEED_ALPHA_V0_27062023_MtEbJge", "derivedFeed": true }, { "symbol": "LINK", "address": "0x5947BB275c521040051D82396192181b413227A3", "nativeOracleAddress": "0x0A77230d17318075983913bC2145DB16C7366156", - "tokenOracleAddress": "0x49ccd9ca821EfEab2b98c60dC60F518E765EDe9a", - "description": "LINK / AVAX", - "priceFeedFunction": "latestAnswer()", - "priceFeedAddress": "0x1b8a25F73c9420dD507406C3A3816A276b62f56a", - "feedSalt": "DEVX_PRICE_FEED_LINK_V0_27062023_JHIxs6o", + "tokenOracleAddress": "0x1b8a25F73c9420dD507406C3A3816A276b62f56a", "derivedFeed": false }, { @@ -170,10 +110,6 @@ "address": "0x37B608519F91f70F2EeB0e5Ed9AF4061722e4F76", "nativeOracleAddress": "0x0A77230d17318075983913bC2145DB16C7366156", "tokenOracleAddress": "0x449A373A090d8A1e5F74c63Ef831Ceff39E94563", - "description": "SUSHI / AVAX", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x0000552E10e879F403dD5F041742E6356d031825", - "feedSalt": "DEVX_PRICE_FEED_SUSHI_V0_27062023_dyZta4I", "derivedFeed": true }, { @@ -181,10 +117,6 @@ "address": "0x130966628846BFd36ff31a822705796e8cb8C18D", "nativeOracleAddress": "0x0A77230d17318075983913bC2145DB16C7366156", "tokenOracleAddress": "0x54EdAB30a7134A16a54218AE64C73e1DAf48a8Fb", - "description": "MIM / AVAX", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x000020a943CeCe5043E1309663bc5Bfa822DE646", - "feedSalt": "DEVX_PRICE_FEED_MIM_V0_27062023_faxTfxe", "derivedFeed": true }, { @@ -192,10 +124,6 @@ "address": "0xD24C2Ad096400B6FBcd2ad8B24E7acBc21A1da64", "nativeOracleAddress": "0x0A77230d17318075983913bC2145DB16C7366156", "tokenOracleAddress": "0xbBa56eF1565354217a3353a466edB82E8F25b08e", - "description": "FRAX / AVAX", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x00005f9f7f943e3db079D3B9A7A86aa80b70898C", - "feedSalt": "DEVX_PRICE_FEED_FRAX_V0_27062023_MmgkOOQ", "derivedFeed": true }, { @@ -203,10 +131,6 @@ "address": "0x62edc0692BD897D2295872a9FFCac5425011c661", "nativeOracleAddress": "0x0A77230d17318075983913bC2145DB16C7366156", "tokenOracleAddress": "0x3F968A21647d7ca81Fb8A5b69c0A452701d5DCe8", - "description": "GMX / AVAX", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x00001BC10BaB33fb8c0f93330e16153894F02a61", - "feedSalt": "DEVX_PRICE_FEED_GMX_V0_27062023_qKe9UwO", "derivedFeed": true } ] diff --git a/scripts/configs/prod/token-config-avalanche-testnet.json b/scripts/configs/prod/token-config-avalanche-testnet.json index 243ff84..9a647dc 100644 --- a/scripts/configs/prod/token-config-avalanche-testnet.json +++ b/scripts/configs/prod/token-config-avalanche-testnet.json @@ -5,10 +5,6 @@ "address": "0xA7b3002ec739077057689A389460a0E7c0367369", "nativeOracleAddress": "0x5498BB86BC934c8D34FDA08E81D444153d0D06aD", "tokenOracleAddress": "0x7898AcCC83587C3C55116c5230C17a6Cd9C71bad", - "description": "USDT / AVAX", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x000001E2C2B39542c30A3fE57c4487030bC03adF", - "feedSalt": "DEVX_PRICE_FEED_USDT_V0_27062023_dIos1Nw", "derivedFeed": true } ] diff --git a/scripts/configs/prod/token-config-base-goerli.json b/scripts/configs/prod/token-config-base-goerli.json index 2d12a99..13e03b8 100644 --- a/scripts/configs/prod/token-config-base-goerli.json +++ b/scripts/configs/prod/token-config-base-goerli.json @@ -5,10 +5,6 @@ "address": "0xD6a8c1eee4D4e4EF998b911B03d52bc301d9b332", "nativeOracleAddress": "0xcD2A119bD1F7DF95d706DE6F2057fDD45A0503E2", "tokenOracleAddress": "0xb85765935B4d9Ab6f841c9a00690Da5F34368bc0", - "description": "USDC / ETH", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x000005ABaE3DEAdbe1FBD12105F950efbA9eaec4", - "feedSalt": "DEVX_PRICE_FEED_USDC_V0_27062023_uiaqdyv", "derivedFeed": true }, { @@ -16,10 +12,6 @@ "address": "0xe01435b1767aED7c25C943faCbdB582b6278650f", "nativeOracleAddress": "0xcD2A119bD1F7DF95d706DE6F2057fDD45A0503E2", "tokenOracleAddress": "0xd5973EB46D6fE54E82C5337dD9536B35D080912C", - "description": "USDT / ETH", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x000001E2C2B39542c30A3fE57c4487030bC03adF", - "feedSalt": "DEVX_PRICE_FEED_USDT_V0_27062023_dIos1Nw", "derivedFeed": true }, { @@ -27,10 +19,6 @@ "address": "0x7c81B296d84802ec2d5e63846912011f2Cd3C31C", "nativeOracleAddress": "0xcD2A119bD1F7DF95d706DE6F2057fDD45A0503E2", "tokenOracleAddress": "0x440bD1535a02243d72E0fEED45B137efcC98bF7e", - "description": "DAI / ETH", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x000000d2Da196474046c7a4D94Ab0E566B26d054", - "feedSalt": "DEVX_PRICE_FEED_DAI_V0_27062023_1m7JNWQ", "derivedFeed": true } ] diff --git a/scripts/configs/prod/token-config-bnb-mainnet.json b/scripts/configs/prod/token-config-bnb-mainnet.json index f223e63..90c2939 100644 --- a/scripts/configs/prod/token-config-bnb-mainnet.json +++ b/scripts/configs/prod/token-config-bnb-mainnet.json @@ -3,67 +3,43 @@ { "symbol": "USDC", "address": "0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d", - "nativeOracleAddress": "", - "tokenOracleAddress": "", - "description": "USDC / BNB", - "priceFeedFunction": "latestAnswer()", - "priceFeedAddress": "0x45f86CA2A8BC9EBD757225B19a1A0D7051bE46Db", - "feedSalt": "DEVX_PRICE_FEED_USDC_V0_27062023_uiaqdyv", + "nativeOracleAddress": "0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE", + "tokenOracleAddress": "0x45f86CA2A8BC9EBD757225B19a1A0D7051bE46Db", "derivedFeed": false }, { "symbol": "USDT", "address": "0x55d398326f99059fF775485246999027B3197955", - "nativeOracleAddress": "", - "tokenOracleAddress": "", - "description": "USDT / BNB", - "priceFeedFunction": "latestAnswer()", - "priceFeedAddress": "0xD5c40f5144848Bd4EF08a9605d860e727b991513", - "feedSalt": "DEVX_PRICE_FEED_USDT_V0_27062023_dIos1Nw", + "nativeOracleAddress": "0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE", + "tokenOracleAddress": "0xD5c40f5144848Bd4EF08a9605d860e727b991513", "derivedFeed": false }, { "symbol": "DAI", "address": "0x1AF3F329e8BE154074D8769D1FFa4eE058B1DBc3", - "nativeOracleAddress": "", - "tokenOracleAddress": "", - "description": "DAI / BNB", - "priceFeedFunction": "latestAnswer()", - "priceFeedAddress": "0x8EC213E7191488C7873cEC6daC8e97cdbAdb7B35", - "feedSalt": "DEVX_PRICE_FEED_DAI_V0_27062023_1m7JNWQ", + "nativeOracleAddress": "0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE", + "tokenOracleAddress": "0x8EC213E7191488C7873cEC6daC8e97cdbAdb7B35", "derivedFeed": false }, { "symbol": "TWT", "address": "0x4b0f1812e5df2a09796481ff14017e6005508003", - "nativeOracleAddress": "", - "tokenOracleAddress": "", - "description": "TWT / BNB", - "priceFeedFunction": "latestAnswer()", - "priceFeedAddress": "0x7E728dFA6bCa9023d9aBeE759fDF56BEAb8aC7aD", - "feedSalt": "DEVX_PRICE_FEED_TWT_V0_27062023_92Xklvq", + "nativeOracleAddress": "0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE", + "tokenOracleAddress": "0x7E728dFA6bCa9023d9aBeE759fDF56BEAb8aC7aD", "derivedFeed": false }, { "symbol": "CAKE", "address": "0x0E09FaBB73Bd3Ade0a17ECC321fD13a19e81cE82", - "nativeOracleAddress": "", - "tokenOracleAddress": "", - "description": "CAKE / BNB", - "priceFeedFunction": "latestAnswer()", - "priceFeedAddress": "0xcB23da9EA243f53194CBc2380A6d4d9bC046161f", - "feedSalt": "DEVX_PRICE_FEED_CAKE_V0_27062023_1BKpzde", + "nativeOracleAddress": "0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE", + "tokenOracleAddress": "0xcB23da9EA243f53194CBc2380A6d4d9bC046161f", "derivedFeed": false }, { "symbol": "LINK", "address": "0xF8A0BF9cF54Bb92F17374d9e9A321E6a111a51bD", - "nativeOracleAddress": "", - "tokenOracleAddress": "", - "description": "LINK / BNB", - "priceFeedFunction": "latestAnswer()", - "priceFeedAddress": "0xB38722F6A608646a538E882Ee9972D15c86Fc597", - "feedSalt": "DEVX_PRICE_FEED_LINK_V0_27062023_JHIxs6o", + "nativeOracleAddress": "0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE", + "tokenOracleAddress": "0xB38722F6A608646a538E882Ee9972D15c86Fc597", "derivedFeed": false }, { @@ -71,10 +47,6 @@ "address": "0x111111111117dC0aa78b770fA6A738034120C302", "nativeOracleAddress": "0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE", "tokenOracleAddress": "0x1B329402Cb1825C6F30A0d92aB9E2862BE47333f", - "description": "1INCH / BNB", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x00000C451fA0b0a79a36c82820F061683E26714c", - "feedSalt": "DEVX_PRICE_FEED_1INCH_V0_27062023_XhXA3sd", "derivedFeed": true }, { @@ -82,43 +54,27 @@ "address": "0xfb6115445Bff7b52FeB98650C87f44907E58f802", "nativeOracleAddress": "0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE", "tokenOracleAddress": "0xA8357BF572460fC40f4B0aCacbB2a6A61c89f475", - "description": "AAVE / BNB", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x0000AF22A276F86B405835c18863e1C2A679D9e3", - "feedSalt": "DEVX_PRICE_FEED_AAVE_V0_28062023_HsugnpY", "derivedFeed": true }, { "symbol": "BUSD", "address": "0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56", - "nativeOracleAddress": "", - "tokenOracleAddress": "", - "description": "BUSD / BNB", - "priceFeedFunction": "latestAnswer()", - "priceFeedAddress": "0x87Ea38c9F24264Ec1Fff41B04ec94a97Caf99941", - "feedSalt": "DEVX_PRICE_FEED_BUSD_V0_27062023_J8nJR8O", + "nativeOracleAddress": "0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE", + "tokenOracleAddress": "0x87Ea38c9F24264Ec1Fff41B04ec94a97Caf99941", "derivedFeed": false }, { "symbol": "ETH", "address": "0x2170Ed0880ac9A755fd29B2688956BD959F933F8", - "nativeOracleAddress": "", - "tokenOracleAddress": "", - "description": "ETH / BNB", - "priceFeedFunction": "latestAnswer()", - "priceFeedAddress": "0x63D407F32Aa72E63C7209ce1c2F5dA40b3AaE726", - "feedSalt": "DEVX_PRICE_FEED_ETH_V0_27062023_jZ9Dvxh", + "nativeOracleAddress": "0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE", + "tokenOracleAddress": "0x63D407F32Aa72E63C7209ce1c2F5dA40b3AaE726", "derivedFeed": false }, { "symbol": "XRP", "address": "0x1D2F0da169ceB9fC7B3144628dB156f3F6c60dBE", - "nativeOracleAddress": "", - "tokenOracleAddress": "", - "description": "XRP / BNB", - "priceFeedFunction": "latestAnswer()", - "priceFeedAddress": "0x798A65D349B2B5E6645695912880b54dfFd79074", - "feedSalt": "DEVX_PRICE_FEED_XRP_V0_27062023_tjCRahl", + "nativeOracleAddress": "0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE", + "tokenOracleAddress": "0x798A65D349B2B5E6645695912880b54dfFd79074", "derivedFeed": false }, { @@ -126,21 +82,13 @@ "address": "0x14016E85a25aeb13065688cAFB43044C2ef86784", "nativeOracleAddress": "0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE", "tokenOracleAddress": "0xa3334A9762090E827413A7495AfeCE76F41dFc06", - "description": "TUSD / BNB", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x000064b138eDB97Ac8a3F4564E14d9a331288a6B", - "feedSalt": "DEVX_PRICE_FEED_TUSD_V0_27062023_QHVx0oQ", "derivedFeed": true }, { "symbol": "UNI", "address": "0xBf5140A22578168FD562DCcF235E5D43A02ce9B1", - "nativeOracleAddress": "", - "tokenOracleAddress": "", - "description": "UNI / BNB", - "priceFeedFunction": "latestAnswer()", - "priceFeedAddress": "0x25298F020c3CA1392da76Eb7Ac844813b218ccf7", - "feedSalt": "DEVX_PRICE_FEED_UNI_V0_27062023_PBQ6vdq", + "nativeOracleAddress": "0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE", + "tokenOracleAddress": "0x25298F020c3CA1392da76Eb7Ac844813b218ccf7", "derivedFeed": false }, { @@ -148,10 +96,6 @@ "address": "0xCC42724C6683B7E57334c4E856f4c9965ED682bD", "nativeOracleAddress": "0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE", "tokenOracleAddress": "0x7CA57b0cA6367191c94C8914d7Df09A57655905f", - "description": "MATIC / BNB", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x0000131e033973d4042167F814974D398C954AE4", - "feedSalt": "DEVX_PRICE_FEED_MATIC_V0_27062023_dUA11H1", "derivedFeed": true }, { @@ -159,10 +103,6 @@ "address": "0xf7DE7E8A6bd59ED41a4b5fe50278b3B7f31384dF", "nativeOracleAddress": "0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE", "tokenOracleAddress": "0x20123C6ebd45c6496102BeEA86e1a6616Ca547c6", - "description": "RDNT / BNB", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x000008fA6c7A8dFDD2eee14360704552e7FF1106", - "feedSalt": "DEVX_PRICE_FEED_RDNT_V0_27062023_CE7LvWZ", "derivedFeed": true }, { @@ -171,10 +111,6 @@ "address": "0x7Ddc52c4De30e94Be3A6A0A2b259b2850f421989", "nativeOracleAddress": "0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE", "tokenOracleAddress": "0x8b0D36ae4CF8e277773A7ba5F35c09Edb144241b", - "description": "GMT / BNB", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x000000EB1BD01130B0429299C59Bcc51280EcFa3", - "feedSalt": "DEVX_PRICE_FEED_GMT(GOMINING)_V0_27062023_9BlrrVe", "derivedFeed": true }, { @@ -182,10 +118,6 @@ "address": "0x9C65AB58d8d978DB963e63f2bfB7121627e3a739", "nativeOracleAddress": "0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE", "tokenOracleAddress": "0x9165366bf450a6906D25549f0E0f8E6586Fc93E2", - "description": "MDX / BNB", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x000055CeB7e51700701D185A2fC5C85CD0A0B4c0", - "feedSalt": "DEVX_PRICE_FEED_MDX_V0_27062023_4cZxM3m", "derivedFeed": true }, { @@ -193,10 +125,6 @@ "address": "0xAD29AbB318791D579433D831ed122aFeAf29dcfe", "nativeOracleAddress": "0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE", "tokenOracleAddress": "0xe2A47e87C0f4134c8D06A41975F6860468b2F925", - "description": "FTM / BNB", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x000014e7939aD646144Ea6b96267bb1BD7cd7067", - "feedSalt": "DEVX_PRICE_FEED_FTM_V0_27062023_e8NvX2b", "derivedFeed": true }, { @@ -204,10 +132,6 @@ "address": "0xaEC945e04baF28b135Fa7c640f624f8D90F1C3a6", "nativeOracleAddress": "0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE", "tokenOracleAddress": "0x889158E39628C0397DC54B84F6b1cbe0AaEb7FFc", - "description": "C98 / BNB", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x0000ECddfaFFfcc20a2eF11694513A2C63564c45", - "feedSalt": "DEVX_PRICE_FEED_C98_V0_27062023_5SwtjcK", "derivedFeed": true }, { @@ -215,10 +139,6 @@ "address": "0x715D400F88C167884bbCc41C5FeA407ed4D2f8A0", "nativeOracleAddress": "0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE", "tokenOracleAddress": "0x7B49524ee5740c99435f52d731dFC94082fE61Ab", - "description": "AXS / BNB", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x0000129361C7DA0Ade90F2559d8dbFcE86f73Cf0", - "feedSalt": "DEVX_PRICE_FEED_AXS_V0_27062023_TcgSX8U", "derivedFeed": true }, { @@ -226,10 +146,6 @@ "address": "0xd17479997F34dd9156Deef8F95A52D81D265be9c", "nativeOracleAddress": "0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE", "tokenOracleAddress": "0x51c78c299C42b058Bf11d47FbB74aC437C6a0c8C", - "description": "USDD / BNB", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x000062e3727903c86308E8c008f2C4147E1bF83b", - "feedSalt": "DEVX_PRICE_FEED_USDD_V0_27062023_PvMWVhA", "derivedFeed": true }, { @@ -238,10 +154,6 @@ "address": "0x3019BF2a2eF8040C242C9a4c5c4BD4C81678b2A1", "nativeOracleAddress": "0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE", "tokenOracleAddress": "0x8b0D36ae4CF8e277773A7ba5F35c09Edb144241b", - "description": "GMT / BNB", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x0000a179410B6AE396Fbf9328179cc51e8eb811E", - "feedSalt": "DEVX_PRICE_FEED_GMT(GREENMETA)_V0_27062023_OP631xI", "derivedFeed": true }, { @@ -249,10 +161,6 @@ "address": "0x90C97F71E18723b0Cf0dfa30ee176Ab653E89F40", "nativeOracleAddress": "0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE", "tokenOracleAddress": "0x13A9c98b07F098c5319f4FF786eB16E22DC738e1", - "description": "FRAX / BNB", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x00005f9f7f943e3db079D3B9A7A86aa80b70898C", - "feedSalt": "DEVX_PRICE_FEED_FRAX_V0_27062023_MmgkOOQ", "derivedFeed": true }, { @@ -260,10 +168,6 @@ "address": "0x965F527D9159dCe6288a2219DB51fc6Eef120dD1", "nativeOracleAddress": "0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE", "tokenOracleAddress": "0x08E70777b982a58D23D05E3D7714f44837c06A21", - "description": "BSW / BNB", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x0000f453C85aB3c839c49Ef729f36081AC8D7ac2", - "feedSalt": "DEVX_PRICE_FEED_BSW_V0_27062023_Kv26Fjv", "derivedFeed": true }, { @@ -271,10 +175,6 @@ "address": "0xfe56d5892BDffC7BF58f2E84BE1b2C32D21C308b", "nativeOracleAddress": "0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE", "tokenOracleAddress": "0xF2f8273F6b9Fc22C90891DC802cAf60eeF805cDF", - "description": "KNC / BNB", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x0000DB3bfA1c8c27e4b99e5b023bFD30F210c185", - "feedSalt": "DEVX_PRICE_FEED_KNC_V0_27062023_G3ECzSl", "derivedFeed": true }, { @@ -282,10 +182,6 @@ "address": "0x4691937a7508860F876c9c0a2a617E7d9E945D4B", "nativeOracleAddress": "0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE", "tokenOracleAddress": "0x02Bfe714e78E2Ad1bb1C2beE93eC8dc5423B66d4", - "description": "WOO / BNB", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x0000DE1c603c7272383E8a7Ed24a5B9941da36DF", - "feedSalt": "DEVX_PRICE_FEED_WOO_V0_27062023_zjZa7el", "derivedFeed": true }, { @@ -293,10 +189,6 @@ "address": "0x16939ef78684453bfDFb47825F8a5F714f12623a", "nativeOracleAddress": "0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE", "tokenOracleAddress": "0x9A18137ADCF7b05f033ad26968Ed5a9cf0Bf8E6b", - "description": "XTZ / BNB", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x00004443efb75BdEcDaaaD6293E10E3e9cDBD0A7", - "feedSalt": "DEVX_PRICE_FEED_XTZ_V0_27062023_EqsLbfu", "derivedFeed": true }, { @@ -304,10 +196,6 @@ "address": "0xb86AbCb37C3A4B64f74f59301AFF131a1BEcC787", "nativeOracleAddress": "0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE", "tokenOracleAddress": "0x3e3aA4FC329529C8Ab921c810850626021dbA7e6", - "description": "ZIL / BNB", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "", - "feedSalt": "DEVX_PRICE_FEED_ZIL_V0_27062023_zucJh8i", "derivedFeed": true }, { @@ -315,10 +203,6 @@ "address": "0x3203c9E46cA618C8C1cE5dC67e7e9D75f5da2377", "nativeOracleAddress": "0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE", "tokenOracleAddress": "0x1AAE42AA46483370Be23274Abb29Bcc40f808a4c", - "description": "MBOX / BNB", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x0000d4B5153b5cc737d5C8a53A29e70257E7De5E", - "feedSalt": "DEVX_PRICE_FEED_MBOX_V0_27062023_gtGW8Jd", "derivedFeed": true }, { @@ -326,10 +210,6 @@ "address": "0x8F0528cE5eF7B51152A59745bEfDD91D97091d2F", "nativeOracleAddress": "0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE", "tokenOracleAddress": "0xe0073b60833249ffd1bb2af809112c2fbf221DF6", - "description": "ALPACA / BNB", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x0000778014B53A0396A3CE80237Afcf89c4a603F", - "feedSalt": "DEVX_PRICE_FEED_ALPACA_V0_27062023_HmWTvr1", "derivedFeed": true }, { @@ -337,10 +217,6 @@ "address": "0xCa3F508B8e4Dd382eE878A314789373D80A5190A", "nativeOracleAddress": "0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE", "tokenOracleAddress": "0xaB827b69daCd586A37E80A7d552a4395d576e645", - "description": "BIFI / BNB", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x0000dd2600f5fC02fEF2Cd97717364144E6c0298", - "feedSalt": "DEVX_PRICE_FEED_BIFI_V0_27062023_j5hVBjs", "derivedFeed": true }, { @@ -348,10 +224,6 @@ "address": "0x762539b45A1dCcE3D36d080F74d1AED37844b878", "nativeOracleAddress": "0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE", "tokenOracleAddress": "0x38393201952f2764E04B290af9df427217D56B41", - "description": "LINA / BNB", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x00009D8f80aC35d0242251b1475F8e6d056Ca56f", - "feedSalt": "DEVX_PRICE_FEED_LINA_V0_27062023_tsAKhlg", "derivedFeed": true }, { @@ -359,10 +231,6 @@ "address": "0x67ee3Cb086F8a16f34beE3ca72FAD36F7Db929e2", "nativeOracleAddress": "0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE", "tokenOracleAddress": "0x87701B15C08687341c2a847ca44eCfBc8d7873E1", - "description": "DODO / BNB", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x00000dFD5Ba9C0Bd10d739Cc6c315Cbd0Bf22d03", - "feedSalt": "DEVX_PRICE_FEED_DODO_V0_27062023_ZYqxFW0", "derivedFeed": true }, { @@ -370,10 +238,6 @@ "address": "0xFd7B3A77848f1C2D67E05E54d78d174a0C850335", "nativeOracleAddress": "0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE", "tokenOracleAddress": "0x887f177CBED2cf555a64e7bF125E1825EB69dB82", - "description": "ONT / BNB", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x0000331F158B3691C9D7E5B623F8e59Ee6d4dFC4", - "feedSalt": "DEVX_PRICE_FEED_ONT_V0_27062023_cvuyqC7", "derivedFeed": true }, { @@ -381,10 +245,6 @@ "address": "0x1Fa4a73a3F0133f0025378af00236f3aBDEE5D63", "nativeOracleAddress": "0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE", "tokenOracleAddress": "0x0Fe4D87883005fCAFaF56B81d09473D9A29dCDC3", - "description": "NEAR / BNB", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x0000e8fbB89b5A593183D52FbE0cAcc4fdE43D06", - "feedSalt": "DEVX_PRICE_FEED_NEAR_V0_27062023_GfOHuQa", "derivedFeed": true }, { @@ -392,10 +252,6 @@ "address": "0x250632378E573c6Be1AC2f97Fcdf00515d0Aa91B", "nativeOracleAddress": "0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE", "tokenOracleAddress": "0x2A3796273d47c4eD363b361D3AEFb7F7E2A13782", - "description": "BETH / BNB", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x00001844fe863119D4F5a36Fb9b13477Cc7fB482", - "feedSalt": "DEVX_PRICE_FEED_BETH_V0_27062023_HIdX0nG", "derivedFeed": true }, { @@ -403,10 +259,6 @@ "address": "0x0Eb3a705fc54725037CC9e008bDede697f62F335", "nativeOracleAddress": "0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE", "tokenOracleAddress": "0xb056B7C804297279A9a673289264c17E6Dc6055d", - "description": "ATOM / BNB", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x0000B3b5E8722d41F23b483747Ad69d553ad4e41", - "feedSalt": "DEVX_PRICE_FEED_ATOM_V0_27062023_uA0jFGU", "derivedFeed": true }, { @@ -414,10 +266,6 @@ "address": "0x0D8Ce2A99Bb6e3B7Db580eD848240e4a0F9aE153", "nativeOracleAddress": "0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE", "tokenOracleAddress": "0xE5dbFD9003bFf9dF5feB2f4F445Ca00fb121fb83", - "description": "FIL / BNB", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x0000d2911880FCa9C055c858c8EE36A4C00df11A", - "feedSalt": "DEVX_PRICE_FEED_FIL_V0_27062023_4v9KFOn", "derivedFeed": true }, { @@ -425,10 +273,6 @@ "address": "0x8fF795a6F4D97E7887C79beA79aba5cc76444aDf", "nativeOracleAddress": "0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE", "tokenOracleAddress": "0x43d80f616DAf0b0B42a928EeD32147dC59027D41", - "description": "BCH / BNB", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x00000756352A0224A157c8867df7aF41592b66F0", - "feedSalt": "DEVX_PRICE_FEED_BCH_V0_27062023_kMHbG6e", "derivedFeed": true }, { @@ -436,10 +280,6 @@ "address": "0xb59490aB09A0f526Cc7305822aC65f2Ab12f9723", "nativeOracleAddress": "0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE", "tokenOracleAddress": "0x83766bA8d964fEAeD3819b145a69c947Df9Cb035", - "description": "LIT / BNB", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x00004244169F87a2b6Fa95FB60481F7D02D9927e", - "feedSalt": "DEVX_PRICE_FEED_LIT_V0_27062023_QzFcBwH", "derivedFeed": true }, { @@ -447,10 +287,6 @@ "address": "0x4338665CBB7B2485A8855A139b75D5e34AB0DB94", "nativeOracleAddress": "0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE", "tokenOracleAddress": "0x74E72F37A8c415c8f1a98Ed42E78Ff997435791D", - "description": "LTC / BNB", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x0000d03686E0113616906f8018CeF0ebff588eDF", - "feedSalt": "DEVX_PRICE_FEED_LTC_V0_27062023_zxuYpzV", "derivedFeed": true }, { @@ -458,10 +294,6 @@ "address": "0x56b6fB708fC5732DEC1Afc8D8556423A2EDcCbD6", "nativeOracleAddress": "0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE", "tokenOracleAddress": "0xd5508c8Ffdb8F15cE336e629fD4ca9AdB48f50F0", - "description": "EOS / BNB", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x0000a730301a18C1F2A8FD7656f8f368135EFF17", - "feedSalt": "DEVX_PRICE_FEED_EOS_V0_27062023_ORB34FP", "derivedFeed": true }, { @@ -469,21 +301,13 @@ "address": "0xa2B726B1145A4773F68593CF171187d8EBe4d495", "nativeOracleAddress": "0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE", "tokenOracleAddress": "0x63A9133cd7c611d6049761038C16f238FddA71d7", - "description": "INJ / BNB", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x00009d870cd3D340588CDc63414785d84680cd84", - "feedSalt": "DEVX_PRICE_FEED_INJ_V0_27062023_HCNhbey", "derivedFeed": true }, { "symbol": "ALPHA", "address": "0xa1faa113cbE53436Df28FF0aEe54275c13B40975", "nativeOracleAddress": "0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE", - "tokenOracleAddress": "", - "description": "ALPHA / BNB", - "priceFeedFunction": "latestAnswer()", - "priceFeedAddress": "0x7bC032A7C19B1BdCb981D892854d090cfB0f238E", - "feedSalt": "DEVX_PRICE_FEED_ALPHA_V0_27062023_MtEbJge", + "tokenOracleAddress": "0x7bC032A7C19B1BdCb981D892854d090cfB0f238E", "derivedFeed": false }, { @@ -491,10 +315,6 @@ "address": "0xF21768cCBC73Ea5B6fd3C687208a7c2def2d966e", "nativeOracleAddress": "0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE", "tokenOracleAddress": "0x46f13472A4d4FeC9E07E8A00eE52f4Fa77810736", - "description": "REEF / BNB", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x000076aD9069129fEba496946bbf4B5e8AbA72b5", - "feedSalt": "DEVX_PRICE_FEED_REEF_V0_27062023_CMtabEv", "derivedFeed": true }, { @@ -502,10 +322,6 @@ "address": "0x52CE071Bd9b1C4B00A0b92D298c512478CaD67e8", "nativeOracleAddress": "0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE", "tokenOracleAddress": "0x0Db8945f9aEf5651fa5bd52314C5aAe78DfDe540", - "description": "COMP / BNB", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x00003Fa408c59d15f1C43F07CBa2724d2D64Bc73", - "feedSalt": "DEVX_PRICE_FEED_COMP_V0_27062023_54gIpet", "derivedFeed": true }, { @@ -513,10 +329,6 @@ "address": "0x47BEAd2563dCBf3bF2c9407fEa4dC236fAbA485A", "nativeOracleAddress": "0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE", "tokenOracleAddress": "0xE188A9875af525d25334d75F3327863B2b8cd0F1", - "description": "SXP / BNB", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x0000D67b9BbFCcefc402bFa787829a8dC49205e6", - "feedSalt": "DEVX_PRICE_FEED_SXP_V0_27062023_NHosDhE", "derivedFeed": true }, { @@ -524,10 +336,6 @@ "address": "0x88f1A5ae2A3BF98AEAF342D26B30a79438c9142e", "nativeOracleAddress": "0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE", "tokenOracleAddress": "0xD7eAa5Bf3013A96e3d515c055Dbd98DbdC8c620D", - "description": "YFI / BNB", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x00009c23613DF04f733A2B72f4e5CB585a47E5C9", - "feedSalt": "DEVX_PRICE_FEED_YFI_V0_27062023_6EmwyeO", "derivedFeed": true }, { @@ -535,10 +343,6 @@ "address": "0xcF6BB5389c92Bdda8a3747Ddb454cB7a64626C63", "nativeOracleAddress": "0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE", "tokenOracleAddress": "0xBF63F430A79D4036A5900C19818aFf1fa710f206", - "description": "XVS / BNB", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x000003721b4D9C88c38aD56aA11E13de61486Ab5", - "feedSalt": "DEVX_PRICE_FEED_XVS_V0_27062023_wBKaSPp", "derivedFeed": true }, { @@ -546,10 +350,6 @@ "address": "0x3EE2200Efb3400fAbB9AacF31297cBdD1d435D47", "nativeOracleAddress": "0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE", "tokenOracleAddress": "0xa767f745331D267c7751297D982b050c93985627", - "description": "ADA / BNB", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x0000d32Bded21f301b68d7beA45276F3E6314fe2", - "feedSalt": "DEVX_PRICE_FEED_ADA_V0_27062023_qygbOee", "derivedFeed": true }, { @@ -557,10 +357,6 @@ "address": "0xAD6cAEb32CD2c308980a548bD0Bc5AA4306c6c18", "nativeOracleAddress": "0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE", "tokenOracleAddress": "0xC78b99Ae87fF43535b0C782128DB3cB49c74A4d3", - "description": "BAND / BNB", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x00000c66455D60C1CD69AF839Fe95CEe02ed531f", - "feedSalt": "DEVX_PRICE_FEED_BAND_V0_27062023_wtCuh5w", "derivedFeed": true }, { @@ -568,10 +364,6 @@ "address": "0x4BD17003473389A42DAF6a0a729f6Fdb328BbBd7", "nativeOracleAddress": "0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE", "tokenOracleAddress": "0x058316f8Bb13aCD442ee7A216C7b60CFB4Ea1B53", - "description": "VAI / BNB", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x00002F98e2473E715C4C799ed6283af82cae5436", - "feedSalt": "DEVX_PRICE_FEED_VAI_V0_27062023_5JAZXHq", "derivedFeed": true }, { @@ -579,10 +371,6 @@ "address": "0x7083609fCE4d1d8Dc0C979AAb8c869Ea2C873402", "nativeOracleAddress": "0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE", "tokenOracleAddress": "0xC333eb0086309a16aa7c8308DfD32c8BBA0a2592", - "description": "DOT / BNB", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x0000344411679C8d7E049349B02d082eF500661b", - "feedSalt": "DEVX_PRICE_FEED_DOT_V0_27062023_lIgEmg1", "derivedFeed": true }, { @@ -590,10 +378,6 @@ "address": "0xa184088a740c695E156F91f5cC086a06bb78b827", "nativeOracleAddress": "0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE", "tokenOracleAddress": "0x88E71E6520E5aC75f5338F5F0c9DeD9d4f692cDA", - "description": "AUTO / BNB", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x000093807D7670407CCA1F1B4C2222AcC81F2dda", - "feedSalt": "DEVX_PRICE_FEED_AUTO_V0_27062023_nk64r20", "derivedFeed": true }, { @@ -601,10 +385,6 @@ "address": "0x570A5D26f7765Ecb712C0924E4De545B89fD43dF", "nativeOracleAddress": "0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE", "tokenOracleAddress": "0x0E8a53DD9c13589df6382F13dA6B3Ec8F919B323", - "description": "SOL / BNB", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x0000daa8f8e278521abE99805113c0Cc157Acb97", - "feedSalt": "DEVX_PRICE_FEED_SOL_V0_27062023_tnr0Rv6", "derivedFeed": true }, { @@ -612,10 +392,6 @@ "address": "0xfE19F0B51438fd612f6FD59C1dbB3eA319f433Ba", "nativeOracleAddress": "0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE", "tokenOracleAddress": "0xc9D267542B23B41fB93397a93e5a1D7B80Ea5A01", - "description": "MIM / BNB", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x000020a943CeCe5043E1309663bc5Bfa822DE646", - "feedSalt": "DEVX_PRICE_FEED_MIM_V0_27062023_faxTfxe", "derivedFeed": true }, { @@ -623,10 +399,6 @@ "address": "0xbA2aE424d960c26247Dd6c32edC70B295c744C43", "nativeOracleAddress": "0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE", "tokenOracleAddress": "0x3AB0A0d137D4F946fBB19eecc6e92E64660231C8", - "description": "DOGE / BNB", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x0000DDb960714B49A6470F66C032c7C6cc41acB2", - "feedSalt": "DEVX_PRICE_FEED_DOGE_V0_27062023_5YdLYJc", "derivedFeed": true }, { @@ -634,10 +406,6 @@ "address": "0x2eD9a5C8C13b93955103B9a7C167B67Ef4d568a3", "nativeOracleAddress": "0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE", "tokenOracleAddress": "0x4978c0abE6899178c1A74838Ee0062280888E2Cf", - "description": "MASK / BNB", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x0000ca992a5420dE8725A494aE98638E2682B0f8", - "feedSalt": "DEVX_PRICE_FEED_MASK_V0_27062023_n5J3tCG", "derivedFeed": true } ] diff --git a/scripts/configs/prod/token-config-bnb-testnet.json b/scripts/configs/prod/token-config-bnb-testnet.json index f841b8e..4fb655b 100644 --- a/scripts/configs/prod/token-config-bnb-testnet.json +++ b/scripts/configs/prod/token-config-bnb-testnet.json @@ -5,10 +5,6 @@ "address": "0x1ffa9c87ead57adc9e4f9a7d26ec3a52150db3b0", "nativeOracleAddress": "0x2514895c72f50D8bd4B4F9b1110F0D6bD2c97526", "tokenOracleAddress": "0x90c069C4538adAc136E051052E14c1cD799C41B7", - "description": "USDC / BNB", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x000005abae3deadbe1fbd12105f950efba9eaec4", - "feedSalt": "DEVX_PRICE_FEED_USDC_V0_27062023_uiaqdyv", "derivedFeed": true }, { @@ -16,10 +12,6 @@ "address": "0x03bbb5660b8687c2aa453a0e42dcb6e0732b1266", "nativeOracleAddress": "0x2514895c72f50D8bd4B4F9b1110F0D6bD2c97526", "tokenOracleAddress": "0xEca2605f0BCF2BA5966372C99837b1F182d3D620", - "description": "USDT / BNB", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x000001e2c2b39542c30a3fe57c4487030bc03adf", - "feedSalt": "DEVX_PRICE_FEED_USDT_V0_27062023_dIos1Nw", "derivedFeed": true }, { @@ -27,10 +19,6 @@ "address": "0x355c8c8395fadf2eaa6bb27f86e53e432e3de4e6", "nativeOracleAddress": "0x2514895c72f50D8bd4B4F9b1110F0D6bD2c97526", "tokenOracleAddress": "0xE4eE17114774713d2De0eC0f035d4F7665fc025D", - "description": "DAI / BNB", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x000000d2da196474046c7a4d94ab0e566b26d054", - "feedSalt": "DEVX_PRICE_FEED_DAI_V0_27062023_1m7JNWQ", "derivedFeed": true }, { @@ -38,10 +26,6 @@ "address": "0xc1537ab4f2e0b1c578baea06b5baae8f87ce971c", "nativeOracleAddress": "0x2514895c72f50D8bd4B4F9b1110F0D6bD2c97526", "tokenOracleAddress": "0x298619601ebCd58d0b526963Deb2365B485Edc74", - "description": "AAVE / BNB", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x0000AF22A276F86B405835c18863e1C2A679D9e3", - "feedSalt": "DEVX_PRICE_FEED_AAVE_V0_28062023_HsugnpY", "derivedFeed": true }, { @@ -49,10 +33,6 @@ "address": "0x81f9e7a56f6869a9a8c385d1e0701b312439501f", "nativeOracleAddress": "0x2514895c72f50D8bd4B4F9b1110F0D6bD2c97526", "tokenOracleAddress": "0x81faeDDfeBc2F8Ac524327d70Cf913001732224C", - "description": "CAKE / BNB", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x000007198738f877c01d9b7e4a4e1bd17e46e4a8", - "feedSalt": "DEVX_PRICE_FEED_CAKE_V0_27062023_1BKpzde", "derivedFeed": true }, { @@ -60,10 +40,6 @@ "address": "0xdeb12ea437c116ed823ab49244cafec4e41704cb", "nativeOracleAddress": "0x2514895c72f50D8bd4B4F9b1110F0D6bD2c97526", "tokenOracleAddress": "0x1B329402Cb1825C6F30A0d92aB9E2862BE47333f", - "description": "LINK / BNB", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x00000da809fe7be1297ee731f998141ba352778d", - "feedSalt": "DEVX_PRICE_FEED_LINK_V0_27062023_JHIxs6o", "derivedFeed": true } ] diff --git a/scripts/configs/prod/token-config-eth-mainnet.json b/scripts/configs/prod/token-config-eth-mainnet.json index cb3544b..11c5420 100644 --- a/scripts/configs/prod/token-config-eth-mainnet.json +++ b/scripts/configs/prod/token-config-eth-mainnet.json @@ -3,12 +3,8 @@ { "symbol": "USDC", "address": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", - "nativeOracleAddress": "", - "tokenOracleAddress": "", - "description": "USDC / ETH", - "priceFeedFunction": "latestAnswer()", - "priceFeedAddress": "0x986b5E1e1755e3C2440e960477f25201B0a8bbD4", - "feedSalt": "DEVX_PRICE_FEED_USDC_V0_27062023_uiaqdyv", + "nativeOracleAddress": "0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419", + "tokenOracleAddress": "0x986b5E1e1755e3C2440e960477f25201B0a8bbD4", "derivedFeed": false } ] diff --git a/scripts/configs/prod/token-config-goerli.json b/scripts/configs/prod/token-config-goerli.json index 9cd4674..0a6dfb7 100644 --- a/scripts/configs/prod/token-config-goerli.json +++ b/scripts/configs/prod/token-config-goerli.json @@ -5,10 +5,6 @@ "address": "0xb5B640E6414b6DeF4FC9B3C1EeF373925effeCcF", "nativeOracleAddress": "0xD4a33860578De61DBAbDc8BFdb98FD742fA7028e", "tokenOracleAddress": "0xAb5c49580294Aff77670F839ea425f5b78ab3Ae7", - "description": "USDC / ETH", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x000005ABaE3DEAdbe1FBD12105F950efbA9eaec4", - "feedSalt": "DEVX_PRICE_FEED_USDC_V0_27062023_uiaqdyv", "derivedFeed": true } ] diff --git a/scripts/configs/prod/token-config-moonbeam.json b/scripts/configs/prod/token-config-moonbeam.json index 11ea0cc..444a0d2 100644 --- a/scripts/configs/prod/token-config-moonbeam.json +++ b/scripts/configs/prod/token-config-moonbeam.json @@ -5,10 +5,6 @@ "address": "0x818ec0A7Fe18Ff94269904fCED6AE3DaE6d6dC0b", "nativeOracleAddress": "0x4497B606be93e773bbA5eaCFCb2ac5E2214220Eb", "tokenOracleAddress": "0xA122591F60115D63421f66F752EF9f6e0bc73abC", - "description": "USDC / GLMR", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x000005ABaE3DEAdbe1FBD12105F950efbA9eaec4", - "feedSalt": "DEVX_PRICE_FEED_USDC_V0_27062023_uiaqdyv", "derivedFeed": true }, { @@ -16,10 +12,6 @@ "address": "0xeFAeeE334F0Fd1712f9a8cc375f427D9Cdd40d73", "nativeOracleAddress": "0x4497B606be93e773bbA5eaCFCb2ac5E2214220Eb", "tokenOracleAddress": "0xD925C5BF88Bd0ca09312625d429240F811b437c6", - "description": "USDT / GLMR", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x000001E2C2B39542c30A3fE57c4487030bC03adF", - "feedSalt": "DEVX_PRICE_FEED_USDT_V0_27062023_dIos1Nw", "derivedFeed": true }, { @@ -27,10 +19,6 @@ "address": "0x765277EebeCA2e31912C9946eAe1021199B39C61", "nativeOracleAddress": "0x4497B606be93e773bbA5eaCFCb2ac5E2214220Eb", "tokenOracleAddress": "0x6063e1037B1afDA2bE5A3340757261E4d6a402ac", - "description": "DAI / GLMR", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x000000d2Da196474046c7a4D94Ab0E566B26d054", - "feedSalt": "DEVX_PRICE_FEED_DAI_V0_27062023_1m7JNWQ", "derivedFeed": true }, { @@ -38,10 +26,6 @@ "address": "0xA649325Aa7C5093d12D6F98EB4378deAe68CE23F", "nativeOracleAddress": "0x4497B606be93e773bbA5eaCFCb2ac5E2214220Eb", "tokenOracleAddress": "0x2330fd83662bba3Fc62bc48cC935ca58847A8957", - "description": "BUSD / GLMR", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x000020c39775542112E3DB0DbAD0d47A44bEB49A", - "feedSalt": "DEVX_PRICE_FEED_BUSD_V0_27062023_J8nJR8O", "derivedFeed": true } ] diff --git a/scripts/configs/prod/token-config-mumbai.json b/scripts/configs/prod/token-config-mumbai.json index d83dd9f..3ca5b80 100644 --- a/scripts/configs/prod/token-config-mumbai.json +++ b/scripts/configs/prod/token-config-mumbai.json @@ -5,10 +5,6 @@ "address": "0xdA5289fCAAF71d52a80A254da614a192b693e977", "nativeOracleAddress": "0xd0D5e3DB44DE05E9F294BB0a3bEEaF030DE24Ada", "tokenOracleAddress": "0x572dDec9087154dC5dfBB1546Bb62713147e0Ab0", - "description": "USDC / MATIC", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x000005abae3deadbe1fbd12105f950efba9eaec4", - "feedSalt": "DEVX_PRICE_FEED_USDC_V0_27062023_uiaqdyv", "derivedFeed": true }, { @@ -16,10 +12,6 @@ "address": "0xeaBc4b91d9375796AA4F69cC764A4aB509080A58", "nativeOracleAddress": "0xd0D5e3DB44DE05E9F294BB0a3bEEaF030DE24Ada", "tokenOracleAddress": "0x92C09849638959196E976289418e5973CC96d645", - "description": "USDT / MATIC", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x000001e2c2b39542c30a3fe57c4487030bc03adf", - "feedSalt": "DEVX_PRICE_FEED_USDT_V0_27062023_dIos1Nw", "derivedFeed": true }, { @@ -27,10 +19,6 @@ "address": "0x27a44456bEDb94DbD59D0f0A14fE977c777fC5C3", "nativeOracleAddress": "0xd0D5e3DB44DE05E9F294BB0a3bEEaF030DE24Ada", "tokenOracleAddress": "0x0FCAa9c899EC5A91eBc3D5Dd869De833b06fB046", - "description": "DAI / MATIC", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x000000d2da196474046c7a4d94ab0e566b26d054", - "feedSalt": "DEVX_PRICE_FEED_DAI_V0_27062023_1m7JNWQ", "derivedFeed": true }, { @@ -38,11 +26,8 @@ "address": "0xE03489D4E90b22c59c5e23d45DFd59Fc0dB8a025", "nativeOracleAddress": "0xd0D5e3DB44DE05E9F294BB0a3bEEaF030DE24Ada", "tokenOracleAddress": "0x9dd18534b8f456557d11B9DDB14dA89b2e52e308", - "description": "SAND / MATIC", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x00000980455efb131c1908efa908c1eaf19db352", - "feedSalt": "DEVX_PRICE_FEED_SAND_V0_27062023_eHPqgeR", - "derivedFeed": true + "derivedFeed": true, + "priceUpdateThreshold": 43200 } ] } diff --git a/scripts/configs/prod/token-config-optimism-goerli.json b/scripts/configs/prod/token-config-optimism-goerli.json index 88e324f..8eb68f3 100644 --- a/scripts/configs/prod/token-config-optimism-goerli.json +++ b/scripts/configs/prod/token-config-optimism-goerli.json @@ -5,10 +5,6 @@ "address": "0xe01435b1767aED7c25C943faCbdB582b6278650f", "nativeOracleAddress": "0x57241A37733983F97C4Ab06448F244A1E0Ca0ba8", "tokenOracleAddress": "0x2636B223652d388721A0ED2861792DA9062D8C73", - "description": "USDC / ETH", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x000005ABaE3DEAdbe1FBD12105F950efbA9eaec4", - "feedSalt": "DEVX_PRICE_FEED_USDC_V0_27062023_uiaqdyv", "derivedFeed": true }, { @@ -16,10 +12,6 @@ "address": "0x7c81B296d84802ec2d5e63846912011f2Cd3C31C", "nativeOracleAddress": "0x57241A37733983F97C4Ab06448F244A1E0Ca0ba8", "tokenOracleAddress": "0x31856c9a2A73aAee6100Aed852650f75c5F539D0", - "description": "DAI / ETH", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x000000d2Da196474046c7a4D94Ab0E566B26d054", - "feedSalt": "DEVX_PRICE_FEED_DAI_V0_27062023_1m7JNWQ", "derivedFeed": true }, { @@ -27,21 +19,13 @@ "address": "0xD6a8c1eee4D4e4EF998b911B03d52bc301d9b332", "nativeOracleAddress": "0x57241A37733983F97C4Ab06448F244A1E0Ca0ba8", "tokenOracleAddress": "0x0A024aa48E09e151090637d2b68162b1Caf7BdbA", - "description": "UNI / ETH", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x0000095CcE092E83E5826cFeb0f03cFa74915b41", - "feedSalt": "DEVX_PRICE_FEED_UNI_V0_27062023_PBQ6vdq", "derivedFeed": true }, { "symbol": "LINK", "address": "0x6EB5be4c0D6da4ca582e9912F212c0DB1d96fC3d", - "nativeOracleAddress": "", - "tokenOracleAddress": "", - "description": "LINK / ETH", - "priceFeedFunction": "latestAnswer()", - "priceFeedAddress": "0x37410D317b96E1fED1814473E1CcD323D0eB4Eb1", - "feedSalt": "DEVX_PRICE_FEED_LINK_V0_27062023_JHIxs6o", + "nativeOracleAddress": "0x57241A37733983F97C4Ab06448F244A1E0Ca0ba8", + "tokenOracleAddress": "0x37410D317b96E1fED1814473E1CcD323D0eB4Eb1", "derivedFeed": false } ] diff --git a/scripts/configs/prod/token-config-optimism-mainnet.json b/scripts/configs/prod/token-config-optimism-mainnet.json index 4f2b7b9..57ffe87 100644 --- a/scripts/configs/prod/token-config-optimism-mainnet.json +++ b/scripts/configs/prod/token-config-optimism-mainnet.json @@ -5,10 +5,6 @@ "address": "0x7F5c764cBc14f9669B88837ca1490cCa17c31607", "nativeOracleAddress": "0x13e3Ee699D1909E989722E753853AE30b17e08c5", "tokenOracleAddress": "0x16a9FA2FDa030272Ce99B29CF780dFA30361E0f3", - "description": "USDC / ETH", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x000005ABaE3DEAdbe1FBD12105F950efbA9eaec4", - "feedSalt": "DEVX_PRICE_FEED_USDC_V0_27062023_uiaqdyv", "derivedFeed": true }, { @@ -16,10 +12,6 @@ "address": "0x94b008aA00579c1307B0EF2c499aD98a8ce58e58", "nativeOracleAddress": "0x13e3Ee699D1909E989722E753853AE30b17e08c5", "tokenOracleAddress": "0xECef79E109e997bCA29c1c0897ec9d7b03647F5E", - "description": "USDT / ETH", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x000001E2C2B39542c30A3fE57c4487030bC03adF", - "feedSalt": "DEVX_PRICE_FEED_USDT_V0_27062023_dIos1Nw", "derivedFeed": true }, { @@ -27,10 +19,6 @@ "address": "0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1", "nativeOracleAddress": "0x13e3Ee699D1909E989722E753853AE30b17e08c5", "tokenOracleAddress": "0x8dBa75e83DA73cc766A7e5a0ee71F656BAb470d6", - "description": "DAI / ETH", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x000000d2Da196474046c7a4D94Ab0E566B26d054", - "feedSalt": "DEVX_PRICE_FEED_DAI_V0_27062023_1m7JNWQ", "derivedFeed": true }, { @@ -38,10 +26,6 @@ "address": "0x68f180fcCe6836688e9084f035309E29Bf0A2095", "nativeOracleAddress": "0x13e3Ee699D1909E989722E753853AE30b17e08c5", "tokenOracleAddress": "0x718A5788b89454aAE3A028AE9c111A29Be6c2a6F", - "description": "WBTC / ETH", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x00002D444779516f9D60368f3fa1E2b036BCCc7D", - "feedSalt": "DEVX_PRICE_FEED_WBTC_V0_27062023_z41FLvK", "derivedFeed": true }, { @@ -49,21 +33,13 @@ "address": "0x8700dAec35aF8Ff88c16BdF0418774CB3D7599B4", "nativeOracleAddress": "0x13e3Ee699D1909E989722E753853AE30b17e08c5", "tokenOracleAddress": "0x2FCF37343e916eAEd1f1DdaaF84458a359b53877", - "description": "SNX / ETH", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x0000f303a2ED1eDF64C3B41E937028b7140d94c8", - "feedSalt": "DEVX_PRICE_FEED_SNX_V0_27062023_4DrwwXZ", "derivedFeed": true }, { "symbol": "LINK", "address": "0x350a791Bfc2C21F9Ed5d10980Dad2e2638ffa7f6", "nativeOracleAddress": "0x13e3Ee699D1909E989722E753853AE30b17e08c5", - "tokenOracleAddress": "", - "description": "LINK / ETH", - "priceFeedFunction": "latestAnswer()", - "priceFeedAddress": "0x464A1515ADc20de946f8d0DEB99cead8CEAE310d", - "feedSalt": "", + "tokenOracleAddress": "0x464A1515ADc20de946f8d0DEB99cead8CEAE310d", "derivedFeed": false }, { @@ -71,10 +47,6 @@ "address": "0x8c6f28f2F1A3C87F0f938b96d27520d9751ec8d9", "nativeOracleAddress": "0x13e3Ee699D1909E989722E753853AE30b17e08c5", "tokenOracleAddress": "0x7f99817d87baD03ea21E05112Ca799d715730efe", - "description": "SUSD / ETH", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x000037cD348e5B79AdEe29148E6D05520B2c45D2", - "feedSalt": "DEVX_PRICE_FEED_SUSD_V0_24072023_0Dv7g4m", "derivedFeed": true }, { @@ -82,10 +54,6 @@ "address": "0x9e1028F5F1D5eDE59748FFceE5532509976840E0", "nativeOracleAddress": "0x13e3Ee699D1909E989722E753853AE30b17e08c5", "tokenOracleAddress": "0xA12CDDd8e986AF9288ab31E58C60e65F2987fB13", - "description": "PERP / ETH", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x000068aa7F8C85Bf8aDa5AA18099baFcd2e1dF5B", - "feedSalt": "DEVX_PRICE_FEED_PERP_V0_24072023_uh65wbb", "derivedFeed": true }, { @@ -93,10 +61,6 @@ "address": "0x4200000000000000000000000000000000000042", "nativeOracleAddress": "0x13e3Ee699D1909E989722E753853AE30b17e08c5", "tokenOracleAddress": "0x0D276FC14719f9292D5C1eA2198673d1f4269246", - "description": "OP / ETH", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x0000462be5bbdA0a7B5414044C32C7e37D0D35f3", - "feedSalt": "DEVX_PRICE_FEED_OP_V0_24072023_riqc17D", "derivedFeed": true } ] diff --git a/scripts/configs/prod/token-config-polygon-mainnet.json b/scripts/configs/prod/token-config-polygon-mainnet.json index 7f5ec61..55f9dd2 100644 --- a/scripts/configs/prod/token-config-polygon-mainnet.json +++ b/scripts/configs/prod/token-config-polygon-mainnet.json @@ -5,10 +5,6 @@ "address": "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174", "nativeOracleAddress": "0xAB594600376Ec9fD91F8e885dADF0CE036862dE0", "tokenOracleAddress": "0xfE4A8cc5b5B2366C1B58Bea3858e81843581b2F7", - "description": "USDC / MATIC", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x000005ABaE3DEAdbe1FBD12105F950efbA9eaec4", - "feedSalt": "DEVX_PRICE_FEED_USDC_V0_27062023_uiaqdyv", "derivedFeed": true }, { @@ -16,10 +12,6 @@ "address": "0xc2132D05D31c914a87C6611C10748AEb04B58e8F", "nativeOracleAddress": "0xAB594600376Ec9fD91F8e885dADF0CE036862dE0", "tokenOracleAddress": "0x0A6513e40db6EB1b165753AD52E80663aeA50545", - "description": "USDT / MATIC", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x000001E2C2B39542c30A3fE57c4487030bC03adF", - "feedSalt": "DEVX_PRICE_FEED_USDT_V0_27062023_dIos1Nw", "derivedFeed": true }, { @@ -27,10 +19,6 @@ "address": "0x8f3Cf7ad23Cd3CaDbD9735AFf958023239c6A063", "nativeOracleAddress": "0xAB594600376Ec9fD91F8e885dADF0CE036862dE0", "tokenOracleAddress": "0x4746DeC9e833A82EC7C2C1356372CcF2cfcD2F3D", - "description": "DAI / MATIC", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x000000d2Da196474046c7a4D94Ab0E566B26d054", - "feedSalt": "DEVX_PRICE_FEED_DAI_V0_27062023_1m7JNWQ", "derivedFeed": true }, { @@ -38,10 +26,6 @@ "address": "0xBbba073C31bF03b8ACf7c28EF0738DeCF3695683", "nativeOracleAddress": "0xAB594600376Ec9fD91F8e885dADF0CE036862dE0", "tokenOracleAddress": "0x3D49406EDd4D52Fb7FFd25485f32E073b529C924", - "description": "SAND / MATIC", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x00000980455EFB131c1908eFa908c1eaF19db352", - "feedSalt": "DEVX_PRICE_FEED_SAND_V0_27062023_eHPqgeR", "derivedFeed": true }, { @@ -49,10 +33,6 @@ "address": "0x1B815d120B3eF02039Ee11dC2d33DE7aA4a8C603", "nativeOracleAddress": "0xAB594600376Ec9fD91F8e885dADF0CE036862dE0", "tokenOracleAddress": "0x6a99EC84819FB7007dd5D032068742604E755c56", - "description": "WOO / MATIC", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x0000DE1c603c7272383E8a7Ed24a5B9941da36DF", - "feedSalt": "DEVX_PRICE_FEED_WOO_V0_27062023_zjZa7el", "derivedFeed": true }, { @@ -60,10 +40,6 @@ "address": "0xD6DF932A45C0f255f85145f286eA0b292B21C90B", "nativeOracleAddress": "0xAB594600376Ec9fD91F8e885dADF0CE036862dE0", "tokenOracleAddress": "0x72484B12719E23115761D5DA1646945632979bB6", - "description": "AAVE / MATIC", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x0000AF22A276F86B405835c18863e1C2A679D9e3", - "feedSalt": "DEVX_PRICE_FEED_AAVE_V0_28062023_HsugnpY", "derivedFeed": true }, { @@ -71,10 +47,6 @@ "address": "0x9C9e5fD8bbc25984B178FdCE6117Defa39d2db39", "nativeOracleAddress": "0xAB594600376Ec9fD91F8e885dADF0CE036862dE0", "tokenOracleAddress": "0xE0dC07D5ED74741CeeDA61284eE56a2A0f7A4Cc9", - "description": "BUSD / MATIC", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x000020c39775542112E3DB0DbAD0d47A44bEB49A", - "feedSalt": "DEVX_PRICE_FEED_BUSD_V0_27062023_J8nJR8O", "derivedFeed": true }, { @@ -82,10 +54,6 @@ "address": "0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619", "nativeOracleAddress": "0xAB594600376Ec9fD91F8e885dADF0CE036862dE0", "tokenOracleAddress": "0xF9680D99D6C9589e2a93a78A04A279e509205945", - "description": "ETH / MATIC", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x00008cC9D5BF9F97AE2879163011707812561b42", - "feedSalt": "DEVX_PRICE_FEED_ETH_V0_27062023_jZ9Dvxh", "derivedFeed": true }, { @@ -93,10 +61,6 @@ "address": "0xA1c57f48F0Deb89f569dFbE6E2B7f46D33606fD4", "nativeOracleAddress": "0xAB594600376Ec9fD91F8e885dADF0CE036862dE0", "tokenOracleAddress": "0xA1CbF3Fe43BC3501e3Fc4b573e822c70e76A7512", - "description": "MANA / MATIC", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x0000De2Ed5b4f74b6f03539529E8Cb67545d7834", - "feedSalt": "DEVX_PRICE_FEED_MANA_V0_28062023_E87OPLB", "derivedFeed": true }, { @@ -104,10 +68,6 @@ "address": "0xB5C064F955D8e7F38fE0460C556a72987494eE17", "nativeOracleAddress": "0xAB594600376Ec9fD91F8e885dADF0CE036862dE0", "tokenOracleAddress": "0xa058689f4bCa95208bba3F265674AE95dED75B6D", - "description": "QUICK / MATIC", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x0000ABAe40C30ab8ac824ba01Eb1003A0d1a2754", - "feedSalt": "DEVX_PRICE_FEED_QUICK_V0_27062023_9UTXOsb", "derivedFeed": true }, { @@ -115,10 +75,6 @@ "address": "0x0b3F868E0BE5597D5DB7fEB59E1CADBb0fdDa50a", "nativeOracleAddress": "0xAB594600376Ec9fD91F8e885dADF0CE036862dE0", "tokenOracleAddress": "0x49B0c695039243BBfEb8EcD054EB70061fd54aa0", - "description": "SUSHI / MATIC", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x0000552E10e879F403dD5F041742E6356d031825", - "feedSalt": "DEVX_PRICE_FEED_SUSHI_V0_27062023_dyZta4I", "derivedFeed": true }, { @@ -126,10 +82,6 @@ "address": "0x2e1AD108fF1D8C782fcBbB89AAd783aC49586756", "nativeOracleAddress": "0xAB594600376Ec9fD91F8e885dADF0CE036862dE0", "tokenOracleAddress": "0x7C5D415B64312D38c56B54358449d0a4058339d2", - "description": "TUSD / MATIC", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x000064b138eDB97Ac8a3F4564E14d9a331288a6B", - "feedSalt": "DEVX_PRICE_FEED_TUSD_V0_27062023_QHVx0oQ", "derivedFeed": true }, { @@ -137,10 +89,6 @@ "address": "0xb33EaAd8d922B1083446DC23f610c2567fB5180f", "nativeOracleAddress": "0xAB594600376Ec9fD91F8e885dADF0CE036862dE0", "tokenOracleAddress": "0xdf0Fb4e4F928d2dCB76f438575fDD8682386e13C", - "description": "UNI / MATIC", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x0000095CcE092E83E5826cFeb0f03cFa74915b41", - "feedSalt": "DEVX_PRICE_FEED_UNI_V0_27062023_PBQ6vdq", "derivedFeed": true }, { @@ -148,21 +96,13 @@ "address": "0x1bfd67037b42cf73acf2047067bd4f2c47d9bfd6", "nativeOracleAddress": "0xAB594600376Ec9fD91F8e885dADF0CE036862dE0", "tokenOracleAddress": "0xDE31F8bFBD8c84b5360CFACCa3539B938dd78ae6", - "description": "UNI / MATIC", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x00002D444779516f9D60368f3fa1E2b036BCCc7D", - "feedSalt": "DEVX_PRICE_FEED_WBTC_V0_27062023_z41FLvK", "derivedFeed": true }, { "symbol": "LINK", "address": "0x53E0bca35eC356BD5ddDFebbD1Fc0fD03FaBad39", - "nativeOracleAddress": "", - "tokenOracleAddress": "", - "description": "LINK / MATIC", - "priceFeedFunction": "latestAnswer()", - "priceFeedAddress": "0x5787BefDc0ECd210Dfa948264631CD53E68F7802", - "feedSalt": "DEVX_PRICE_FEED_LINK_V0_27062023_JHIxs6o", + "nativeOracleAddress": "0xAB594600376Ec9fD91F8e885dADF0CE036862dE0", + "tokenOracleAddress": "0x5787BefDc0ECd210Dfa948264631CD53E68F7802", "derivedFeed": false }, { @@ -170,10 +110,6 @@ "address": "0xE0B52e49357Fd4DAf2c15e02058DCE6BC0057db4", "nativeOracleAddress": "0xAB594600376Ec9fD91F8e885dADF0CE036862dE0", "tokenOracleAddress": "0x9b88d07B2354eF5f4579690356818e07371c7BeD", - "description": "agEUR / MATIC", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x00000a13B868fEed2De6ADC47B982caA875F1879", - "feedSalt": "DEVX_PRICE_FEED_AGEUR_V0_27062023_npeAxaf", "derivedFeed": true }, { @@ -181,10 +117,6 @@ "address": "0x2C89bbc92BD86F8075d1DEcc58C7F4E0107f286b", "nativeOracleAddress": "0xAB594600376Ec9fD91F8e885dADF0CE036862dE0", "tokenOracleAddress": "0xe01eA2fbd8D76ee323FbEd03eB9a8625EC981A10", - "description": "AVAX / MATIC", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x0000312944601e41a06Bc26C7B28912ff15248e1", - "feedSalt": "DEVX_PRICE_FEED_AVAX_V0_27062023_f9ygwpY", "derivedFeed": true }, { @@ -192,10 +124,6 @@ "address": "0x9a71012B13CA4d3D0Cdc72A177DF3ef03b0E76A3", "nativeOracleAddress": "0xAB594600376Ec9fD91F8e885dADF0CE036862dE0", "tokenOracleAddress": "0xD106B538F2A868c28Ca1Ec7E298C3325E0251d66", - "description": "BAL / MATIC", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x00002a35F6a70c64769D9FF26750f5b5cAE2bC88", - "feedSalt": "DEVX_PRICE_FEED_BAL_V0_27062023_IzEMruz", "derivedFeed": true }, { @@ -203,10 +131,6 @@ "address": "0xD85d1e945766Fea5Eda9103F918Bd915FbCa63E6", "nativeOracleAddress": "0xAB594600376Ec9fD91F8e885dADF0CE036862dE0", "tokenOracleAddress": "0xc9ECF45956f576681bDc01F79602A79bC2667B0c", - "description": "CEL / MATIC", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x0000c8EFFbE9d075B6e56C1Ab2d1De9952141C8D", - "feedSalt": "DEVX_PRICE_FEED_CEL_V0_28062023_ZALYl4b", "derivedFeed": true }, { @@ -214,10 +138,6 @@ "address": "0x8505b9d2254A7Ae468c0E9dd10Ccea3A837aef5c", "nativeOracleAddress": "0xAB594600376Ec9fD91F8e885dADF0CE036862dE0", "tokenOracleAddress": "0x2A8758b7257102461BC958279054e372C2b1bDE6", - "description": "COMP / MATIC", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x00003Fa408c59d15f1C43F07CBa2724d2D64Bc73", - "feedSalt": "DEVX_PRICE_FEED_COMP_V0_27062023_54gIpet", "derivedFeed": true }, { @@ -225,10 +145,6 @@ "address": "0x172370d5Cd63279eFa6d502DAB29171933a610AF", "nativeOracleAddress": "0xAB594600376Ec9fD91F8e885dADF0CE036862dE0", "tokenOracleAddress": "0x336584C8E6Dc19637A5b36206B1c79923111b405", - "description": "CRV / MATIC", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x0000ba91FB68ea2fF253328834CB9E1d0f427D83", - "feedSalt": "DEVX_PRICE_FEED_CRV_V0_27062023_GrIWEtf", "derivedFeed": true }, { @@ -236,10 +152,6 @@ "address": "0x45c32fA6DF82ead1e2EF74d17b76547EDdFaFF89", "nativeOracleAddress": "0xAB594600376Ec9fD91F8e885dADF0CE036862dE0", "tokenOracleAddress": "0x00DBeB1e45485d53DF7C2F0dF1Aa0b6Dc30311d3", - "description": "FRAX / MATIC", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x00005f9f7f943e3db079D3B9A7A86aa80b70898C", - "feedSalt": "DEVX_PRICE_FEED_FRAX_V0_27062023_MmgkOOQ", "derivedFeed": true }, { @@ -247,10 +159,6 @@ "address": "0x385Eeac5cB85A38A9a07A70c73e0a3271CfB54A7", "nativeOracleAddress": "0xAB594600376Ec9fD91F8e885dADF0CE036862dE0", "tokenOracleAddress": "0xDD229Ce42f11D8Ee7fFf29bDB71C7b81352e11be", - "description": "GHST / MATIC", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x0000Af2E95EcABCC7b2c03BF2Dd8e840554A98c4", - "feedSalt": "DEVX_PRICE_FEED_GHST_V0_27062023_GgAZpkz", "derivedFeed": true }, { @@ -258,10 +166,6 @@ "address": "0x5fe2B58c013d7601147DcdD68C143A77499f5531", "nativeOracleAddress": "0xAB594600376Ec9fD91F8e885dADF0CE036862dE0", "tokenOracleAddress": "0x3FabBfb300B1e2D7c9B84512fe9D30aeDF24C410", - "description": "GRT / MATIC", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x000005e5cC18cdb3cdB513caBAFb4d215Ae63235", - "feedSalt": "DEVX_PRICE_FEED_GRT_V0_27062023_uBLkfy1", "derivedFeed": true }, { @@ -269,10 +173,6 @@ "address": "0x1C954E8fe737F99f68Fa1CCda3e51ebDB291948C", "nativeOracleAddress": "0xAB594600376Ec9fD91F8e885dADF0CE036862dE0", "tokenOracleAddress": "0x10e5f3DFc81B3e5Ef4e648C4454D04e79E1E41E2", - "description": "KNC / MATIC", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x0000DB3bfA1c8c27e4b99e5b023bFD30F210c185", - "feedSalt": "DEVX_PRICE_FEED_KNC_V0_27062023_G3ECzSl", "derivedFeed": true }, { @@ -280,10 +180,6 @@ "address": "0xa3Fa99A148fA48D14Ed51d610c367C61876997F1", "nativeOracleAddress": "0xAB594600376Ec9fD91F8e885dADF0CE036862dE0", "tokenOracleAddress": "0xd8d483d813547CfB624b8Dc33a00F2fcbCd2D428", - "description": "MIMATIC / MATIC", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x0000A60ddc7E929Da83Af1821fb13B7BbC2Bf2C2", - "feedSalt": "DEVX_PRICE_FEED_MIMATIC_V0_27062023_IgmN8NM", "derivedFeed": true }, { @@ -291,10 +187,6 @@ "address": "0xC3Ec80343D2bae2F8E680FDADDe7C17E71E114ea", "nativeOracleAddress": "0xAB594600376Ec9fD91F8e885dADF0CE036862dE0", "tokenOracleAddress": "0xc86105DccF9BD629Cea7Fd41f94c6050bF96D57F", - "description": "OM / MATIC", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x00005AFae4A06322ce9B08bB930eC175BD35FA53", - "feedSalt": "DEVX_PRICE_FEED_OM_V0_27062023_moV4Zhy", "derivedFeed": true }, { @@ -302,10 +194,6 @@ "address": "0x8765f05ADce126d70bcdF1b0a48Db573316662eB", "nativeOracleAddress": "0xAB594600376Ec9fD91F8e885dADF0CE036862dE0", "tokenOracleAddress": "0x24C0e0FC8cCb21e2fb3e1A8A4eC4b29458664f79", - "description": "PLA / MATIC", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x00007AdBC383D37A2F67D45544B677191D73d2Ba", - "feedSalt": "DEVX_PRICE_FEED_PLA_V0_27062023_BsEEM6r", "derivedFeed": true }, { @@ -313,10 +201,6 @@ "address": "0x00e5646f60AC6Fb446f621d146B6E1886f002905", "nativeOracleAddress": "0xAB594600376Ec9fD91F8e885dADF0CE036862dE0", "tokenOracleAddress": "0x7f45273fD7C644714825345670414Ea649b50b16", - "description": "RAI / MATIC", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x0000A3D0BEDB1f6533DB80ff63d33A3ccba4dDDE", - "feedSalt": "DEVX_PRICE_FEED_RAI_V0_27062023_GfS8MIt", "derivedFeed": true }, { @@ -324,10 +208,6 @@ "address": "0x50B728D8D964fd00C2d0AAD81718b71311feF68a", "nativeOracleAddress": "0xAB594600376Ec9fD91F8e885dADF0CE036862dE0", "tokenOracleAddress": "0xbF90A5D9B6EE9019028dbFc2a9E50056d5252894", - "description": "SNX / MATIC", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x0000f303a2ED1eDF64C3B41E937028b7140d94c8", - "feedSalt": "DEVX_PRICE_FEED_SNX_V0_27062023_4DrwwXZ", "derivedFeed": true }, { @@ -335,10 +215,6 @@ "address": "0xd93f7E271cB87c23AaA73edC008A79646d1F9912", "nativeOracleAddress": "0xAB594600376Ec9fD91F8e885dADF0CE036862dE0", "tokenOracleAddress": "0x10C8264C0935b3B9870013e057f330Ff3e9C56dC", - "description": "SOL / MATIC", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x0000daa8f8e278521abE99805113c0Cc157Acb97", - "feedSalt": "DEVX_PRICE_FEED_SOL_V0_27062023_tnr0Rv6", "derivedFeed": true }, { @@ -346,10 +222,6 @@ "address": "0xEFeE2de82343BE622Dcb4E545f75a3b9f50c272D", "nativeOracleAddress": "0xAB594600376Ec9fD91F8e885dADF0CE036862dE0", "tokenOracleAddress": "0xd78325DcA0F90F0FFe53cCeA1B02Bb12E1bf8FdB", - "description": "TRY / MATIC", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x000017bbc04B0b1EFd0372E1f353BC5aaDD4c659", - "feedSalt": "DEVX_PRICE_FEED_TRY_V0_27062023_CDdLFlo", "derivedFeed": true } ] diff --git a/scripts/configs/prod/token-config-sepolia.json b/scripts/configs/prod/token-config-sepolia.json index f998f15..5069e60 100644 --- a/scripts/configs/prod/token-config-sepolia.json +++ b/scripts/configs/prod/token-config-sepolia.json @@ -5,10 +5,6 @@ "address": "0x9C73373C70F23920EA54F7883dCB1F85b162Df40", "nativeOracleAddress": "0x694AA1769357215DE4FAC081bf1f309aDC325306", "tokenOracleAddress": "0xA2F78ab2355fe2f984D808B5CeE7FD0A93D5270E", - "description": "USDC / ETH", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x000005ABaE3DEAdbe1FBD12105F950efbA9eaec4", - "feedSalt": "DEVX_PRICE_FEED_USDC_V0_27062023_uiaqdyv", "derivedFeed": true }, { @@ -16,10 +12,6 @@ "address": "0x5Bc7c8cFC6d54c055547Fcd8f6Ee4f2eDcda613e", "nativeOracleAddress": "0x694AA1769357215DE4FAC081bf1f309aDC325306", "tokenOracleAddress": "0x14866185B1962B63C3Ea9E03Bc1da838bab34C19", - "description": "DAI / ETH", - "priceFeedFunction": "getThePrice()", - "priceFeedAddress": "0x000000d2da196474046c7a4d94ab0e566b26d054", - "feedSalt": "DEVX_PRICE_FEED_DAI_V0_27062023_1m7JNWQ", "derivedFeed": true } ] diff --git a/scripts/deploy-arbitrum-goerli.ts b/scripts/deploy-arbitrum-goerli.ts deleted file mode 100644 index 922ecf3..0000000 --- a/scripts/deploy-arbitrum-goerli.ts +++ /dev/null @@ -1,474 +0,0 @@ -import { ethers, run } from "hardhat"; -import { arbGoerliConfigInfoProd } from "./configs"; -import { TokenConfig } from "./utils/Types"; -import { - deployContract, - DEPLOYMENT_SALTS, - encodeParam, - isContract, -} from "./utils"; -import { - BiconomyTokenPaymaster, - BiconomyTokenPaymaster__factory, - ChainlinkOracleAggregator, - ChainlinkOracleAggregator__factory, - Deployer, - Deployer__factory, -} from "../typechain-types"; - -const tokenConfig: TokenConfig = arbGoerliConfigInfoProd; - -const entryPointAddress = - process.env.ENTRY_POINT_ADDRESS || - "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789"; -const verifyingSigner = process.env.PAYMASTER_SIGNER_ADDRESS_DEV || ""; -const DEPLOYER_CONTRACT_ADDRESS_DEV = - process.env.DEPLOYER_CONTRACT_ADDRESS_DEV || ""; -const DEPLOYER_CONTRACT_ADDRESS_PROD = - process.env.DEPLOYER_CONTRACT_ADDRESS_PROD || ""; - -function delay(ms: number) { - return new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, ms); - }); -} - -async function deployChainlinkOracleAggregatorContract( - deployerInstance: Deployer, - earlyOwnerAddress: string -): Promise { - const ORACLE_AGGREGATOR_SALT = ethers.utils.keccak256( - ethers.utils.toUtf8Bytes(DEPLOYMENT_SALTS.ORACLE_AGGREGATOR) - ); - - const OracleAggregator = await ethers.getContractFactory( - "ChainlinkOracleAggregator" - ); - const oracleAggregatorBytecode = `${OracleAggregator.bytecode}${encodeParam( - "address", - earlyOwnerAddress - ).slice(2)}`; - const oracleAggregatorComputedAddr = await deployerInstance.addressOf( - ORACLE_AGGREGATOR_SALT - ); - console.log( - "Chainlink Oracle Aggregator Computed Address: ", - oracleAggregatorComputedAddr - ); - - const isOracleAggregatorDeployed = await isContract( - oracleAggregatorComputedAddr, - provider - ); // true (deployed on-chain) - if (!isOracleAggregatorDeployed) { - try { - await deployContract( - DEPLOYMENT_SALTS.ORACLE_AGGREGATOR, - oracleAggregatorComputedAddr, - ORACLE_AGGREGATOR_SALT, - oracleAggregatorBytecode, - deployerInstance - ); - await delay(10000); - } catch (err) { - console.log("issue with the deployment"); - console.log(err); - return ethers.constants.AddressZero; - } - - try { - await run(`verify:verify`, { - address: oracleAggregatorComputedAddr, - constructorArguments: [earlyOwnerAddress], - }); - } catch (err) { - console.log("issue with the verification ", oracleAggregatorComputedAddr); - return oracleAggregatorComputedAddr; - } - } else { - console.log( - "Chainlink Oracle Aggregator is already deployed with address ", - oracleAggregatorComputedAddr - ); - } - return oracleAggregatorComputedAddr; -} - -async function deployTokenPaymasterContract( - deployerInstance: Deployer, - earlyOwnerAddress: string -): Promise { - const salt = ethers.utils.keccak256( - ethers.utils.toUtf8Bytes(DEPLOYMENT_SALTS.TOKEN_PAYMASTER) - ); - - const BiconomyTokenPaymaster = await ethers.getContractFactory( - "BiconomyTokenPaymaster" - ); - const tokenPaymasterBytecode = `${ - BiconomyTokenPaymaster.bytecode - }${encodeParam("address", earlyOwnerAddress).slice(2)}${encodeParam( - "address", - entryPointAddress - ).slice(2)}${encodeParam("address", verifyingSigner).slice(2)}`; - - const tokenPaymasterComputedAddr = await deployerInstance.addressOf(salt); - console.log("Token paymaster Computed Address: ", tokenPaymasterComputedAddr); - const isContractDeployed = await isContract( - tokenPaymasterComputedAddr, - provider - ); - if (!isContractDeployed) { - try { - await deployContract( - DEPLOYMENT_SALTS.TOKEN_PAYMASTER, - tokenPaymasterComputedAddr, - salt, - tokenPaymasterBytecode, - deployerInstance - ); - await delay(5000); - } catch (err) { - console.log(err); - console.log("issue with the deployment"); - return ethers.constants.AddressZero; - } - try { - await run(`verify:verify`, { - address: tokenPaymasterComputedAddr, - constructorArguments: [ - earlyOwnerAddress, - entryPointAddress, - verifyingSigner, - ], - }); - } catch (err) { - console.log("issue with the verification ", tokenPaymasterComputedAddr); - return tokenPaymasterComputedAddr; - } - } else { - console.log( - "Token Paymaster is Already deployed with address ", - tokenPaymasterComputedAddr - ); - } - return tokenPaymasterComputedAddr; -} - -async function deployDerivedPriceFeed( - deployerInstance: Deployer, - nativeOracleAddress: string, - tokenOracleAddress: string, - description: string, - feedSalt: string -): Promise { - const salt = ethers.utils.keccak256(ethers.utils.toUtf8Bytes(feedSalt)); - - const DerivedPriceFeed = await ethers.getContractFactory("DerivedPriceFeed"); - - const derivedPriceFeedBytecode = `${ - DerivedPriceFeed.bytecode - }${ethers.utils.defaultAbiCoder - .encode( - ["address", "address", "string"], - [nativeOracleAddress, tokenOracleAddress, description] - ) - .slice(2)}`; - - const derivedPriceFeedBComputedAddr = await deployerInstance.addressOf(salt); - console.log( - "Derived Price Feed Computed Address: ", - derivedPriceFeedBComputedAddr - ); - const isContractDeployed = await isContract( - derivedPriceFeedBComputedAddr, - provider - ); - if (!isContractDeployed) { - try { - await deployContract( - feedSalt, - derivedPriceFeedBComputedAddr, - salt, - derivedPriceFeedBytecode, - deployerInstance - ); - await delay(5000); - } catch (err) { - console.log(err); - console.log("issue with the deployment"); - return ethers.constants.AddressZero; - } - try { - await run(`verify:verify`, { - address: derivedPriceFeedBComputedAddr, - constructorArguments: [ - nativeOracleAddress, - tokenOracleAddress, - description, - ], - }); - } catch (err) { - console.log( - "issue with the verification ", - derivedPriceFeedBComputedAddr - ); - return derivedPriceFeedBComputedAddr; - } - } else { - console.log( - "Derived Price Feed is Already deployed with address ", - derivedPriceFeedBComputedAddr - ); - } - return derivedPriceFeedBComputedAddr; -} - -async function setTokenOracle( - oracleAggregatorInstance: ChainlinkOracleAggregator, - tokenAddress: string, - priceFeedAddress: string, - priceFeedDecimals: number, - priceFeedFunctionName: string -) { - const PriceFeedContract = await ethers.getContractAt( - "FeedInterface", - priceFeedAddress - ); - - // Find the function ABI based on the provided function name - const functionAbi = - PriceFeedContract.interface.functions[ - priceFeedFunctionName as keyof typeof PriceFeedContract.functions - ]; - - // Generate the function data based on the function ABI - const functionData = - PriceFeedContract.interface.encodeFunctionData(functionAbi); - - const tx = await oracleAggregatorInstance.setTokenOracle( - tokenAddress, - priceFeedAddress, - priceFeedDecimals, - functionData, - true - ); - const receipt = await tx.wait(); - console.log( - `Oracle set for ${tokenAddress} with tx hash ${receipt.transactionHash}` - ); -} - -/* - * This function is added to support the flow with pre-deploying the deployer contract - * using the `deployer-contract.deploy.ts` script. - */ -async function getPredeployedDeployerContractInstanceDEV(): Promise { - const code = await provider.getCode(DEPLOYER_CONTRACT_ADDRESS_DEV); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Deployer not deployed on chain ${chainId}, deploy it with deployer-contract.deploy.ts script before using this script.` - ); - throw new Error("Deployer not deployed"); - } else { - console.log( - "Deploying with EOA %s through Deployer Contract %s", - signer.address, - DEPLOYER_CONTRACT_ADDRESS_DEV - ); - return Deployer__factory.connect(DEPLOYER_CONTRACT_ADDRESS_DEV, signer); - } -} - -async function getPredeployedDeployerContractInstancePROD(): Promise { - const code = await provider.getCode(DEPLOYER_CONTRACT_ADDRESS_PROD); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Deployer not deployed on chain ${chainId}, deploy it with deployer-contract.deploy.ts script before using this script.` - ); - throw new Error("Deployer not deployed"); - } else { - console.log( - "Deploying with EOA %s through Deployer Contract %s", - signer.address, - DEPLOYER_CONTRACT_ADDRESS_PROD - ); - return Deployer__factory.connect(DEPLOYER_CONTRACT_ADDRESS_PROD, signer); - } -} - -async function getChainlinkOracleAggregatorContractInstance( - oracleAggregatorAddress: string -): Promise { - const code = await provider.getCode(oracleAggregatorAddress); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `ChainlinkOracleAggregator not deployed on chain ${chainId}, It should have been deployed as part of this script.` - ); - throw new Error("ChainlinkOracleAggregator not deployed"); - } else { - console.log( - "Returning instance connected with EOA %s and address %s", - signer.address, - oracleAggregatorAddress - ); - return ChainlinkOracleAggregator__factory.connect( - oracleAggregatorAddress, - signer - ); - } -} - -async function getTokenPaymasterContractInstance( - tokenPaymasterAddress: string -): Promise { - const code = await provider.getCode(tokenPaymasterAddress); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Biconomy Token Paymaster not deployed on chain ${chainId}, It should have been deployed as part of this script.` - ); - throw new Error("Biconomy Token Paymaster not deployed"); - } else { - console.log( - "Returning instance connected with EOA %s and address %s", - signer.address, - tokenPaymasterAddress - ); - return BiconomyTokenPaymaster__factory.connect( - tokenPaymasterAddress, - signer - ); - } -} - -async function main() { - let tx, receipt; - const provider = ethers.provider; - - const accounts = await ethers.getSigners(); - const earlyOwner = await accounts[0].getAddress(); - - const deployerInstanceDEV = await getPredeployedDeployerContractInstanceDEV(); - console.log("========================================="); - - const deployerInstancePROD = - await getPredeployedDeployerContractInstancePROD(); - console.log("========================================="); - - // 1. Deploy Chainlink Oracle Aggregator - // @note: owner is kept the deployer because we need to perform more actions on this contract using owner as part of other scripts - // @note: ownership should be transferred at the end - const oracleAggregatorAddress = await deployChainlinkOracleAggregatorContract( - deployerInstancePROD, - earlyOwner - ); - console.log( - "==================oracleAggregatorAddress=======================", - oracleAggregatorAddress - ); - await delay(5000); - - // 2. Deploy Token paymaster - const tokenPaymasterAddress = await deployTokenPaymasterContract( - deployerInstancePROD, - earlyOwner - ); - console.log( - "==================tokenPaymasterAddress=======================", - tokenPaymasterAddress - ); - await delay(5000); - - let oracleAggregatorInstance; - if (oracleAggregatorAddress) { - oracleAggregatorInstance = - await getChainlinkOracleAggregatorContractInstance( - oracleAggregatorAddress - ); - console.log( - "==================oracleAggregatorInstance=======================" - ); - } - - // 3a. Deploy the derived price feeds for all chainlink supported ERC20 tokens - for (const token of tokenConfig.tokens) { - const { - symbol, - address, - nativeOracleAddress, - tokenOracleAddress, - priceFeedAddress, - description, - priceFeedFunction, - feedSalt, - derivedFeed, - } = token; - let derivedPriceFeedAddress = priceFeedAddress; - - if (derivedPriceFeedAddress == "") { - derivedPriceFeedAddress = await deployDerivedPriceFeed( - deployerInstanceDEV, - nativeOracleAddress, - tokenOracleAddress, - description, - feedSalt - ); - console.log( - `==================${symbol} PriceFeedAddress=======================`, - derivedPriceFeedAddress - ); - await delay(5000); - } - - // Continue with other steps like setting token oracle, transferring ownership, etc. - // Use the derivedPriceFeedAddress and other token-specific information as needed - // ... - - // 4. Set token oracle on oracle aggregator - if (oracleAggregatorInstance) { - let feedAddress = derivedPriceFeedAddress; - if (priceFeedFunction == "latestAnswer()" || derivedFeed == false) { - feedAddress = priceFeedAddress; - } - // TODO - // This should not hardcode tokenOracleDeciamls to 18 - // It works in case of derived price feeds and chainlink feeds which are in the erc20 / native base and quote format. - await setTokenOracle( - oracleAggregatorInstance, - address, - feedAddress, - 18, - priceFeedFunction - ); - } - } - - if (tokenPaymasterAddress) { - // 5b. transfer ownership of token paymaster to the owner - const tokenPaymasterInstance = await getTokenPaymasterContractInstance( - tokenPaymasterAddress - ); - console.log( - "==================tokenPaymasterInstance=======================" - ); - } -} - -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); diff --git a/scripts/deploy-arbitrum-one-mainnet.ts b/scripts/deploy-arbitrum-one-mainnet.ts deleted file mode 100644 index 15f0085..0000000 --- a/scripts/deploy-arbitrum-one-mainnet.ts +++ /dev/null @@ -1,486 +0,0 @@ -import { ethers, run, network } from "hardhat"; -import { arbitrumOneConfigInfoProd } from "./configs"; -import { Token, TokenConfig } from "./utils/Types"; -import { - deployContract, - DEPLOYMENT_SALTS, - encodeParam, - getDeployerInstance, - isContract, -} from "./utils"; -import { - BiconomyTokenPaymaster, - BiconomyTokenPaymaster__factory, - ChainlinkOracleAggregator, - ChainlinkOracleAggregator__factory, - Deployer, - Deployer__factory, -} from "../typechain-types"; - -const tokenConfig: TokenConfig = arbitrumOneConfigInfoProd; - -const provider = ethers.provider; -const entryPointAddress = - process.env.ENTRY_POINT_ADDRESS || - "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789"; -const owner = process.env.PAYMASTER_OWNER_ADDRESS_DEV || ""; -const verifyingSigner = process.env.PAYMASTER_SIGNER_ADDRESS_DEV || ""; -const DEPLOYER_CONTRACT_ADDRESS_DEV = - process.env.DEPLOYER_CONTRACT_ADDRESS_DEV || ""; -const DEPLOYER_CONTRACT_ADDRESS_PROD = - process.env.DEPLOYER_CONTRACT_ADDRESS_PROD || ""; - -function delay(ms: number) { - return new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, ms); - }); -} - -async function deployChainlinkOracleAggregatorContract( - deployerInstance: Deployer, - earlyOwnerAddress: string -): Promise { - const ORACLE_AGGREGATOR_SALT = ethers.utils.keccak256( - ethers.utils.toUtf8Bytes(DEPLOYMENT_SALTS.ORACLE_AGGREGATOR) - ); - - const OracleAggregator = await ethers.getContractFactory( - "ChainlinkOracleAggregator" - ); - const oracleAggregatorBytecode = `${OracleAggregator.bytecode}${encodeParam( - "address", - earlyOwnerAddress - ).slice(2)}`; - const oracleAggregatorComputedAddr = await deployerInstance.addressOf( - ORACLE_AGGREGATOR_SALT - ); - console.log( - "Chainlink Oracle Aggregator Computed Address: ", - oracleAggregatorComputedAddr - ); - - const isOracleAggregatorDeployed = await isContract( - oracleAggregatorComputedAddr, - provider - ); // true (deployed on-chain) - if (!isOracleAggregatorDeployed) { - try { - await deployContract( - DEPLOYMENT_SALTS.ORACLE_AGGREGATOR, - oracleAggregatorComputedAddr, - ORACLE_AGGREGATOR_SALT, - oracleAggregatorBytecode, - deployerInstance - ); - await delay(10000); - } catch (err) { - console.log("issue with the deployment"); - console.log(err); - return ethers.constants.AddressZero; - } - - try { - await run(`verify:verify`, { - address: oracleAggregatorComputedAddr, - constructorArguments: [earlyOwnerAddress], - }); - } catch (err) { - console.log("issue with the verification ", oracleAggregatorComputedAddr); - - return oracleAggregatorComputedAddr; - } - } else { - console.log( - "Chainlink Oracle Aggregator is already deployed with address ", - oracleAggregatorComputedAddr - ); - } - return oracleAggregatorComputedAddr; -} - -async function deployTokenPaymasterContract( - deployerInstance: Deployer, - earlyOwnerAddress: string -): Promise { - const salt = ethers.utils.keccak256( - ethers.utils.toUtf8Bytes(DEPLOYMENT_SALTS.TOKEN_PAYMASTER) - ); - - const BiconomyTokenPaymaster = await ethers.getContractFactory( - "BiconomyTokenPaymaster" - ); - const tokenPaymasterBytecode = `${ - BiconomyTokenPaymaster.bytecode - }${encodeParam("address", earlyOwnerAddress).slice(2)}${encodeParam( - "address", - entryPointAddress - ).slice(2)}${encodeParam("address", verifyingSigner).slice(2)}`; - - const tokenPaymasterComputedAddr = await deployerInstance.addressOf(salt); - console.log("Token paymaster Computed Address: ", tokenPaymasterComputedAddr); - const isContractDeployed = await isContract( - tokenPaymasterComputedAddr, - provider - ); - if (!isContractDeployed) { - try { - await deployContract( - DEPLOYMENT_SALTS.TOKEN_PAYMASTER, - tokenPaymasterComputedAddr, - salt, - tokenPaymasterBytecode, - deployerInstance - ); - await delay(7000); - } catch (err) { - console.log(err); - console.log("issue with the deployment"); - return ethers.constants.AddressZero; - } - try { - await run(`verify:verify`, { - address: tokenPaymasterComputedAddr, - constructorArguments: [ - earlyOwnerAddress, - entryPointAddress, - verifyingSigner, - ], - }); - } catch (err) { - console.log("issue with the verification ", tokenPaymasterComputedAddr); - - return tokenPaymasterComputedAddr; - } - } else { - console.log( - "Token Paymaster is Already deployed with address ", - tokenPaymasterComputedAddr - ); - } - return tokenPaymasterComputedAddr; -} - -async function deployDerivedPriceFeed( - deployerInstance: Deployer, - nativeOracleAddress: string, - tokenOracleAddress: string, - description: string, - feedSalt: string -): Promise { - const salt = ethers.utils.keccak256(ethers.utils.toUtf8Bytes(feedSalt)); - - const DerivedPriceFeed = await ethers.getContractFactory("DerivedPriceFeed"); - - const derivedPriceFeedBytecode = `${ - DerivedPriceFeed.bytecode - }${ethers.utils.defaultAbiCoder - .encode( - ["address", "address", "string"], - [nativeOracleAddress, tokenOracleAddress, description] - ) - .slice(2)}`; - - const derivedPriceFeedBComputedAddr = await deployerInstance.addressOf(salt); - console.log( - "Derived Price Feed Computed Address: ", - derivedPriceFeedBComputedAddr - ); - const isContractDeployed = await isContract( - derivedPriceFeedBComputedAddr, - provider - ); - if (!isContractDeployed) { - try { - await deployContract( - feedSalt, - derivedPriceFeedBComputedAddr, - salt, - derivedPriceFeedBytecode, - deployerInstance - ); - await delay(7000); - } catch (err) { - console.log(err); - console.log("issue with the deployment"); - return ethers.constants.AddressZero; - } - try { - await run(`verify:verify`, { - address: derivedPriceFeedBComputedAddr, - constructorArguments: [ - nativeOracleAddress, - tokenOracleAddress, - description, - ], - }); - } catch (err) { - console.log( - "issue with the verification ", - derivedPriceFeedBComputedAddr - ); - - return derivedPriceFeedBComputedAddr; - } - } else { - console.log( - "Derived Price Feed is Already deployed with address ", - derivedPriceFeedBComputedAddr - ); - } - return derivedPriceFeedBComputedAddr; -} - -async function setTokenOracle( - oracleAggregatorInstance: ChainlinkOracleAggregator, - tokenAddress: string, - priceFeedAddress: string, - priceFeedDecimals: number, - priceFeedFunctionName: string -) { - const PriceFeedContract = await ethers.getContractAt( - "FeedInterface", - priceFeedAddress - ); - - // Find the function ABI based on the provided function name - // @ts-ignore - const functionAbi = - PriceFeedContract.interface.functions[ - priceFeedFunctionName as keyof typeof PriceFeedContract.functions - ]; - - // Generate the function data based on the function ABI - const functionData = - PriceFeedContract.interface.encodeFunctionData(functionAbi); - - const tx = await oracleAggregatorInstance.setTokenOracle( - tokenAddress, - priceFeedAddress, - priceFeedDecimals, - functionData, - true - ); - const receipt = await tx.wait(); - console.log( - `Oracle set for ${tokenAddress} with tx hash ${receipt.transactionHash}` - ); -} - -/* - * This function is added to support the flow with pre-deploying the deployer contract - * using the `deployer-contract.deploy.ts` script. - */ -async function getPredeployedDeployerContractInstanceDEV(): Promise { - const code = await provider.getCode(DEPLOYER_CONTRACT_ADDRESS_DEV); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Deployer not deployed on chain ${chainId}, deploy it with deployer-contract.deploy.ts script before using this script.` - ); - throw new Error("Deployer not deployed"); - } else { - console.log( - "Deploying with EOA %s through Deployer Contract %s", - signer.address, - DEPLOYER_CONTRACT_ADDRESS_DEV - ); - return Deployer__factory.connect(DEPLOYER_CONTRACT_ADDRESS_DEV, signer); - } -} - -async function getPredeployedDeployerContractInstancePROD(): Promise { - const code = await provider.getCode(DEPLOYER_CONTRACT_ADDRESS_PROD); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Deployer not deployed on chain ${chainId}, deploy it with deployer-contract.deploy.ts script before using this script.` - ); - throw new Error("Deployer not deployed"); - } else { - console.log( - "Deploying with EOA %s through Deployer Contract %s", - signer.address, - DEPLOYER_CONTRACT_ADDRESS_PROD - ); - return Deployer__factory.connect(DEPLOYER_CONTRACT_ADDRESS_PROD, signer); - } -} - -async function getChainlinkOracleAggregatorContractInstance( - oracleAggregatorAddress: string -): Promise { - const code = await provider.getCode(oracleAggregatorAddress); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `ChainlinkOracleAggregator not deployed on chain ${chainId}, It should have been deployed as part of this script.` - ); - throw new Error("ChainlinkOracleAggregator not deployed"); - } else { - console.log( - "Returning instance connected with EOA %s and address %s", - signer.address, - oracleAggregatorAddress - ); - return ChainlinkOracleAggregator__factory.connect( - oracleAggregatorAddress, - signer - ); - } -} - -async function getTokenPaymasterContractInstance( - tokenPaymasterAddress: string -): Promise { - const code = await provider.getCode(tokenPaymasterAddress); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Biconomy Token Paymaster not deployed on chain ${chainId}, It should have been deployed as part of this script.` - ); - throw new Error("Biconomy Token Paymaster not deployed"); - } else { - console.log( - "Returning instance connected with EOA %s and address %s", - signer.address, - tokenPaymasterAddress - ); - return BiconomyTokenPaymaster__factory.connect( - tokenPaymasterAddress, - signer - ); - } -} - -async function main() { - let tx, receipt; - const provider = ethers.provider; - - const accounts = await ethers.getSigners(); - const earlyOwner = await accounts[0].getAddress(); - - const deployerInstanceDEV = await getPredeployedDeployerContractInstanceDEV(); - console.log("========================================="); - - const deployerInstancePROD = - await getPredeployedDeployerContractInstancePROD(); - console.log("========================================="); - - // 1. Deploy Chainlink Oracle Aggregator - // @note: owner is kept the deployer because we need to perform more actions on this contract using owner as part of other scripts - // @note: ownership should be transferred at the end - const oracleAggregatorAddress = await deployChainlinkOracleAggregatorContract( - deployerInstancePROD, - earlyOwner - ); - console.log( - "==================oracleAggregatorAddress=======================", - oracleAggregatorAddress - ); - await delay(7000); - - // 2. Deploy Token paymaster - const tokenPaymasterAddress = await deployTokenPaymasterContract( - deployerInstancePROD, - earlyOwner - ); - console.log( - "==================tokenPaymasterAddress=======================", - tokenPaymasterAddress - ); - await delay(7000); - - let oracleAggregatorInstance; - if (oracleAggregatorAddress) { - oracleAggregatorInstance = - await getChainlinkOracleAggregatorContractInstance( - oracleAggregatorAddress - ); - console.log( - "==================oracleAggregatorInstance=======================" - ); - } - - // 3a. Deploy the derived price feeds for all chainlink supported ERC20 tokens - for (const token of tokenConfig.tokens) { - const { - symbol, - address, - nativeOracleAddress, - tokenOracleAddress, - priceFeedAddress, - description, - priceFeedFunction, - feedSalt, - derivedFeed, - } = token; - let derivedPriceFeedAddress = priceFeedAddress; - console.log( - `derived price feed address for token ${symbol} is ${derivedPriceFeedAddress}` - ); - - if (derivedPriceFeedAddress == "") { - derivedPriceFeedAddress = await deployDerivedPriceFeed( - deployerInstanceDEV, - nativeOracleAddress, - tokenOracleAddress, - description, - feedSalt - ); - console.log( - `==================${symbol} PriceFeedAddress=======================`, - derivedPriceFeedAddress - ); - await delay(7000); - } - - // Continue with other steps like setting token oracle, transferring ownership, etc. - // Use the derivedPriceFeedAddress and other token-specific information as needed - // ... - - // 4. Set token oracle on oracle aggregator - if (oracleAggregatorInstance) { - let feedAddress = derivedPriceFeedAddress; - if (priceFeedFunction == "latestAnswer()" || derivedFeed == false) { - feedAddress = priceFeedAddress; - } - // TODO - // This should not hardcode tokenOracleDeciamls to 18 - // It works in case of derived price feeds and chainlink feeds which are in the erc20 / native base and quote format. - await setTokenOracle( - oracleAggregatorInstance, - address, - feedAddress, - 18, - priceFeedFunction - ); - } - } - - if (tokenPaymasterAddress) { - // 5b. transfer ownership of token paymaster to the owner - const tokenPaymasterInstance = await getTokenPaymasterContractInstance( - tokenPaymasterAddress - ); - console.log( - "==================tokenPaymasterInstance=======================" - ); - - - } -} - -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); diff --git a/scripts/deploy-avalanche-mainnet.ts b/scripts/deploy-avalanche-mainnet.ts deleted file mode 100644 index ca21dff..0000000 --- a/scripts/deploy-avalanche-mainnet.ts +++ /dev/null @@ -1,483 +0,0 @@ -import { ethers, run, network } from "hardhat"; -import { avalancheMainnetConfigInfoProd } from "./configs"; -import { Token, TokenConfig } from "./utils/Types"; -import { - deployContract, - DEPLOYMENT_SALTS, - encodeParam, - getDeployerInstance, - isContract, -} from "./utils"; -import { - BiconomyTokenPaymaster, - BiconomyTokenPaymaster__factory, - ChainlinkOracleAggregator, - ChainlinkOracleAggregator__factory, - Deployer, - Deployer__factory, -} from "../typechain-types"; - -const tokenConfig: TokenConfig = avalancheMainnetConfigInfoProd; - -const provider = ethers.provider; -const entryPointAddress = - process.env.ENTRY_POINT_ADDRESS || - "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789"; -const owner = process.env.PAYMASTER_OWNER_ADDRESS_DEV || ""; -const verifyingSigner = process.env.PAYMASTER_SIGNER_ADDRESS_DEV || ""; -const DEPLOYER_CONTRACT_ADDRESS_DEV = - process.env.DEPLOYER_CONTRACT_ADDRESS_DEV || ""; -const DEPLOYER_CONTRACT_ADDRESS_PROD = - process.env.DEPLOYER_CONTRACT_ADDRESS_PROD || ""; - -function delay(ms: number) { - return new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, ms); - }); -} - -async function deployChainlinkOracleAggregatorContract( - deployerInstance: Deployer, - earlyOwnerAddress: string -): Promise { - const ORACLE_AGGREGATOR_SALT = ethers.utils.keccak256( - ethers.utils.toUtf8Bytes(DEPLOYMENT_SALTS.ORACLE_AGGREGATOR) - ); - - const OracleAggregator = await ethers.getContractFactory( - "ChainlinkOracleAggregator" - ); - const oracleAggregatorBytecode = `${OracleAggregator.bytecode}${encodeParam( - "address", - earlyOwnerAddress - ).slice(2)}`; - const oracleAggregatorComputedAddr = await deployerInstance.addressOf( - ORACLE_AGGREGATOR_SALT - ); - console.log( - "Chainlink Oracle Aggregator Computed Address: ", - oracleAggregatorComputedAddr - ); - - const isOracleAggregatorDeployed = await isContract( - oracleAggregatorComputedAddr, - provider - ); // true (deployed on-chain) - if (!isOracleAggregatorDeployed) { - try { - await deployContract( - DEPLOYMENT_SALTS.ORACLE_AGGREGATOR, - oracleAggregatorComputedAddr, - ORACLE_AGGREGATOR_SALT, - oracleAggregatorBytecode, - deployerInstance - ); - await delay(10000); - } catch (err) { - console.log("issue with the deployment"); - console.log(err); - return ethers.constants.AddressZero; - } - - try { - await run(`verify:verify`, { - address: oracleAggregatorComputedAddr, - constructorArguments: [earlyOwnerAddress], - }); - } catch (err) { - console.log("issue with the verification ", oracleAggregatorComputedAddr); - - return oracleAggregatorComputedAddr; - } - } else { - console.log( - "Chainlink Oracle Aggregator is already deployed with address ", - oracleAggregatorComputedAddr - ); - } - return oracleAggregatorComputedAddr; -} - -async function deployTokenPaymasterContract( - deployerInstance: Deployer, - earlyOwnerAddress: string -): Promise { - const salt = ethers.utils.keccak256( - ethers.utils.toUtf8Bytes(DEPLOYMENT_SALTS.TOKEN_PAYMASTER) - ); - - const BiconomyTokenPaymaster = await ethers.getContractFactory( - "BiconomyTokenPaymaster" - ); - const tokenPaymasterBytecode = `${ - BiconomyTokenPaymaster.bytecode - }${encodeParam("address", earlyOwnerAddress).slice(2)}${encodeParam( - "address", - entryPointAddress - ).slice(2)}${encodeParam("address", verifyingSigner).slice(2)}`; - - const tokenPaymasterComputedAddr = await deployerInstance.addressOf(salt); - console.log("Token paymaster Computed Address: ", tokenPaymasterComputedAddr); - const isContractDeployed = await isContract( - tokenPaymasterComputedAddr, - provider - ); - if (!isContractDeployed) { - try { - await deployContract( - DEPLOYMENT_SALTS.TOKEN_PAYMASTER, - tokenPaymasterComputedAddr, - salt, - tokenPaymasterBytecode, - deployerInstance - ); - await delay(5000); - } catch (err) { - console.log(err); - console.log("issue with the deployment"); - return ethers.constants.AddressZero; - } - try { - await run(`verify:verify`, { - address: tokenPaymasterComputedAddr, - constructorArguments: [ - earlyOwnerAddress, - entryPointAddress, - verifyingSigner, - ], - }); - } catch (err) { - console.log("issue with the verification ", tokenPaymasterComputedAddr); - - return tokenPaymasterComputedAddr; - } - } else { - console.log( - "Token Paymaster is Already deployed with address ", - tokenPaymasterComputedAddr - ); - } - return tokenPaymasterComputedAddr; -} - -async function deployDerivedPriceFeed( - deployerInstance: Deployer, - nativeOracleAddress: string, - tokenOracleAddress: string, - description: string, - feedSalt: string -): Promise { - const salt = ethers.utils.keccak256(ethers.utils.toUtf8Bytes(feedSalt)); - - const DerivedPriceFeed = await ethers.getContractFactory("DerivedPriceFeed"); - - const derivedPriceFeedBytecode = `${ - DerivedPriceFeed.bytecode - }${ethers.utils.defaultAbiCoder - .encode( - ["address", "address", "string"], - [nativeOracleAddress, tokenOracleAddress, description] - ) - .slice(2)}`; - - const derivedPriceFeedBComputedAddr = await deployerInstance.addressOf(salt); - console.log( - "Derived Price Feed Computed Address: ", - derivedPriceFeedBComputedAddr - ); - const isContractDeployed = await isContract( - derivedPriceFeedBComputedAddr, - provider - ); - if (!isContractDeployed) { - try { - await deployContract( - feedSalt, - derivedPriceFeedBComputedAddr, - salt, - derivedPriceFeedBytecode, - deployerInstance - ); - await delay(5000); - } catch (err) { - console.log(err); - console.log("issue with the deployment"); - return ethers.constants.AddressZero; - } - try { - await run(`verify:verify`, { - address: derivedPriceFeedBComputedAddr, - constructorArguments: [ - nativeOracleAddress, - tokenOracleAddress, - description, - ], - }); - } catch (err) { - console.log( - "issue with the verification ", - derivedPriceFeedBComputedAddr - ); - - return derivedPriceFeedBComputedAddr; - } - } else { - console.log( - "Derived Price Feed is Already deployed with address ", - derivedPriceFeedBComputedAddr - ); - } - return derivedPriceFeedBComputedAddr; -} - -async function setTokenOracle( - oracleAggregatorInstance: ChainlinkOracleAggregator, - tokenAddress: string, - priceFeedAddress: string, - priceFeedDecimals: number, - priceFeedFunctionName: string -) { - const PriceFeedContract = await ethers.getContractAt( - "FeedInterface", - priceFeedAddress - ); - - // Find the function ABI based on the provided function name - // @ts-ignore - const functionAbi = - PriceFeedContract.interface.functions[ - priceFeedFunctionName as keyof typeof PriceFeedContract.functions - ]; - - // Generate the function data based on the function ABI - const functionData = - PriceFeedContract.interface.encodeFunctionData(functionAbi); - - const tx = await oracleAggregatorInstance.setTokenOracle( - tokenAddress, - priceFeedAddress, - priceFeedDecimals, - functionData, - true - ); - const receipt = await tx.wait(); - console.log( - `Oracle set for ${tokenAddress} with tx hash ${receipt.transactionHash}` - ); -} - -/* - * This function is added to support the flow with pre-deploying the deployer contract - * using the `deployer-contract.deploy.ts` script. - */ -async function getPredeployedDeployerContractInstanceDEV(): Promise { - const code = await provider.getCode(DEPLOYER_CONTRACT_ADDRESS_DEV); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Deployer not deployed on chain ${chainId}, deploy it with deployer-contract.deploy.ts script before using this script.` - ); - throw new Error("Deployer not deployed"); - } else { - console.log( - "Deploying with EOA %s through Deployer Contract %s", - signer.address, - DEPLOYER_CONTRACT_ADDRESS_DEV - ); - return Deployer__factory.connect(DEPLOYER_CONTRACT_ADDRESS_DEV, signer); - } -} - -async function getPredeployedDeployerContractInstancePROD(): Promise { - const code = await provider.getCode(DEPLOYER_CONTRACT_ADDRESS_PROD); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Deployer not deployed on chain ${chainId}, deploy it with deployer-contract.deploy.ts script before using this script.` - ); - throw new Error("Deployer not deployed"); - } else { - console.log( - "Deploying with EOA %s through Deployer Contract %s", - signer.address, - DEPLOYER_CONTRACT_ADDRESS_PROD - ); - return Deployer__factory.connect(DEPLOYER_CONTRACT_ADDRESS_PROD, signer); - } -} - -async function getChainlinkOracleAggregatorContractInstance( - oracleAggregatorAddress: string -): Promise { - const code = await provider.getCode(oracleAggregatorAddress); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `ChainlinkOracleAggregator not deployed on chain ${chainId}, It should have been deployed as part of this script.` - ); - throw new Error("ChainlinkOracleAggregator not deployed"); - } else { - console.log( - "Returning instance connected with EOA %s and address %s", - signer.address, - oracleAggregatorAddress - ); - return ChainlinkOracleAggregator__factory.connect( - oracleAggregatorAddress, - signer - ); - } -} - -async function getTokenPaymasterContractInstance( - tokenPaymasterAddress: string -): Promise { - const code = await provider.getCode(tokenPaymasterAddress); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Biconomy Token Paymaster not deployed on chain ${chainId}, It should have been deployed as part of this script.` - ); - throw new Error("Biconomy Token Paymaster not deployed"); - } else { - console.log( - "Returning instance connected with EOA %s and address %s", - signer.address, - tokenPaymasterAddress - ); - return BiconomyTokenPaymaster__factory.connect( - tokenPaymasterAddress, - signer - ); - } -} - -async function main() { - let tx, receipt; - const provider = ethers.provider; - - const accounts = await ethers.getSigners(); - const earlyOwner = await accounts[0].getAddress(); - - const deployerInstanceDEV = await getPredeployedDeployerContractInstanceDEV(); - console.log("========================================="); - - const deployerInstancePROD = - await getPredeployedDeployerContractInstancePROD(); - console.log("========================================="); - - // 1. Deploy Chainlink Oracle Aggregator - // @note: owner is kept the deployer because we need to perform more actions on this contract using owner as part of other scripts - // @note: ownership should be transferred at the end - const oracleAggregatorAddress = await deployChainlinkOracleAggregatorContract( - deployerInstancePROD, - earlyOwner - ); - console.log( - "==================oracleAggregatorAddress=======================", - oracleAggregatorAddress - ); - await delay(5000); - - // 2. Deploy Token paymaster - const tokenPaymasterAddress = await deployTokenPaymasterContract( - deployerInstancePROD, - earlyOwner - ); - console.log( - "==================tokenPaymasterAddress=======================", - tokenPaymasterAddress - ); - await delay(5000); - - let oracleAggregatorInstance; - if (oracleAggregatorAddress) { - oracleAggregatorInstance = - await getChainlinkOracleAggregatorContractInstance( - oracleAggregatorAddress - ); - console.log( - "==================oracleAggregatorInstance=======================" - ); - } - - // 3a. Deploy the derived price feeds for all chainlink supported ERC20 tokens - for (const token of tokenConfig.tokens) { - const { - symbol, - address, - nativeOracleAddress, - tokenOracleAddress, - priceFeedAddress, - description, - priceFeedFunction, - feedSalt, - derivedFeed, - } = token; - let derivedPriceFeedAddress = priceFeedAddress; - - if (derivedPriceFeedAddress == "") { - derivedPriceFeedAddress = await deployDerivedPriceFeed( - deployerInstanceDEV, - nativeOracleAddress, - tokenOracleAddress, - description, - feedSalt - ); - console.log( - `==================${symbol} PriceFeedAddress=======================`, - derivedPriceFeedAddress - ); - await delay(5000); - } - - // Continue with other steps like setting token oracle, transferring ownership, etc. - // Use the derivedPriceFeedAddress and other token-specific information as needed - // ... - - // 4. Set token oracle on oracle aggregator - if (oracleAggregatorInstance) { - let feedAddress = derivedPriceFeedAddress; - if (priceFeedFunction == "latestAnswer()" || derivedFeed == false) { - feedAddress = priceFeedAddress; - } - // TODO - // This should not hardcode tokenOracleDeciamls to 18 - // It works in case of derived price feeds and chainlink feeds which are in the erc20 / native base and quote format. - await setTokenOracle( - oracleAggregatorInstance, - address, - feedAddress, - 18, - priceFeedFunction - ); - } - } - - if (tokenPaymasterAddress) { - // 5b. transfer ownership of token paymaster to the owner - const tokenPaymasterInstance = await getTokenPaymasterContractInstance( - tokenPaymasterAddress - ); - console.log( - "==================tokenPaymasterInstance=======================" - ); - - - } -} - -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); diff --git a/scripts/deploy-avalanche-testnet.ts b/scripts/deploy-avalanche-testnet.ts deleted file mode 100644 index c86603f..0000000 --- a/scripts/deploy-avalanche-testnet.ts +++ /dev/null @@ -1,483 +0,0 @@ -import { ethers, run, network } from "hardhat"; -import { avalancheFujiConfigInfoProd } from "./configs"; -import { Token, TokenConfig } from "./utils/Types"; -import { - deployContract, - DEPLOYMENT_SALTS, - encodeParam, - getDeployerInstance, - isContract, -} from "./utils"; -import { - BiconomyTokenPaymaster, - BiconomyTokenPaymaster__factory, - ChainlinkOracleAggregator, - ChainlinkOracleAggregator__factory, - Deployer, - Deployer__factory, -} from "../typechain-types"; - -const tokenConfig: TokenConfig = avalancheFujiConfigInfoProd; - -const provider = ethers.provider; -const entryPointAddress = - process.env.ENTRY_POINT_ADDRESS || - "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789"; -const owner = process.env.PAYMASTER_OWNER_ADDRESS_DEV || ""; -const verifyingSigner = process.env.PAYMASTER_SIGNER_ADDRESS_DEV || ""; -const DEPLOYER_CONTRACT_ADDRESS_DEV = - process.env.DEPLOYER_CONTRACT_ADDRESS_DEV || ""; -const DEPLOYER_CONTRACT_ADDRESS_PROD = - process.env.DEPLOYER_CONTRACT_ADDRESS_PROD || ""; - -function delay(ms: number) { - return new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, ms); - }); -} - -async function deployChainlinkOracleAggregatorContract( - deployerInstance: Deployer, - earlyOwnerAddress: string -): Promise { - const ORACLE_AGGREGATOR_SALT = ethers.utils.keccak256( - ethers.utils.toUtf8Bytes(DEPLOYMENT_SALTS.ORACLE_AGGREGATOR) - ); - - const OracleAggregator = await ethers.getContractFactory( - "ChainlinkOracleAggregator" - ); - const oracleAggregatorBytecode = `${OracleAggregator.bytecode}${encodeParam( - "address", - earlyOwnerAddress - ).slice(2)}`; - const oracleAggregatorComputedAddr = await deployerInstance.addressOf( - ORACLE_AGGREGATOR_SALT - ); - console.log( - "Chainlink Oracle Aggregator Computed Address: ", - oracleAggregatorComputedAddr - ); - - const isOracleAggregatorDeployed = await isContract( - oracleAggregatorComputedAddr, - provider - ); // true (deployed on-chain) - if (!isOracleAggregatorDeployed) { - try { - await deployContract( - DEPLOYMENT_SALTS.ORACLE_AGGREGATOR, - oracleAggregatorComputedAddr, - ORACLE_AGGREGATOR_SALT, - oracleAggregatorBytecode, - deployerInstance - ); - await delay(10000); - } catch (err) { - console.log("issue with the deployment"); - console.log(err); - return ethers.constants.AddressZero; - } - - try { - await run(`verify:verify`, { - address: oracleAggregatorComputedAddr, - constructorArguments: [earlyOwnerAddress], - }); - } catch (err) { - console.log("issue with the verification ", oracleAggregatorComputedAddr); - - return oracleAggregatorComputedAddr; - } - } else { - console.log( - "Chainlink Oracle Aggregator is already deployed with address ", - oracleAggregatorComputedAddr - ); - } - return oracleAggregatorComputedAddr; -} - -async function deployTokenPaymasterContract( - deployerInstance: Deployer, - earlyOwnerAddress: string -): Promise { - const salt = ethers.utils.keccak256( - ethers.utils.toUtf8Bytes(DEPLOYMENT_SALTS.TOKEN_PAYMASTER) - ); - - const BiconomyTokenPaymaster = await ethers.getContractFactory( - "BiconomyTokenPaymaster" - ); - const tokenPaymasterBytecode = `${ - BiconomyTokenPaymaster.bytecode - }${encodeParam("address", earlyOwnerAddress).slice(2)}${encodeParam( - "address", - entryPointAddress - ).slice(2)}${encodeParam("address", verifyingSigner).slice(2)}`; - - const tokenPaymasterComputedAddr = await deployerInstance.addressOf(salt); - console.log("Token paymaster Computed Address: ", tokenPaymasterComputedAddr); - const isContractDeployed = await isContract( - tokenPaymasterComputedAddr, - provider - ); - if (!isContractDeployed) { - try { - await deployContract( - DEPLOYMENT_SALTS.TOKEN_PAYMASTER, - tokenPaymasterComputedAddr, - salt, - tokenPaymasterBytecode, - deployerInstance - ); - await delay(5000); - } catch (err) { - console.log(err); - console.log("issue with the deployment"); - return ethers.constants.AddressZero; - } - try { - await run(`verify:verify`, { - address: tokenPaymasterComputedAddr, - constructorArguments: [ - earlyOwnerAddress, - entryPointAddress, - verifyingSigner, - ], - }); - } catch (err) { - console.log("issue with the verification ", tokenPaymasterComputedAddr); - - return tokenPaymasterComputedAddr; - } - } else { - console.log( - "Token Paymaster is Already deployed with address ", - tokenPaymasterComputedAddr - ); - } - return tokenPaymasterComputedAddr; -} - -async function deployDerivedPriceFeed( - deployerInstance: Deployer, - nativeOracleAddress: string, - tokenOracleAddress: string, - description: string, - feedSalt: string -): Promise { - const salt = ethers.utils.keccak256(ethers.utils.toUtf8Bytes(feedSalt)); - - const DerivedPriceFeed = await ethers.getContractFactory("DerivedPriceFeed"); - - const derivedPriceFeedBytecode = `${ - DerivedPriceFeed.bytecode - }${ethers.utils.defaultAbiCoder - .encode( - ["address", "address", "string"], - [nativeOracleAddress, tokenOracleAddress, description] - ) - .slice(2)}`; - - const derivedPriceFeedBComputedAddr = await deployerInstance.addressOf(salt); - console.log( - "Derived Price Feed Computed Address: ", - derivedPriceFeedBComputedAddr - ); - const isContractDeployed = await isContract( - derivedPriceFeedBComputedAddr, - provider - ); - if (!isContractDeployed) { - try { - await deployContract( - feedSalt, - derivedPriceFeedBComputedAddr, - salt, - derivedPriceFeedBytecode, - deployerInstance - ); - await delay(5000); - } catch (err) { - console.log(err); - console.log("issue with the deployment"); - return ethers.constants.AddressZero; - } - try { - await run(`verify:verify`, { - address: derivedPriceFeedBComputedAddr, - constructorArguments: [ - nativeOracleAddress, - tokenOracleAddress, - description, - ], - }); - } catch (err) { - console.log( - "issue with the verification ", - derivedPriceFeedBComputedAddr - ); - - return derivedPriceFeedBComputedAddr; - } - } else { - console.log( - "Derived Price Feed is Already deployed with address ", - derivedPriceFeedBComputedAddr - ); - } - return derivedPriceFeedBComputedAddr; -} - -async function setTokenOracle( - oracleAggregatorInstance: ChainlinkOracleAggregator, - tokenAddress: string, - priceFeedAddress: string, - priceFeedDecimals: number, - priceFeedFunctionName: string -) { - const PriceFeedContract = await ethers.getContractAt( - "FeedInterface", - priceFeedAddress - ); - - // Find the function ABI based on the provided function name - // @ts-ignore - const functionAbi = - PriceFeedContract.interface.functions[ - priceFeedFunctionName as keyof typeof PriceFeedContract.functions - ]; - - // Generate the function data based on the function ABI - const functionData = - PriceFeedContract.interface.encodeFunctionData(functionAbi); - - const tx = await oracleAggregatorInstance.setTokenOracle( - tokenAddress, - priceFeedAddress, - priceFeedDecimals, - functionData, - true - ); - const receipt = await tx.wait(); - console.log( - `Oracle set for ${tokenAddress} with tx hash ${receipt.transactionHash}` - ); -} - -/* - * This function is added to support the flow with pre-deploying the deployer contract - * using the `deployer-contract.deploy.ts` script. - */ -async function getPredeployedDeployerContractInstanceDEV(): Promise { - const code = await provider.getCode(DEPLOYER_CONTRACT_ADDRESS_DEV); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Deployer not deployed on chain ${chainId}, deploy it with deployer-contract.deploy.ts script before using this script.` - ); - throw new Error("Deployer not deployed"); - } else { - console.log( - "Deploying with EOA %s through Deployer Contract %s", - signer.address, - DEPLOYER_CONTRACT_ADDRESS_DEV - ); - return Deployer__factory.connect(DEPLOYER_CONTRACT_ADDRESS_DEV, signer); - } -} - -async function getPredeployedDeployerContractInstancePROD(): Promise { - const code = await provider.getCode(DEPLOYER_CONTRACT_ADDRESS_PROD); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Deployer not deployed on chain ${chainId}, deploy it with deployer-contract.deploy.ts script before using this script.` - ); - throw new Error("Deployer not deployed"); - } else { - console.log( - "Deploying with EOA %s through Deployer Contract %s", - signer.address, - DEPLOYER_CONTRACT_ADDRESS_PROD - ); - return Deployer__factory.connect(DEPLOYER_CONTRACT_ADDRESS_PROD, signer); - } -} - -async function getChainlinkOracleAggregatorContractInstance( - oracleAggregatorAddress: string -): Promise { - const code = await provider.getCode(oracleAggregatorAddress); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `ChainlinkOracleAggregator not deployed on chain ${chainId}, It should have been deployed as part of this script.` - ); - throw new Error("ChainlinkOracleAggregator not deployed"); - } else { - console.log( - "Returning instance connected with EOA %s and address %s", - signer.address, - oracleAggregatorAddress - ); - return ChainlinkOracleAggregator__factory.connect( - oracleAggregatorAddress, - signer - ); - } -} - -async function getTokenPaymasterContractInstance( - tokenPaymasterAddress: string -): Promise { - const code = await provider.getCode(tokenPaymasterAddress); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Biconomy Token Paymaster not deployed on chain ${chainId}, It should have been deployed as part of this script.` - ); - throw new Error("Biconomy Token Paymaster not deployed"); - } else { - console.log( - "Returning instance connected with EOA %s and address %s", - signer.address, - tokenPaymasterAddress - ); - return BiconomyTokenPaymaster__factory.connect( - tokenPaymasterAddress, - signer - ); - } -} - -async function main() { - let tx, receipt; - const provider = ethers.provider; - - const accounts = await ethers.getSigners(); - const earlyOwner = await accounts[0].getAddress(); - - const deployerInstanceDEV = await getPredeployedDeployerContractInstanceDEV(); - console.log("========================================="); - - const deployerInstancePROD = - await getPredeployedDeployerContractInstancePROD(); - console.log("========================================="); - - // 1. Deploy Chainlink Oracle Aggregator - // @note: owner is kept the deployer because we need to perform more actions on this contract using owner as part of other scripts - // @note: ownership should be transferred at the end - const oracleAggregatorAddress = await deployChainlinkOracleAggregatorContract( - deployerInstancePROD, - earlyOwner - ); - console.log( - "==================oracleAggregatorAddress=======================", - oracleAggregatorAddress - ); - await delay(5000); - - // 2. Deploy Token paymaster - const tokenPaymasterAddress = await deployTokenPaymasterContract( - deployerInstancePROD, - earlyOwner - ); - console.log( - "==================tokenPaymasterAddress=======================", - tokenPaymasterAddress - ); - await delay(5000); - - let oracleAggregatorInstance; - if (oracleAggregatorAddress) { - oracleAggregatorInstance = - await getChainlinkOracleAggregatorContractInstance( - oracleAggregatorAddress - ); - console.log( - "==================oracleAggregatorInstance=======================" - ); - } - - // 3a. Deploy the derived price feeds for all chainlink supported ERC20 tokens - for (const token of tokenConfig.tokens) { - const { - symbol, - address, - nativeOracleAddress, - tokenOracleAddress, - priceFeedAddress, - description, - priceFeedFunction, - feedSalt, - derivedFeed, - } = token; - let derivedPriceFeedAddress = priceFeedAddress; - - if (derivedPriceFeedAddress == "") { - derivedPriceFeedAddress = await deployDerivedPriceFeed( - deployerInstanceDEV, - nativeOracleAddress, - tokenOracleAddress, - description, - feedSalt - ); - console.log( - `==================${symbol} PriceFeedAddress=======================`, - derivedPriceFeedAddress - ); - await delay(5000); - } - - // Continue with other steps like setting token oracle, transferring ownership, etc. - // Use the derivedPriceFeedAddress and other token-specific information as needed - // ... - - // 4. Set token oracle on oracle aggregator - if (oracleAggregatorInstance) { - let feedAddress = derivedPriceFeedAddress; - if (priceFeedFunction == "latestAnswer()" || derivedFeed == false) { - feedAddress = priceFeedAddress; - } - // TODO - // This should not hardcode tokenOracleDeciamls to 18 - // It works in case of derived price feeds and chainlink feeds which are in the erc20 / native base and quote format. - await setTokenOracle( - oracleAggregatorInstance, - address, - feedAddress, - 18, - priceFeedFunction - ); - } - } - - if (tokenPaymasterAddress) { - // 5b. transfer ownership of token paymaster to the owner - const tokenPaymasterInstance = await getTokenPaymasterContractInstance( - tokenPaymasterAddress - ); - console.log( - "==================tokenPaymasterInstance=======================" - ); - - - } -} - -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); diff --git a/scripts/deploy-base-goerli.ts b/scripts/deploy-base-goerli.ts deleted file mode 100644 index 79a01a7..0000000 --- a/scripts/deploy-base-goerli.ts +++ /dev/null @@ -1,483 +0,0 @@ -import { ethers, run, network } from "hardhat"; -import { baseGoerliConfigInfoProd } from "./configs"; -import { Token, TokenConfig } from "./utils/Types"; -import { - deployContract, - DEPLOYMENT_SALTS, - encodeParam, - getDeployerInstance, - isContract, -} from "./utils"; -import { - BiconomyTokenPaymaster, - BiconomyTokenPaymaster__factory, - ChainlinkOracleAggregator, - ChainlinkOracleAggregator__factory, - Deployer, - Deployer__factory, -} from "../typechain-types"; - -const tokenConfig: TokenConfig = baseGoerliConfigInfoProd; - -const provider = ethers.provider; -const entryPointAddress = - process.env.ENTRY_POINT_ADDRESS || - "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789"; -const owner = process.env.PAYMASTER_OWNER_ADDRESS_DEV || ""; -const verifyingSigner = process.env.PAYMASTER_SIGNER_ADDRESS_DEV || ""; -const DEPLOYER_CONTRACT_ADDRESS_DEV = - process.env.DEPLOYER_CONTRACT_ADDRESS_DEV || ""; -const DEPLOYER_CONTRACT_ADDRESS_PROD = - process.env.DEPLOYER_CONTRACT_ADDRESS_PROD || ""; - -function delay(ms: number) { - return new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, ms); - }); -} - -async function deployChainlinkOracleAggregatorContract( - deployerInstance: Deployer, - earlyOwnerAddress: string -): Promise { - const ORACLE_AGGREGATOR_SALT = ethers.utils.keccak256( - ethers.utils.toUtf8Bytes(DEPLOYMENT_SALTS.ORACLE_AGGREGATOR) - ); - - const OracleAggregator = await ethers.getContractFactory( - "ChainlinkOracleAggregator" - ); - const oracleAggregatorBytecode = `${OracleAggregator.bytecode}${encodeParam( - "address", - earlyOwnerAddress - ).slice(2)}`; - const oracleAggregatorComputedAddr = await deployerInstance.addressOf( - ORACLE_AGGREGATOR_SALT - ); - console.log( - "Chainlink Oracle Aggregator Computed Address: ", - oracleAggregatorComputedAddr - ); - - const isOracleAggregatorDeployed = await isContract( - oracleAggregatorComputedAddr, - provider - ); // true (deployed on-chain) - if (!isOracleAggregatorDeployed) { - try { - await deployContract( - DEPLOYMENT_SALTS.ORACLE_AGGREGATOR, - oracleAggregatorComputedAddr, - ORACLE_AGGREGATOR_SALT, - oracleAggregatorBytecode, - deployerInstance - ); - await delay(10000); - } catch (err) { - console.log("issue with the deployment"); - console.log(err); - return ethers.constants.AddressZero; - } - - try { - await run(`verify:verify`, { - address: oracleAggregatorComputedAddr, - constructorArguments: [earlyOwnerAddress], - }); - } catch (err) { - console.log("issue with the verification ", oracleAggregatorComputedAddr); - - return oracleAggregatorComputedAddr; - } - } else { - console.log( - "Chainlink Oracle Aggregator is already deployed with address ", - oracleAggregatorComputedAddr - ); - } - return oracleAggregatorComputedAddr; -} - -async function deployTokenPaymasterContract( - deployerInstance: Deployer, - earlyOwnerAddress: string -): Promise { - const salt = ethers.utils.keccak256( - ethers.utils.toUtf8Bytes(DEPLOYMENT_SALTS.TOKEN_PAYMASTER) - ); - - const BiconomyTokenPaymaster = await ethers.getContractFactory( - "BiconomyTokenPaymaster" - ); - const tokenPaymasterBytecode = `${ - BiconomyTokenPaymaster.bytecode - }${encodeParam("address", earlyOwnerAddress).slice(2)}${encodeParam( - "address", - entryPointAddress - ).slice(2)}${encodeParam("address", verifyingSigner).slice(2)}`; - - const tokenPaymasterComputedAddr = await deployerInstance.addressOf(salt); - console.log("Token paymaster Computed Address: ", tokenPaymasterComputedAddr); - const isContractDeployed = await isContract( - tokenPaymasterComputedAddr, - provider - ); - if (!isContractDeployed) { - try { - await deployContract( - DEPLOYMENT_SALTS.TOKEN_PAYMASTER, - tokenPaymasterComputedAddr, - salt, - tokenPaymasterBytecode, - deployerInstance - ); - await delay(5000); - } catch (err) { - console.log(err); - console.log("issue with the deployment"); - return ethers.constants.AddressZero; - } - try { - await run(`verify:verify`, { - address: tokenPaymasterComputedAddr, - constructorArguments: [ - earlyOwnerAddress, - entryPointAddress, - verifyingSigner, - ], - }); - } catch (err) { - console.log("issue with the verification ", tokenPaymasterComputedAddr); - - return tokenPaymasterComputedAddr; - } - } else { - console.log( - "Token Paymaster is Already deployed with address ", - tokenPaymasterComputedAddr - ); - } - return tokenPaymasterComputedAddr; -} - -async function deployDerivedPriceFeed( - deployerInstance: Deployer, - nativeOracleAddress: string, - tokenOracleAddress: string, - description: string, - feedSalt: string -): Promise { - const salt = ethers.utils.keccak256(ethers.utils.toUtf8Bytes(feedSalt)); - - const DerivedPriceFeed = await ethers.getContractFactory("DerivedPriceFeed"); - - const derivedPriceFeedBytecode = `${ - DerivedPriceFeed.bytecode - }${ethers.utils.defaultAbiCoder - .encode( - ["address", "address", "string"], - [nativeOracleAddress, tokenOracleAddress, description] - ) - .slice(2)}`; - - const derivedPriceFeedBComputedAddr = await deployerInstance.addressOf(salt); - console.log( - "Derived Price Feed Computed Address: ", - derivedPriceFeedBComputedAddr - ); - const isContractDeployed = await isContract( - derivedPriceFeedBComputedAddr, - provider - ); - if (!isContractDeployed) { - try { - await deployContract( - feedSalt, - derivedPriceFeedBComputedAddr, - salt, - derivedPriceFeedBytecode, - deployerInstance - ); - await delay(5000); - } catch (err) { - console.log(err); - console.log("issue with the deployment"); - return ethers.constants.AddressZero; - } - try { - await run(`verify:verify`, { - address: derivedPriceFeedBComputedAddr, - constructorArguments: [ - nativeOracleAddress, - tokenOracleAddress, - description, - ], - }); - } catch (err) { - console.log( - "issue with the verification ", - derivedPriceFeedBComputedAddr - ); - - return derivedPriceFeedBComputedAddr; - } - } else { - console.log( - "Derived Price Feed is Already deployed with address ", - derivedPriceFeedBComputedAddr - ); - } - return derivedPriceFeedBComputedAddr; -} - -async function setTokenOracle( - oracleAggregatorInstance: ChainlinkOracleAggregator, - tokenAddress: string, - priceFeedAddress: string, - priceFeedDecimals: number, - priceFeedFunctionName: string -) { - const PriceFeedContract = await ethers.getContractAt( - "FeedInterface", - priceFeedAddress - ); - - // Find the function ABI based on the provided function name - // @ts-ignore - const functionAbi = - PriceFeedContract.interface.functions[ - priceFeedFunctionName as keyof typeof PriceFeedContract.functions - ]; - - // Generate the function data based on the function ABI - const functionData = - PriceFeedContract.interface.encodeFunctionData(functionAbi); - - const tx = await oracleAggregatorInstance.setTokenOracle( - tokenAddress, - priceFeedAddress, - priceFeedDecimals, - functionData, - true - ); - const receipt = await tx.wait(); - console.log( - `Oracle set for ${tokenAddress} with tx hash ${receipt.transactionHash}` - ); -} - -/* - * This function is added to support the flow with pre-deploying the deployer contract - * using the `deployer-contract.deploy.ts` script. - */ -async function getPredeployedDeployerContractInstanceDEV(): Promise { - const code = await provider.getCode(DEPLOYER_CONTRACT_ADDRESS_DEV); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Deployer not deployed on chain ${chainId}, deploy it with deployer-contract.deploy.ts script before using this script.` - ); - throw new Error("Deployer not deployed"); - } else { - console.log( - "Deploying with EOA %s through Deployer Contract %s", - signer.address, - DEPLOYER_CONTRACT_ADDRESS_DEV - ); - return Deployer__factory.connect(DEPLOYER_CONTRACT_ADDRESS_DEV, signer); - } -} - -async function getPredeployedDeployerContractInstancePROD(): Promise { - const code = await provider.getCode(DEPLOYER_CONTRACT_ADDRESS_PROD); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Deployer not deployed on chain ${chainId}, deploy it with deployer-contract.deploy.ts script before using this script.` - ); - throw new Error("Deployer not deployed"); - } else { - console.log( - "Deploying with EOA %s through Deployer Contract %s", - signer.address, - DEPLOYER_CONTRACT_ADDRESS_PROD - ); - return Deployer__factory.connect(DEPLOYER_CONTRACT_ADDRESS_PROD, signer); - } -} - -async function getChainlinkOracleAggregatorContractInstance( - oracleAggregatorAddress: string -): Promise { - const code = await provider.getCode(oracleAggregatorAddress); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `ChainlinkOracleAggregator not deployed on chain ${chainId}, It should have been deployed as part of this script.` - ); - throw new Error("ChainlinkOracleAggregator not deployed"); - } else { - console.log( - "Returning instance connected with EOA %s and address %s", - signer.address, - oracleAggregatorAddress - ); - return ChainlinkOracleAggregator__factory.connect( - oracleAggregatorAddress, - signer - ); - } -} - -async function getTokenPaymasterContractInstance( - tokenPaymasterAddress: string -): Promise { - const code = await provider.getCode(tokenPaymasterAddress); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Biconomy Token Paymaster not deployed on chain ${chainId}, It should have been deployed as part of this script.` - ); - throw new Error("Biconomy Token Paymaster not deployed"); - } else { - console.log( - "Returning instance connected with EOA %s and address %s", - signer.address, - tokenPaymasterAddress - ); - return BiconomyTokenPaymaster__factory.connect( - tokenPaymasterAddress, - signer - ); - } -} - -async function main() { - let tx, receipt; - const provider = ethers.provider; - - const accounts = await ethers.getSigners(); - const earlyOwner = await accounts[0].getAddress(); - - const deployerInstanceDEV = await getPredeployedDeployerContractInstanceDEV(); - console.log("========================================="); - - const deployerInstancePROD = - await getPredeployedDeployerContractInstancePROD(); - console.log("========================================="); - - // 1. Deploy Chainlink Oracle Aggregator - // @note: owner is kept the deployer because we need to perform more actions on this contract using owner as part of other scripts - // @note: ownership should be transferred at the end - const oracleAggregatorAddress = await deployChainlinkOracleAggregatorContract( - deployerInstancePROD, - earlyOwner - ); - console.log( - "==================oracleAggregatorAddress=======================", - oracleAggregatorAddress - ); - await delay(5000); - - // 2. Deploy Token paymaster - const tokenPaymasterAddress = await deployTokenPaymasterContract( - deployerInstancePROD, - earlyOwner - ); - console.log( - "==================tokenPaymasterAddress=======================", - tokenPaymasterAddress - ); - await delay(5000); - - let oracleAggregatorInstance; - if (oracleAggregatorAddress) { - oracleAggregatorInstance = - await getChainlinkOracleAggregatorContractInstance( - oracleAggregatorAddress - ); - console.log( - "==================oracleAggregatorInstance=======================" - ); - } - - // 3a. Deploy the derived price feeds for all chainlink supported ERC20 tokens - for (const token of tokenConfig.tokens) { - const { - symbol, - address, - nativeOracleAddress, - tokenOracleAddress, - priceFeedAddress, - description, - priceFeedFunction, - feedSalt, - derivedFeed, - } = token; - let derivedPriceFeedAddress = priceFeedAddress; - - if (derivedPriceFeedAddress == "") { - derivedPriceFeedAddress = await deployDerivedPriceFeed( - deployerInstanceDEV, - nativeOracleAddress, - tokenOracleAddress, - description, - feedSalt - ); - console.log( - `==================${symbol} PriceFeedAddress=======================`, - derivedPriceFeedAddress - ); - await delay(5000); - } - - // Continue with other steps like setting token oracle, transferring ownership, etc. - // Use the derivedPriceFeedAddress and other token-specific information as needed - // ... - - // 4. Set token oracle on oracle aggregator - if (oracleAggregatorInstance) { - let feedAddress = derivedPriceFeedAddress; - if (priceFeedFunction == "latestAnswer()" || derivedFeed == false) { - feedAddress = priceFeedAddress; - } - // TODO - // This should not hardcode tokenOracleDeciamls to 18 - // It works in case of derived price feeds and chainlink feeds which are in the erc20 / native base and quote format. - await setTokenOracle( - oracleAggregatorInstance, - address, - feedAddress, - 18, - priceFeedFunction - ); - } - } - - if (tokenPaymasterAddress) { - // 5b. transfer ownership of token paymaster to the owner - const tokenPaymasterInstance = await getTokenPaymasterContractInstance( - tokenPaymasterAddress - ); - console.log( - "==================tokenPaymasterInstance=======================" - ); - - - } -} - -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); diff --git a/scripts/deploy-bnb-mainnet.ts b/scripts/deploy-bnb-mainnet.ts deleted file mode 100644 index a35cbab..0000000 --- a/scripts/deploy-bnb-mainnet.ts +++ /dev/null @@ -1,486 +0,0 @@ -import { ethers, run, network } from "hardhat"; -import { bnbMainnetConfigInfoProd } from "./configs"; -import { Token, TokenConfig } from "./utils/Types"; -import { - deployContract, - DEPLOYMENT_SALTS, - encodeParam, - getDeployerInstance, - isContract, -} from "./utils"; -import { - BiconomyTokenPaymaster, - BiconomyTokenPaymaster__factory, - ChainlinkOracleAggregator, - ChainlinkOracleAggregator__factory, - Deployer, - Deployer__factory, -} from "../typechain-types"; - -const tokenConfig: TokenConfig = bnbMainnetConfigInfoProd; - -const provider = ethers.provider; -const entryPointAddress = - process.env.ENTRY_POINT_ADDRESS || - "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789"; -const owner = process.env.PAYMASTER_OWNER_ADDRESS_DEV || ""; -const verifyingSigner = process.env.PAYMASTER_SIGNER_ADDRESS_DEV || ""; -const DEPLOYER_CONTRACT_ADDRESS_DEV = - process.env.DEPLOYER_CONTRACT_ADDRESS_DEV || ""; -const DEPLOYER_CONTRACT_ADDRESS_PROD = - process.env.DEPLOYER_CONTRACT_ADDRESS_PROD || ""; - -function delay(ms: number) { - return new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, ms); - }); -} - -async function deployChainlinkOracleAggregatorContract( - deployerInstance: Deployer, - earlyOwnerAddress: string -): Promise { - const ORACLE_AGGREGATOR_SALT = ethers.utils.keccak256( - ethers.utils.toUtf8Bytes(DEPLOYMENT_SALTS.ORACLE_AGGREGATOR) - ); - - const OracleAggregator = await ethers.getContractFactory( - "ChainlinkOracleAggregator" - ); - const oracleAggregatorBytecode = `${OracleAggregator.bytecode}${encodeParam( - "address", - earlyOwnerAddress - ).slice(2)}`; - const oracleAggregatorComputedAddr = await deployerInstance.addressOf( - ORACLE_AGGREGATOR_SALT - ); - console.log( - "Chainlink Oracle Aggregator Computed Address: ", - oracleAggregatorComputedAddr - ); - - const isOracleAggregatorDeployed = await isContract( - oracleAggregatorComputedAddr, - provider - ); // true (deployed on-chain) - if (!isOracleAggregatorDeployed) { - try { - await deployContract( - DEPLOYMENT_SALTS.ORACLE_AGGREGATOR, - oracleAggregatorComputedAddr, - ORACLE_AGGREGATOR_SALT, - oracleAggregatorBytecode, - deployerInstance - ); - await delay(5000); - } catch (err) { - console.log("issue with the deployment"); - console.log(err); - return ethers.constants.AddressZero; - } - - try { - await run(`verify:verify`, { - address: oracleAggregatorComputedAddr, - constructorArguments: [earlyOwnerAddress], - }); - } catch (err) { - console.log("issue with the verification ", oracleAggregatorComputedAddr); - - return oracleAggregatorComputedAddr; - } - } else { - console.log( - "Chainlink Oracle Aggregator is already deployed with address ", - oracleAggregatorComputedAddr - ); - } - return oracleAggregatorComputedAddr; -} - -async function deployTokenPaymasterContract( - deployerInstance: Deployer, - earlyOwnerAddress: string -): Promise { - const salt = ethers.utils.keccak256( - ethers.utils.toUtf8Bytes(DEPLOYMENT_SALTS.TOKEN_PAYMASTER) - ); - - const BiconomyTokenPaymaster = await ethers.getContractFactory( - "BiconomyTokenPaymaster" - ); - const tokenPaymasterBytecode = `${ - BiconomyTokenPaymaster.bytecode - }${encodeParam("address", earlyOwnerAddress).slice(2)}${encodeParam( - "address", - entryPointAddress - ).slice(2)}${encodeParam("address", verifyingSigner).slice(2)}`; - - const tokenPaymasterComputedAddr = await deployerInstance.addressOf(salt); - console.log("Token paymaster Computed Address: ", tokenPaymasterComputedAddr); - const isContractDeployed = await isContract( - tokenPaymasterComputedAddr, - provider - ); - if (!isContractDeployed) { - try { - await deployContract( - DEPLOYMENT_SALTS.TOKEN_PAYMASTER, - tokenPaymasterComputedAddr, - salt, - tokenPaymasterBytecode, - deployerInstance - ); - await delay(5000); - } catch (err) { - console.log(err); - console.log("issue with the deployment"); - return ethers.constants.AddressZero; - } - try { - await run(`verify:verify`, { - address: tokenPaymasterComputedAddr, - constructorArguments: [ - earlyOwnerAddress, - entryPointAddress, - verifyingSigner, - ], - }); - } catch (err) { - console.log("issue with the verification ", tokenPaymasterComputedAddr); - - return tokenPaymasterComputedAddr; - } - } else { - console.log( - "Token Paymaster is Already deployed with address ", - tokenPaymasterComputedAddr - ); - } - return tokenPaymasterComputedAddr; -} - -async function deployDerivedPriceFeed( - deployerInstance: Deployer, - nativeOracleAddress: string, - tokenOracleAddress: string, - description: string, - feedSalt: string -): Promise { - const salt = ethers.utils.keccak256(ethers.utils.toUtf8Bytes(feedSalt)); - - const DerivedPriceFeed = await ethers.getContractFactory("DerivedPriceFeed"); - - const derivedPriceFeedBytecode = `${ - DerivedPriceFeed.bytecode - }${ethers.utils.defaultAbiCoder - .encode( - ["address", "address", "string"], - [nativeOracleAddress, tokenOracleAddress, description] - ) - .slice(2)}`; - - const derivedPriceFeedBComputedAddr = await deployerInstance.addressOf(salt); - console.log( - "Derived Price Feed Computed Address: ", - derivedPriceFeedBComputedAddr - ); - const isContractDeployed = await isContract( - derivedPriceFeedBComputedAddr, - provider - ); - if (!isContractDeployed) { - try { - await deployContract( - feedSalt, - derivedPriceFeedBComputedAddr, - salt, - derivedPriceFeedBytecode, - deployerInstance - ); - await delay(5000); - } catch (err) { - console.log(err); - console.log("issue with the deployment"); - return ethers.constants.AddressZero; - } - try { - await run(`verify:verify`, { - address: derivedPriceFeedBComputedAddr, - constructorArguments: [ - nativeOracleAddress, - tokenOracleAddress, - description, - ], - }); - } catch (err) { - console.log( - "issue with the verification ", - derivedPriceFeedBComputedAddr - ); - - return derivedPriceFeedBComputedAddr; - } - } else { - console.log( - "Derived Price Feed is Already deployed with address ", - derivedPriceFeedBComputedAddr - ); - } - return derivedPriceFeedBComputedAddr; -} - -async function setTokenOracle( - oracleAggregatorInstance: ChainlinkOracleAggregator, - tokenAddress: string, - priceFeedAddress: string, - priceFeedDecimals: number, - priceFeedFunctionName: string -) { - const PriceFeedContract = await ethers.getContractAt( - "FeedInterface", - priceFeedAddress - ); - - // Find the function ABI based on the provided function name - // @ts-ignore - const functionAbi = - PriceFeedContract.interface.functions[ - priceFeedFunctionName as keyof typeof PriceFeedContract.functions - ]; - - // Generate the function data based on the function ABI - const functionData = - PriceFeedContract.interface.encodeFunctionData(functionAbi); - - const tx = await oracleAggregatorInstance.setTokenOracle( - tokenAddress, - priceFeedAddress, - priceFeedDecimals, - functionData, - true - ); - const receipt = await tx.wait(); - console.log( - `Oracle set for ${tokenAddress} with tx hash ${receipt.transactionHash}` - ); -} - -/* - * This function is added to support the flow with pre-deploying the deployer contract - * using the `deployer-contract.deploy.ts` script. - */ -async function getPredeployedDeployerContractInstanceDEV(): Promise { - const code = await provider.getCode(DEPLOYER_CONTRACT_ADDRESS_DEV); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Deployer not deployed on chain ${chainId}, deploy it with deployer-contract.deploy.ts script before using this script.` - ); - throw new Error("Deployer not deployed"); - } else { - console.log( - "Deploying with EOA %s through Deployer Contract %s", - signer.address, - DEPLOYER_CONTRACT_ADDRESS_DEV - ); - return Deployer__factory.connect(DEPLOYER_CONTRACT_ADDRESS_DEV, signer); - } -} - -async function getPredeployedDeployerContractInstancePROD(): Promise { - const code = await provider.getCode(DEPLOYER_CONTRACT_ADDRESS_PROD); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Deployer not deployed on chain ${chainId}, deploy it with deployer-contract.deploy.ts script before using this script.` - ); - throw new Error("Deployer not deployed"); - } else { - console.log( - "Deploying with EOA %s through Deployer Contract %s", - signer.address, - DEPLOYER_CONTRACT_ADDRESS_PROD - ); - return Deployer__factory.connect(DEPLOYER_CONTRACT_ADDRESS_PROD, signer); - } -} - -async function getChainlinkOracleAggregatorContractInstance( - oracleAggregatorAddress: string -): Promise { - const code = await provider.getCode(oracleAggregatorAddress); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `ChainlinkOracleAggregator not deployed on chain ${chainId}, It should have been deployed as part of this script.` - ); - throw new Error("ChainlinkOracleAggregator not deployed"); - } else { - console.log( - "Returning instance connected with EOA %s and address %s", - signer.address, - oracleAggregatorAddress - ); - return ChainlinkOracleAggregator__factory.connect( - oracleAggregatorAddress, - signer - ); - } -} - -async function getTokenPaymasterContractInstance( - tokenPaymasterAddress: string -): Promise { - const code = await provider.getCode(tokenPaymasterAddress); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Biconomy Token Paymaster not deployed on chain ${chainId}, It should have been deployed as part of this script.` - ); - throw new Error("Biconomy Token Paymaster not deployed"); - } else { - console.log( - "Returning instance connected with EOA %s and address %s", - signer.address, - tokenPaymasterAddress - ); - return BiconomyTokenPaymaster__factory.connect( - tokenPaymasterAddress, - signer - ); - } -} - -async function main() { - let tx, receipt; - const provider = ethers.provider; - - const accounts = await ethers.getSigners(); - const earlyOwner = await accounts[0].getAddress(); - - const deployerInstanceDEV = await getPredeployedDeployerContractInstanceDEV(); - console.log("========================================="); - - const deployerInstancePROD = - await getPredeployedDeployerContractInstancePROD(); - console.log("========================================="); - - // 1. Deploy Chainlink Oracle Aggregator - // @note: owner is kept the deployer because we need to perform more actions on this contract using owner as part of other scripts - // @note: ownership should be transferred at the end - const oracleAggregatorAddress = await deployChainlinkOracleAggregatorContract( - deployerInstancePROD, - earlyOwner - ); - console.log( - "==================oracleAggregatorAddress=======================", - oracleAggregatorAddress - ); - await delay(5000); - - // 2. Deploy Token paymaster - const tokenPaymasterAddress = await deployTokenPaymasterContract( - deployerInstancePROD, - earlyOwner - ); - console.log( - "==================tokenPaymasterAddress=======================", - tokenPaymasterAddress - ); - await delay(5000); - - let oracleAggregatorInstance; - if (oracleAggregatorAddress) { - oracleAggregatorInstance = - await getChainlinkOracleAggregatorContractInstance( - oracleAggregatorAddress - ); - console.log( - "==================oracleAggregatorInstance=======================" - ); - } - - // 3a. Deploy the derived price feeds for all chainlink supported ERC20 tokens - for (const token of tokenConfig.tokens) { - const { - symbol, - address, - nativeOracleAddress, - tokenOracleAddress, - priceFeedAddress, - description, - priceFeedFunction, - feedSalt, - derivedFeed, - } = token; - let derivedPriceFeedAddress = priceFeedAddress; - console.log( - `derived price feed address for token ${symbol} is ${derivedPriceFeedAddress}` - ); - - if (derivedPriceFeedAddress == "") { - derivedPriceFeedAddress = await deployDerivedPriceFeed( - deployerInstanceDEV, - nativeOracleAddress, - tokenOracleAddress, - description, - feedSalt - ); - console.log( - `==================${symbol} PriceFeedAddress=======================`, - derivedPriceFeedAddress - ); - await delay(5000); - } - - // Continue with other steps like setting token oracle, transferring ownership, etc. - // Use the derivedPriceFeedAddress and other token-specific information as needed - // ... - - // 4. Set token oracle on oracle aggregator - if (oracleAggregatorInstance) { - let feedAddress = derivedPriceFeedAddress; - if (priceFeedFunction == "latestAnswer()" || derivedFeed == false) { - feedAddress = priceFeedAddress; - } - // TODO - // This should not hardcode tokenOracleDeciamls to 18 - // It works in case of derived price feeds and chainlink feeds which are in the erc20 / native base and quote format. - await setTokenOracle( - oracleAggregatorInstance, - address, - feedAddress, - 18, - priceFeedFunction - ); - } - } - - if (tokenPaymasterAddress) { - // 5b. transfer ownership of token paymaster to the owner - const tokenPaymasterInstance = await getTokenPaymasterContractInstance( - tokenPaymasterAddress - ); - console.log( - "==================tokenPaymasterInstance=======================" - ); - - - } -} - -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); diff --git a/scripts/deploy-bnb-testnet.ts b/scripts/deploy-bnb-testnet.ts deleted file mode 100644 index 8b1f732..0000000 --- a/scripts/deploy-bnb-testnet.ts +++ /dev/null @@ -1,483 +0,0 @@ -import { ethers, run, network } from "hardhat"; -import { bnbTestnetConfigInfoProd } from "./configs"; -import { Token, TokenConfig } from "./utils/Types"; -import { - deployContract, - DEPLOYMENT_SALTS, - encodeParam, - getDeployerInstance, - isContract, -} from "./utils"; -import { - BiconomyTokenPaymaster, - BiconomyTokenPaymaster__factory, - ChainlinkOracleAggregator, - ChainlinkOracleAggregator__factory, - Deployer, - Deployer__factory, -} from "../typechain-types"; - -const tokenConfig: TokenConfig = bnbTestnetConfigInfoProd; - -const provider = ethers.provider; -const entryPointAddress = - process.env.ENTRY_POINT_ADDRESS || - "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789"; -const owner = process.env.PAYMASTER_OWNER_ADDRESS_DEV || ""; -const verifyingSigner = process.env.PAYMASTER_SIGNER_ADDRESS_DEV || ""; -const DEPLOYER_CONTRACT_ADDRESS_DEV = - process.env.DEPLOYER_CONTRACT_ADDRESS_DEV || ""; -const DEPLOYER_CONTRACT_ADDRESS_PROD = - process.env.DEPLOYER_CONTRACT_ADDRESS_PROD || ""; - -function delay(ms: number) { - return new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, ms); - }); -} - -async function deployChainlinkOracleAggregatorContract( - deployerInstance: Deployer, - earlyOwnerAddress: string -): Promise { - const ORACLE_AGGREGATOR_SALT = ethers.utils.keccak256( - ethers.utils.toUtf8Bytes(DEPLOYMENT_SALTS.ORACLE_AGGREGATOR) - ); - - const OracleAggregator = await ethers.getContractFactory( - "ChainlinkOracleAggregator" - ); - const oracleAggregatorBytecode = `${OracleAggregator.bytecode}${encodeParam( - "address", - earlyOwnerAddress - ).slice(2)}`; - const oracleAggregatorComputedAddr = await deployerInstance.addressOf( - ORACLE_AGGREGATOR_SALT - ); - console.log( - "Chainlink Oracle Aggregator Computed Address: ", - oracleAggregatorComputedAddr - ); - - const isOracleAggregatorDeployed = await isContract( - oracleAggregatorComputedAddr, - provider - ); // true (deployed on-chain) - if (!isOracleAggregatorDeployed) { - try { - await deployContract( - DEPLOYMENT_SALTS.ORACLE_AGGREGATOR, - oracleAggregatorComputedAddr, - ORACLE_AGGREGATOR_SALT, - oracleAggregatorBytecode, - deployerInstance - ); - await delay(10000); - } catch (err) { - console.log("issue with the deployment"); - console.log(err); - return ethers.constants.AddressZero; - } - - try { - await run(`verify:verify`, { - address: oracleAggregatorComputedAddr, - constructorArguments: [earlyOwnerAddress], - }); - } catch (err) { - console.log("issue with the verification ", oracleAggregatorComputedAddr); - - return oracleAggregatorComputedAddr; - } - } else { - console.log( - "Chainlink Oracle Aggregator is already deployed with address ", - oracleAggregatorComputedAddr - ); - } - return oracleAggregatorComputedAddr; -} - -async function deployTokenPaymasterContract( - deployerInstance: Deployer, - earlyOwnerAddress: string -): Promise { - const salt = ethers.utils.keccak256( - ethers.utils.toUtf8Bytes(DEPLOYMENT_SALTS.TOKEN_PAYMASTER) - ); - - const BiconomyTokenPaymaster = await ethers.getContractFactory( - "BiconomyTokenPaymaster" - ); - const tokenPaymasterBytecode = `${ - BiconomyTokenPaymaster.bytecode - }${encodeParam("address", earlyOwnerAddress).slice(2)}${encodeParam( - "address", - entryPointAddress - ).slice(2)}${encodeParam("address", verifyingSigner).slice(2)}`; - - const tokenPaymasterComputedAddr = await deployerInstance.addressOf(salt); - console.log("Token paymaster Computed Address: ", tokenPaymasterComputedAddr); - const isContractDeployed = await isContract( - tokenPaymasterComputedAddr, - provider - ); - if (!isContractDeployed) { - try { - await deployContract( - DEPLOYMENT_SALTS.TOKEN_PAYMASTER, - tokenPaymasterComputedAddr, - salt, - tokenPaymasterBytecode, - deployerInstance - ); - await delay(5000); - } catch (err) { - console.log(err); - console.log("issue with the deployment"); - return ethers.constants.AddressZero; - } - try { - await run(`verify:verify`, { - address: tokenPaymasterComputedAddr, - constructorArguments: [ - earlyOwnerAddress, - entryPointAddress, - verifyingSigner, - ], - }); - } catch (err) { - console.log("issue with the verification ", tokenPaymasterComputedAddr); - - return tokenPaymasterComputedAddr; - } - } else { - console.log( - "Token Paymaster is Already deployed with address ", - tokenPaymasterComputedAddr - ); - } - return tokenPaymasterComputedAddr; -} - -async function deployDerivedPriceFeed( - deployerInstance: Deployer, - nativeOracleAddress: string, - tokenOracleAddress: string, - description: string, - feedSalt: string -): Promise { - const salt = ethers.utils.keccak256(ethers.utils.toUtf8Bytes(feedSalt)); - - const DerivedPriceFeed = await ethers.getContractFactory("DerivedPriceFeed"); - - const derivedPriceFeedBytecode = `${ - DerivedPriceFeed.bytecode - }${ethers.utils.defaultAbiCoder - .encode( - ["address", "address", "string"], - [nativeOracleAddress, tokenOracleAddress, description] - ) - .slice(2)}`; - - const derivedPriceFeedBComputedAddr = await deployerInstance.addressOf(salt); - console.log( - "Derived Price Feed Computed Address: ", - derivedPriceFeedBComputedAddr - ); - const isContractDeployed = await isContract( - derivedPriceFeedBComputedAddr, - provider - ); - if (!isContractDeployed) { - try { - await deployContract( - feedSalt, - derivedPriceFeedBComputedAddr, - salt, - derivedPriceFeedBytecode, - deployerInstance - ); - await delay(5000); - } catch (err) { - console.log(err); - console.log("issue with the deployment"); - return ethers.constants.AddressZero; - } - try { - await run(`verify:verify`, { - address: derivedPriceFeedBComputedAddr, - constructorArguments: [ - nativeOracleAddress, - tokenOracleAddress, - description, - ], - }); - } catch (err) { - console.log( - "issue with the verification ", - derivedPriceFeedBComputedAddr - ); - - return derivedPriceFeedBComputedAddr; - } - } else { - console.log( - "Derived Price Feed is Already deployed with address ", - derivedPriceFeedBComputedAddr - ); - } - return derivedPriceFeedBComputedAddr; -} - -async function setTokenOracle( - oracleAggregatorInstance: ChainlinkOracleAggregator, - tokenAddress: string, - priceFeedAddress: string, - priceFeedDecimals: number, - priceFeedFunctionName: string -) { - const PriceFeedContract = await ethers.getContractAt( - "FeedInterface", - priceFeedAddress - ); - - // Find the function ABI based on the provided function name - // @ts-ignore - const functionAbi = - PriceFeedContract.interface.functions[ - priceFeedFunctionName as keyof typeof PriceFeedContract.functions - ]; - - // Generate the function data based on the function ABI - const functionData = - PriceFeedContract.interface.encodeFunctionData(functionAbi); - - const tx = await oracleAggregatorInstance.setTokenOracle( - tokenAddress, - priceFeedAddress, - priceFeedDecimals, - functionData, - true - ); - const receipt = await tx.wait(); - console.log( - `Oracle set for ${tokenAddress} with tx hash ${receipt.transactionHash}` - ); -} - -/* - * This function is added to support the flow with pre-deploying the deployer contract - * using the `deployer-contract.deploy.ts` script. - */ -async function getPredeployedDeployerContractInstanceDEV(): Promise { - const code = await provider.getCode(DEPLOYER_CONTRACT_ADDRESS_DEV); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Deployer not deployed on chain ${chainId}, deploy it with deployer-contract.deploy.ts script before using this script.` - ); - throw new Error("Deployer not deployed"); - } else { - console.log( - "Deploying with EOA %s through Deployer Contract %s", - signer.address, - DEPLOYER_CONTRACT_ADDRESS_DEV - ); - return Deployer__factory.connect(DEPLOYER_CONTRACT_ADDRESS_DEV, signer); - } -} - -async function getPredeployedDeployerContractInstancePROD(): Promise { - const code = await provider.getCode(DEPLOYER_CONTRACT_ADDRESS_PROD); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Deployer not deployed on chain ${chainId}, deploy it with deployer-contract.deploy.ts script before using this script.` - ); - throw new Error("Deployer not deployed"); - } else { - console.log( - "Deploying with EOA %s through Deployer Contract %s", - signer.address, - DEPLOYER_CONTRACT_ADDRESS_PROD - ); - return Deployer__factory.connect(DEPLOYER_CONTRACT_ADDRESS_PROD, signer); - } -} - -async function getChainlinkOracleAggregatorContractInstance( - oracleAggregatorAddress: string -): Promise { - const code = await provider.getCode(oracleAggregatorAddress); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `ChainlinkOracleAggregator not deployed on chain ${chainId}, It should have been deployed as part of this script.` - ); - throw new Error("ChainlinkOracleAggregator not deployed"); - } else { - console.log( - "Returning instance connected with EOA %s and address %s", - signer.address, - oracleAggregatorAddress - ); - return ChainlinkOracleAggregator__factory.connect( - oracleAggregatorAddress, - signer - ); - } -} - -async function getTokenPaymasterContractInstance( - tokenPaymasterAddress: string -): Promise { - const code = await provider.getCode(tokenPaymasterAddress); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Biconomy Token Paymaster not deployed on chain ${chainId}, It should have been deployed as part of this script.` - ); - throw new Error("Biconomy Token Paymaster not deployed"); - } else { - console.log( - "Returning instance connected with EOA %s and address %s", - signer.address, - tokenPaymasterAddress - ); - return BiconomyTokenPaymaster__factory.connect( - tokenPaymasterAddress, - signer - ); - } -} - -async function main() { - let tx, receipt; - const provider = ethers.provider; - - const accounts = await ethers.getSigners(); - const earlyOwner = await accounts[0].getAddress(); - - const deployerInstanceDEV = await getPredeployedDeployerContractInstanceDEV(); - console.log("========================================="); - - const deployerInstancePROD = - await getPredeployedDeployerContractInstancePROD(); - console.log("========================================="); - - // 1. Deploy Chainlink Oracle Aggregator - // @note: owner is kept the deployer because we need to perform more actions on this contract using owner as part of other scripts - // @note: ownership should be transferred at the end - const oracleAggregatorAddress = await deployChainlinkOracleAggregatorContract( - deployerInstancePROD, - earlyOwner - ); - console.log( - "==================oracleAggregatorAddress=======================", - oracleAggregatorAddress - ); - await delay(5000); - - // 2. Deploy Token paymaster - const tokenPaymasterAddress = await deployTokenPaymasterContract( - deployerInstancePROD, - earlyOwner - ); - console.log( - "==================tokenPaymasterAddress=======================", - tokenPaymasterAddress - ); - await delay(5000); - - let oracleAggregatorInstance; - if (oracleAggregatorAddress) { - oracleAggregatorInstance = - await getChainlinkOracleAggregatorContractInstance( - oracleAggregatorAddress - ); - console.log( - "==================oracleAggregatorInstance=======================" - ); - } - - // 3a. Deploy the derived price feeds for all chainlink supported ERC20 tokens - for (const token of tokenConfig.tokens) { - const { - symbol, - address, - nativeOracleAddress, - tokenOracleAddress, - priceFeedAddress, - description, - priceFeedFunction, - feedSalt, - derivedFeed, - } = token; - let derivedPriceFeedAddress = priceFeedAddress; - - if (derivedPriceFeedAddress == "") { - derivedPriceFeedAddress = await deployDerivedPriceFeed( - deployerInstanceDEV, - nativeOracleAddress, - tokenOracleAddress, - description, - feedSalt - ); - console.log( - `==================${symbol} PriceFeedAddress=======================`, - derivedPriceFeedAddress - ); - await delay(5000); - } - - // Continue with other steps like setting token oracle, transferring ownership, etc. - // Use the derivedPriceFeedAddress and other token-specific information as needed - // ... - - // 4. Set token oracle on oracle aggregator - if (oracleAggregatorInstance) { - let feedAddress = derivedPriceFeedAddress; - if (priceFeedFunction == "latestAnswer()" || derivedFeed == false) { - feedAddress = priceFeedAddress; - } - // TODO - // This should not hardcode tokenOracleDeciamls to 18 - // It works in case of derived price feeds and chainlink feeds which are in the erc20 / native base and quote format. - await setTokenOracle( - oracleAggregatorInstance, - address, - feedAddress, - 18, - priceFeedFunction - ); - } - } - - if (tokenPaymasterAddress) { - // 5b. transfer ownership of token paymaster to the owner - const tokenPaymasterInstance = await getTokenPaymasterContractInstance( - tokenPaymasterAddress - ); - console.log( - "==================tokenPaymasterInstance=======================" - ); - - - } -} - -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); diff --git a/scripts/deploy-eth-mainnet.ts b/scripts/deploy-eth-mainnet.ts deleted file mode 100644 index 6e6ecda..0000000 --- a/scripts/deploy-eth-mainnet.ts +++ /dev/null @@ -1,480 +0,0 @@ -import { ethers, run, network } from "hardhat"; -import { ethMainnetConfigInfoProd } from "./configs"; -import { Token, TokenConfig } from "./utils/Types"; -import { - deployContract, - DEPLOYMENT_SALTS, - encodeParam, - getDeployerInstance, - isContract, -} from "./utils"; -import { - BiconomyTokenPaymaster, - BiconomyTokenPaymaster__factory, - ChainlinkOracleAggregator, - ChainlinkOracleAggregator__factory, - Deployer, - Deployer__factory, -} from "../typechain-types"; - -const tokenConfig: TokenConfig = ethMainnetConfigInfoProd; - -const provider = ethers.provider; -const entryPointAddress = - process.env.ENTRY_POINT_ADDRESS || - "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789"; -const owner = process.env.PAYMASTER_OWNER_ADDRESS_DEV || ""; -const verifyingSigner = process.env.PAYMASTER_SIGNER_ADDRESS_DEV || ""; -const DEPLOYER_CONTRACT_ADDRESS_DEV = - process.env.DEPLOYER_CONTRACT_ADDRESS_DEV || ""; -const DEPLOYER_CONTRACT_ADDRESS_PROD = - process.env.DEPLOYER_CONTRACT_ADDRESS_PROD || ""; - -function delay(ms: number) { - return new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, ms); - }); -} - -async function deployChainlinkOracleAggregatorContract( - deployerInstance: Deployer, - earlyOwnerAddress: string -): Promise { - const ORACLE_AGGREGATOR_SALT = ethers.utils.keccak256( - ethers.utils.toUtf8Bytes(DEPLOYMENT_SALTS.ORACLE_AGGREGATOR) - ); - - const OracleAggregator = await ethers.getContractFactory( - "ChainlinkOracleAggregator" - ); - const oracleAggregatorBytecode = `${OracleAggregator.bytecode}${encodeParam( - "address", - earlyOwnerAddress - ).slice(2)}`; - const oracleAggregatorComputedAddr = await deployerInstance.addressOf( - ORACLE_AGGREGATOR_SALT - ); - console.log( - "Chainlink Oracle Aggregator Computed Address: ", - oracleAggregatorComputedAddr - ); - - const isOracleAggregatorDeployed = await isContract( - oracleAggregatorComputedAddr, - provider - ); // true (deployed on-chain) - if (!isOracleAggregatorDeployed) { - try { - await deployContract( - DEPLOYMENT_SALTS.ORACLE_AGGREGATOR, - oracleAggregatorComputedAddr, - ORACLE_AGGREGATOR_SALT, - oracleAggregatorBytecode, - deployerInstance - ); - await delay(10000); - } catch (err) { - console.log("issue with the deployment"); - console.log(err); - return ethers.constants.AddressZero; - } - - try { - await run(`verify:verify`, { - address: oracleAggregatorComputedAddr, - constructorArguments: [earlyOwnerAddress], - }); - } catch (err) { - console.log("issue with the verification ", oracleAggregatorComputedAddr); - - return oracleAggregatorComputedAddr; - } - } else { - console.log( - "Chainlink Oracle Aggregator is already deployed with address ", - oracleAggregatorComputedAddr - ); - } - return oracleAggregatorComputedAddr; -} - -async function deployTokenPaymasterContract( - deployerInstance: Deployer, - earlyOwnerAddress: string -): Promise { - const salt = ethers.utils.keccak256( - ethers.utils.toUtf8Bytes(DEPLOYMENT_SALTS.TOKEN_PAYMASTER) - ); - - const BiconomyTokenPaymaster = await ethers.getContractFactory( - "BiconomyTokenPaymaster" - ); - const tokenPaymasterBytecode = `${ - BiconomyTokenPaymaster.bytecode - }${encodeParam("address", earlyOwnerAddress).slice(2)}${encodeParam( - "address", - entryPointAddress - ).slice(2)}${encodeParam("address", verifyingSigner).slice(2)}`; - - const tokenPaymasterComputedAddr = await deployerInstance.addressOf(salt); - console.log("Token paymaster Computed Address: ", tokenPaymasterComputedAddr); - const isContractDeployed = await isContract( - tokenPaymasterComputedAddr, - provider - ); - if (!isContractDeployed) { - try { - await deployContract( - DEPLOYMENT_SALTS.TOKEN_PAYMASTER, - tokenPaymasterComputedAddr, - salt, - tokenPaymasterBytecode, - deployerInstance - ); - await delay(7000); - } catch (err) { - console.log(err); - console.log("issue with the deployment"); - return ethers.constants.AddressZero; - } - try { - await run(`verify:verify`, { - address: tokenPaymasterComputedAddr, - constructorArguments: [ - earlyOwnerAddress, - entryPointAddress, - verifyingSigner, - ], - }); - } catch (err) { - console.log("issue with the verification ", tokenPaymasterComputedAddr); - - return tokenPaymasterComputedAddr; - } - } else { - console.log( - "Token Paymaster is Already deployed with address ", - tokenPaymasterComputedAddr - ); - } - return tokenPaymasterComputedAddr; -} - -async function deployDerivedPriceFeed( - deployerInstance: Deployer, - nativeOracleAddress: string, - tokenOracleAddress: string, - description: string, - feedSalt: string -): Promise { - const salt = ethers.utils.keccak256(ethers.utils.toUtf8Bytes(feedSalt)); - - const DerivedPriceFeed = await ethers.getContractFactory("DerivedPriceFeed"); - - const derivedPriceFeedBytecode = `${ - DerivedPriceFeed.bytecode - }${ethers.utils.defaultAbiCoder - .encode( - ["address", "address", "string"], - [nativeOracleAddress, tokenOracleAddress, description] - ) - .slice(2)}`; - - const derivedPriceFeedBComputedAddr = await deployerInstance.addressOf(salt); - console.log( - "Derived Price Feed Computed Address: ", - derivedPriceFeedBComputedAddr - ); - const isContractDeployed = await isContract( - derivedPriceFeedBComputedAddr, - provider - ); - if (!isContractDeployed) { - try { - await deployContract( - feedSalt, - derivedPriceFeedBComputedAddr, - salt, - derivedPriceFeedBytecode, - deployerInstance - ); - await delay(7000); - } catch (err) { - console.log(err); - console.log("issue with the deployment"); - return ethers.constants.AddressZero; - } - try { - await run(`verify:verify`, { - address: derivedPriceFeedBComputedAddr, - constructorArguments: [ - nativeOracleAddress, - tokenOracleAddress, - description, - ], - }); - } catch (err) { - console.log( - "issue with the verification ", - derivedPriceFeedBComputedAddr - ); - - return derivedPriceFeedBComputedAddr; - } - } else { - console.log( - "Derived Price Feed is Already deployed with address ", - derivedPriceFeedBComputedAddr - ); - } - return derivedPriceFeedBComputedAddr; -} - -async function setTokenOracle( - oracleAggregatorInstance: ChainlinkOracleAggregator, - tokenAddress: string, - priceFeedAddress: string, - priceFeedDecimals: number, - priceFeedFunctionName: string -) { - const PriceFeedContract = await ethers.getContractAt( - "FeedInterface", - priceFeedAddress - ); - - // Find the function ABI based on the provided function name - // @ts-ignore - const functionAbi = - PriceFeedContract.interface.functions[ - priceFeedFunctionName as keyof typeof PriceFeedContract.functions - ]; - - // Generate the function data based on the function ABI - const functionData = - PriceFeedContract.interface.encodeFunctionData(functionAbi); - - const tx = await oracleAggregatorInstance.setTokenOracle( - tokenAddress, - priceFeedAddress, - priceFeedDecimals, - functionData, - true - ); - const receipt = await tx.wait(); - console.log( - `Oracle set for ${tokenAddress} with tx hash ${receipt.transactionHash}` - ); -} - -/* - * This function is added to support the flow with pre-deploying the deployer contract - * using the `deployer-contract.deploy.ts` script. - */ -async function getPredeployedDeployerContractInstanceDEV(): Promise { - const code = await provider.getCode(DEPLOYER_CONTRACT_ADDRESS_DEV); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Deployer not deployed on chain ${chainId}, deploy it with deployer-contract.deploy.ts script before using this script.` - ); - throw new Error("Deployer not deployed"); - } else { - console.log( - "Deploying with EOA %s through Deployer Contract %s", - signer.address, - DEPLOYER_CONTRACT_ADDRESS_DEV - ); - return Deployer__factory.connect(DEPLOYER_CONTRACT_ADDRESS_DEV, signer); - } -} - -async function getPredeployedDeployerContractInstancePROD(): Promise { - const code = await provider.getCode(DEPLOYER_CONTRACT_ADDRESS_PROD); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Deployer not deployed on chain ${chainId}, deploy it with deployer-contract.deploy.ts script before using this script.` - ); - throw new Error("Deployer not deployed"); - } else { - console.log( - "Deploying with EOA %s through Deployer Contract %s", - signer.address, - DEPLOYER_CONTRACT_ADDRESS_PROD - ); - return Deployer__factory.connect(DEPLOYER_CONTRACT_ADDRESS_PROD, signer); - } -} - -async function getChainlinkOracleAggregatorContractInstance( - oracleAggregatorAddress: string -): Promise { - const code = await provider.getCode(oracleAggregatorAddress); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `ChainlinkOracleAggregator not deployed on chain ${chainId}, It should have been deployed as part of this script.` - ); - throw new Error("ChainlinkOracleAggregator not deployed"); - } else { - console.log( - "Returning instance connected with EOA %s and address %s", - signer.address, - oracleAggregatorAddress - ); - return ChainlinkOracleAggregator__factory.connect( - oracleAggregatorAddress, - signer - ); - } -} - -async function getTokenPaymasterContractInstance( - tokenPaymasterAddress: string -): Promise { - const code = await provider.getCode(tokenPaymasterAddress); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Biconomy Token Paymaster not deployed on chain ${chainId}, It should have been deployed as part of this script.` - ); - throw new Error("Biconomy Token Paymaster not deployed"); - } else { - console.log( - "Returning instance connected with EOA %s and address %s", - signer.address, - tokenPaymasterAddress - ); - return BiconomyTokenPaymaster__factory.connect( - tokenPaymasterAddress, - signer - ); - } -} - -async function main() { - let tx, receipt; - const provider = ethers.provider; - - const accounts = await ethers.getSigners(); - const earlyOwner = await accounts[0].getAddress(); - - // const deployerInstanceDEV = await getPredeployedDeployerContractInstanceDEV(); - // console.log("========================================="); - - const deployerInstancePROD = - await getPredeployedDeployerContractInstancePROD(); - console.log("========================================="); - - // 1. Deploy Chainlink Oracle Aggregator - // @note: owner is kept the deployer because we need to perform more actions on this contract using owner as part of other scripts - // @note: ownership should be transferred at the end - const oracleAggregatorAddress = await deployChainlinkOracleAggregatorContract( - deployerInstancePROD, - earlyOwner - ); - console.log( - "==================oracleAggregatorAddress=======================", - oracleAggregatorAddress - ); - await delay(7000); - - // 2. Deploy Token paymaster - const tokenPaymasterAddress = await deployTokenPaymasterContract( - deployerInstancePROD, - earlyOwner - ); - console.log( - "==================tokenPaymasterAddress=======================", - tokenPaymasterAddress - ); - await delay(7000); - - let oracleAggregatorInstance; - if (oracleAggregatorAddress) { - oracleAggregatorInstance = - await getChainlinkOracleAggregatorContractInstance( - oracleAggregatorAddress - ); - console.log( - "==================oracleAggregatorInstance=======================" - ); - } - - // 3a. Deploy the derived price feeds for all chainlink supported ERC20 tokens - for (const token of tokenConfig.tokens) { - const { - symbol, - address, - nativeOracleAddress, - tokenOracleAddress, - priceFeedAddress, - description, - priceFeedFunction, - feedSalt, - derivedFeed, - } = token; - const derivedPriceFeedAddress = priceFeedAddress; - console.log( - `derived price feed address for token ${symbol} is ${derivedPriceFeedAddress}` - ); - - if (derivedPriceFeedAddress == "") { - // derivedPriceFeedAddress = await deployDerivedPriceFeed(deployerInstanceDEV, nativeOracleAddress, tokenOracleAddress, description, feedSalt); - console.log( - `==================${symbol} PriceFeedAddress=======================`, - derivedPriceFeedAddress - ); - // await delay(7000); - } - - // Continue with other steps like setting token oracle, transferring ownership, etc. - // Use the derivedPriceFeedAddress and other token-specific information as needed - // ... - - // 4. Set token oracle on oracle aggregator - if (oracleAggregatorInstance) { - let feedAddress = derivedPriceFeedAddress; - if (priceFeedFunction == "latestAnswer()" || derivedFeed == false) { - feedAddress = priceFeedAddress; - } - // TODO - // This should not hardcode tokenOracleDeciamls to 18 - // It works in case of derived price feeds and chainlink feeds which are in the erc20 / native base and quote format. - await setTokenOracle( - oracleAggregatorInstance, - address, - feedAddress, - 18, - priceFeedFunction - ); - } - } - - if (tokenPaymasterAddress) { - // 5b. transfer ownership of token paymaster to the owner - const tokenPaymasterInstance = await getTokenPaymasterContractInstance( - tokenPaymasterAddress - ); - console.log( - "==================tokenPaymasterInstance=======================" - ); - - - } -} - -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); diff --git a/scripts/deploy-goerli.ts b/scripts/deploy-goerli.ts deleted file mode 100644 index 5891a28..0000000 --- a/scripts/deploy-goerli.ts +++ /dev/null @@ -1,483 +0,0 @@ -import { ethers, run, network } from "hardhat"; -import { goerliConfigInfoProd } from "./configs"; -import { Token, TokenConfig } from "./utils/Types"; -import { - deployContract, - DEPLOYMENT_SALTS, - encodeParam, - getDeployerInstance, - isContract, -} from "./utils"; -import { - BiconomyTokenPaymaster, - BiconomyTokenPaymaster__factory, - ChainlinkOracleAggregator, - ChainlinkOracleAggregator__factory, - Deployer, - Deployer__factory, -} from "../typechain-types"; - -const tokenConfig: TokenConfig = goerliConfigInfoProd; - -const provider = ethers.provider; -const entryPointAddress = - process.env.ENTRY_POINT_ADDRESS || - "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789"; -const owner = process.env.PAYMASTER_OWNER_ADDRESS_DEV || ""; -const verifyingSigner = process.env.PAYMASTER_SIGNER_ADDRESS_DEV || ""; -const DEPLOYER_CONTRACT_ADDRESS_DEV = - process.env.DEPLOYER_CONTRACT_ADDRESS_DEV || ""; -const DEPLOYER_CONTRACT_ADDRESS_PROD = - process.env.DEPLOYER_CONTRACT_ADDRESS_PROD || ""; - -function delay(ms: number) { - return new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, ms); - }); -} - -async function deployChainlinkOracleAggregatorContract( - deployerInstance: Deployer, - earlyOwnerAddress: string -): Promise { - const ORACLE_AGGREGATOR_SALT = ethers.utils.keccak256( - ethers.utils.toUtf8Bytes(DEPLOYMENT_SALTS.ORACLE_AGGREGATOR) - ); - - const OracleAggregator = await ethers.getContractFactory( - "ChainlinkOracleAggregator" - ); - const oracleAggregatorBytecode = `${OracleAggregator.bytecode}${encodeParam( - "address", - earlyOwnerAddress - ).slice(2)}`; - const oracleAggregatorComputedAddr = await deployerInstance.addressOf( - ORACLE_AGGREGATOR_SALT - ); - console.log( - "Chainlink Oracle Aggregator Computed Address: ", - oracleAggregatorComputedAddr - ); - - const isOracleAggregatorDeployed = await isContract( - oracleAggregatorComputedAddr, - provider - ); // true (deployed on-chain) - if (!isOracleAggregatorDeployed) { - try { - await deployContract( - DEPLOYMENT_SALTS.ORACLE_AGGREGATOR, - oracleAggregatorComputedAddr, - ORACLE_AGGREGATOR_SALT, - oracleAggregatorBytecode, - deployerInstance - ); - await delay(10000); - } catch (err) { - console.log("issue with the deployment"); - console.log(err); - return ethers.constants.AddressZero; - } - - try { - await run(`verify:verify`, { - address: oracleAggregatorComputedAddr, - constructorArguments: [earlyOwnerAddress], - }); - } catch (err) { - console.log("issue with the verification ", oracleAggregatorComputedAddr); - - return oracleAggregatorComputedAddr; - } - } else { - console.log( - "Chainlink Oracle Aggregator is already deployed with address ", - oracleAggregatorComputedAddr - ); - } - return oracleAggregatorComputedAddr; -} - -async function deployTokenPaymasterContract( - deployerInstance: Deployer, - earlyOwnerAddress: string -): Promise { - const salt = ethers.utils.keccak256( - ethers.utils.toUtf8Bytes(DEPLOYMENT_SALTS.TOKEN_PAYMASTER) - ); - - const BiconomyTokenPaymaster = await ethers.getContractFactory( - "BiconomyTokenPaymaster" - ); - const tokenPaymasterBytecode = `${ - BiconomyTokenPaymaster.bytecode - }${encodeParam("address", earlyOwnerAddress).slice(2)}${encodeParam( - "address", - entryPointAddress - ).slice(2)}${encodeParam("address", verifyingSigner).slice(2)}`; - - const tokenPaymasterComputedAddr = await deployerInstance.addressOf(salt); - console.log("Token paymaster Computed Address: ", tokenPaymasterComputedAddr); - const isContractDeployed = await isContract( - tokenPaymasterComputedAddr, - provider - ); - if (!isContractDeployed) { - try { - await deployContract( - DEPLOYMENT_SALTS.TOKEN_PAYMASTER, - tokenPaymasterComputedAddr, - salt, - tokenPaymasterBytecode, - deployerInstance - ); - await delay(5000); - } catch (err) { - console.log(err); - console.log("issue with the deployment"); - return ethers.constants.AddressZero; - } - try { - await run(`verify:verify`, { - address: tokenPaymasterComputedAddr, - constructorArguments: [ - earlyOwnerAddress, - entryPointAddress, - verifyingSigner, - ], - }); - } catch (err) { - console.log("issue with the verification ", tokenPaymasterComputedAddr); - - return tokenPaymasterComputedAddr; - } - } else { - console.log( - "Token Paymaster is Already deployed with address ", - tokenPaymasterComputedAddr - ); - } - return tokenPaymasterComputedAddr; -} - -async function deployDerivedPriceFeed( - deployerInstance: Deployer, - nativeOracleAddress: string, - tokenOracleAddress: string, - description: string, - feedSalt: string -): Promise { - const salt = ethers.utils.keccak256(ethers.utils.toUtf8Bytes(feedSalt)); - - const DerivedPriceFeed = await ethers.getContractFactory("DerivedPriceFeed"); - - const derivedPriceFeedBytecode = `${ - DerivedPriceFeed.bytecode - }${ethers.utils.defaultAbiCoder - .encode( - ["address", "address", "string"], - [nativeOracleAddress, tokenOracleAddress, description] - ) - .slice(2)}`; - - const derivedPriceFeedBComputedAddr = await deployerInstance.addressOf(salt); - console.log( - "Derived Price Feed Computed Address: ", - derivedPriceFeedBComputedAddr - ); - const isContractDeployed = await isContract( - derivedPriceFeedBComputedAddr, - provider - ); - if (!isContractDeployed) { - try { - await deployContract( - feedSalt, - derivedPriceFeedBComputedAddr, - salt, - derivedPriceFeedBytecode, - deployerInstance - ); - await delay(5000); - } catch (err) { - console.log(err); - console.log("issue with the deployment"); - return ethers.constants.AddressZero; - } - try { - await run(`verify:verify`, { - address: derivedPriceFeedBComputedAddr, - constructorArguments: [ - nativeOracleAddress, - tokenOracleAddress, - description, - ], - }); - } catch (err) { - console.log( - "issue with the verification ", - derivedPriceFeedBComputedAddr - ); - - return derivedPriceFeedBComputedAddr; - } - } else { - console.log( - "Derived Price Feed is Already deployed with address ", - derivedPriceFeedBComputedAddr - ); - } - return derivedPriceFeedBComputedAddr; -} - -async function setTokenOracle( - oracleAggregatorInstance: ChainlinkOracleAggregator, - tokenAddress: string, - priceFeedAddress: string, - priceFeedDecimals: number, - priceFeedFunctionName: string -) { - const PriceFeedContract = await ethers.getContractAt( - "FeedInterface", - priceFeedAddress - ); - - // Find the function ABI based on the provided function name - // @ts-ignore - const functionAbi = - PriceFeedContract.interface.functions[ - priceFeedFunctionName as keyof typeof PriceFeedContract.functions - ]; - - // Generate the function data based on the function ABI - const functionData = - PriceFeedContract.interface.encodeFunctionData(functionAbi); - - const tx = await oracleAggregatorInstance.setTokenOracle( - tokenAddress, - priceFeedAddress, - priceFeedDecimals, - functionData, - true - ); - const receipt = await tx.wait(); - console.log( - `Oracle set for ${tokenAddress} with tx hash ${receipt.transactionHash}` - ); -} - -/* - * This function is added to support the flow with pre-deploying the deployer contract - * using the `deployer-contract.deploy.ts` script. - */ -async function getPredeployedDeployerContractInstanceDEV(): Promise { - const code = await provider.getCode(DEPLOYER_CONTRACT_ADDRESS_DEV); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Deployer not deployed on chain ${chainId}, deploy it with deployer-contract.deploy.ts script before using this script.` - ); - throw new Error("Deployer not deployed"); - } else { - console.log( - "Deploying with EOA %s through Deployer Contract %s", - signer.address, - DEPLOYER_CONTRACT_ADDRESS_DEV - ); - return Deployer__factory.connect(DEPLOYER_CONTRACT_ADDRESS_DEV, signer); - } -} - -async function getPredeployedDeployerContractInstancePROD(): Promise { - const code = await provider.getCode(DEPLOYER_CONTRACT_ADDRESS_PROD); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Deployer not deployed on chain ${chainId}, deploy it with deployer-contract.deploy.ts script before using this script.` - ); - throw new Error("Deployer not deployed"); - } else { - console.log( - "Deploying with EOA %s through Deployer Contract %s", - signer.address, - DEPLOYER_CONTRACT_ADDRESS_PROD - ); - return Deployer__factory.connect(DEPLOYER_CONTRACT_ADDRESS_PROD, signer); - } -} - -async function getChainlinkOracleAggregatorContractInstance( - oracleAggregatorAddress: string -): Promise { - const code = await provider.getCode(oracleAggregatorAddress); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `ChainlinkOracleAggregator not deployed on chain ${chainId}, It should have been deployed as part of this script.` - ); - throw new Error("ChainlinkOracleAggregator not deployed"); - } else { - console.log( - "Returning instance connected with EOA %s and address %s", - signer.address, - oracleAggregatorAddress - ); - return ChainlinkOracleAggregator__factory.connect( - oracleAggregatorAddress, - signer - ); - } -} - -async function getTokenPaymasterContractInstance( - tokenPaymasterAddress: string -): Promise { - const code = await provider.getCode(tokenPaymasterAddress); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Biconomy Token Paymaster not deployed on chain ${chainId}, It should have been deployed as part of this script.` - ); - throw new Error("Biconomy Token Paymaster not deployed"); - } else { - console.log( - "Returning instance connected with EOA %s and address %s", - signer.address, - tokenPaymasterAddress - ); - return BiconomyTokenPaymaster__factory.connect( - tokenPaymasterAddress, - signer - ); - } -} - -async function main() { - let tx, receipt; - const provider = ethers.provider; - - const accounts = await ethers.getSigners(); - const earlyOwner = await accounts[0].getAddress(); - - const deployerInstanceDEV = await getPredeployedDeployerContractInstanceDEV(); - console.log("========================================="); - - const deployerInstancePROD = - await getPredeployedDeployerContractInstancePROD(); - console.log("========================================="); - - // 1. Deploy Chainlink Oracle Aggregator - // @note: owner is kept the deployer because we need to perform more actions on this contract using owner as part of other scripts - // @note: ownership should be transferred at the end - const oracleAggregatorAddress = await deployChainlinkOracleAggregatorContract( - deployerInstancePROD, - earlyOwner - ); - console.log( - "==================oracleAggregatorAddress=======================", - oracleAggregatorAddress - ); - await delay(5000); - - // 2. Deploy Token paymaster - const tokenPaymasterAddress = await deployTokenPaymasterContract( - deployerInstancePROD, - earlyOwner - ); - console.log( - "==================tokenPaymasterAddress=======================", - tokenPaymasterAddress - ); - await delay(5000); - - let oracleAggregatorInstance; - if (oracleAggregatorAddress) { - oracleAggregatorInstance = - await getChainlinkOracleAggregatorContractInstance( - oracleAggregatorAddress - ); - console.log( - "==================oracleAggregatorInstance=======================" - ); - } - - // 3a. Deploy the derived price feeds for all chainlink supported ERC20 tokens - for (const token of tokenConfig.tokens) { - const { - symbol, - address, - nativeOracleAddress, - tokenOracleAddress, - priceFeedAddress, - description, - priceFeedFunction, - feedSalt, - derivedFeed, - } = token; - let derivedPriceFeedAddress = priceFeedAddress; - - if (derivedPriceFeedAddress == "") { - derivedPriceFeedAddress = await deployDerivedPriceFeed( - deployerInstanceDEV, - nativeOracleAddress, - tokenOracleAddress, - description, - feedSalt - ); - console.log( - `==================${symbol} PriceFeedAddress=======================`, - derivedPriceFeedAddress - ); - await delay(5000); - } - - // Continue with other steps like setting token oracle, transferring ownership, etc. - // Use the derivedPriceFeedAddress and other token-specific information as needed - // ... - - // 4. Set token oracle on oracle aggregator - if (oracleAggregatorInstance) { - let feedAddress = derivedPriceFeedAddress; - if (priceFeedFunction == "latestAnswer()" || derivedFeed == false) { - feedAddress = priceFeedAddress; - } - // TODO - // This should not hardcode tokenOracleDeciamls to 18 - // It works in case of derived price feeds and chainlink feeds which are in the erc20 / native base and quote format. - await setTokenOracle( - oracleAggregatorInstance, - address, - feedAddress, - 18, - priceFeedFunction - ); - } - } - - if (tokenPaymasterAddress) { - // 5b. transfer ownership of token paymaster to the owner - const tokenPaymasterInstance = await getTokenPaymasterContractInstance( - tokenPaymasterAddress - ); - console.log( - "==================tokenPaymasterInstance=======================" - ); - - - } -} - -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); diff --git a/scripts/deploy-moonbeam-mainnet.ts b/scripts/deploy-moonbeam-mainnet.ts deleted file mode 100644 index a463de7..0000000 --- a/scripts/deploy-moonbeam-mainnet.ts +++ /dev/null @@ -1,483 +0,0 @@ -import { ethers, run, network } from "hardhat"; -import { moonbeamMainnetConfigInfoProd } from "./configs"; -import { Token, TokenConfig } from "./utils/Types"; -import { - deployContract, - DEPLOYMENT_SALTS, - encodeParam, - getDeployerInstance, - isContract, -} from "./utils"; -import { - BiconomyTokenPaymaster, - BiconomyTokenPaymaster__factory, - ChainlinkOracleAggregator, - ChainlinkOracleAggregator__factory, - Deployer, - Deployer__factory, -} from "../typechain-types"; - -const tokenConfig: TokenConfig = moonbeamMainnetConfigInfoProd; - -const provider = ethers.provider; -const entryPointAddress = - process.env.ENTRY_POINT_ADDRESS || - "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789"; -const owner = process.env.PAYMASTER_OWNER_ADDRESS_DEV || ""; -const verifyingSigner = process.env.PAYMASTER_SIGNER_ADDRESS_DEV || ""; -const DEPLOYER_CONTRACT_ADDRESS_DEV = - process.env.DEPLOYER_CONTRACT_ADDRESS_DEV || ""; -const DEPLOYER_CONTRACT_ADDRESS_PROD = - process.env.DEPLOYER_CONTRACT_ADDRESS_PROD || ""; - -function delay(ms: number) { - return new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, ms); - }); -} - -async function deployChainlinkOracleAggregatorContract( - deployerInstance: Deployer, - earlyOwnerAddress: string -): Promise { - const ORACLE_AGGREGATOR_SALT = ethers.utils.keccak256( - ethers.utils.toUtf8Bytes(DEPLOYMENT_SALTS.ORACLE_AGGREGATOR) - ); - - const OracleAggregator = await ethers.getContractFactory( - "ChainlinkOracleAggregator" - ); - const oracleAggregatorBytecode = `${OracleAggregator.bytecode}${encodeParam( - "address", - earlyOwnerAddress - ).slice(2)}`; - const oracleAggregatorComputedAddr = await deployerInstance.addressOf( - ORACLE_AGGREGATOR_SALT - ); - console.log( - "Chainlink Oracle Aggregator Computed Address: ", - oracleAggregatorComputedAddr - ); - - const isOracleAggregatorDeployed = await isContract( - oracleAggregatorComputedAddr, - provider - ); // true (deployed on-chain) - if (!isOracleAggregatorDeployed) { - try { - await deployContract( - DEPLOYMENT_SALTS.ORACLE_AGGREGATOR, - oracleAggregatorComputedAddr, - ORACLE_AGGREGATOR_SALT, - oracleAggregatorBytecode, - deployerInstance - ); - await delay(10000); - } catch (err) { - console.log("issue with the deployment"); - console.log(err); - return ethers.constants.AddressZero; - } - - try { - await run(`verify:verify`, { - address: oracleAggregatorComputedAddr, - constructorArguments: [earlyOwnerAddress], - }); - } catch (err) { - console.log("issue with the verification ", oracleAggregatorComputedAddr); - - return oracleAggregatorComputedAddr; - } - } else { - console.log( - "Chainlink Oracle Aggregator is already deployed with address ", - oracleAggregatorComputedAddr - ); - } - return oracleAggregatorComputedAddr; -} - -async function deployTokenPaymasterContract( - deployerInstance: Deployer, - earlyOwnerAddress: string -): Promise { - const salt = ethers.utils.keccak256( - ethers.utils.toUtf8Bytes(DEPLOYMENT_SALTS.TOKEN_PAYMASTER) - ); - - const BiconomyTokenPaymaster = await ethers.getContractFactory( - "BiconomyTokenPaymaster" - ); - const tokenPaymasterBytecode = `${ - BiconomyTokenPaymaster.bytecode - }${encodeParam("address", earlyOwnerAddress).slice(2)}${encodeParam( - "address", - entryPointAddress - ).slice(2)}${encodeParam("address", verifyingSigner).slice(2)}`; - - const tokenPaymasterComputedAddr = await deployerInstance.addressOf(salt); - console.log("Token paymaster Computed Address: ", tokenPaymasterComputedAddr); - const isContractDeployed = await isContract( - tokenPaymasterComputedAddr, - provider - ); - if (!isContractDeployed) { - try { - await deployContract( - DEPLOYMENT_SALTS.TOKEN_PAYMASTER, - tokenPaymasterComputedAddr, - salt, - tokenPaymasterBytecode, - deployerInstance - ); - await delay(5000); - } catch (err) { - console.log(err); - console.log("issue with the deployment"); - return ethers.constants.AddressZero; - } - try { - await run(`verify:verify`, { - address: tokenPaymasterComputedAddr, - constructorArguments: [ - earlyOwnerAddress, - entryPointAddress, - verifyingSigner, - ], - }); - } catch (err) { - console.log("issue with the verification ", tokenPaymasterComputedAddr); - - return tokenPaymasterComputedAddr; - } - } else { - console.log( - "Token Paymaster is Already deployed with address ", - tokenPaymasterComputedAddr - ); - } - return tokenPaymasterComputedAddr; -} - -async function deployDerivedPriceFeed( - deployerInstance: Deployer, - nativeOracleAddress: string, - tokenOracleAddress: string, - description: string, - feedSalt: string -): Promise { - const salt = ethers.utils.keccak256(ethers.utils.toUtf8Bytes(feedSalt)); - - const DerivedPriceFeed = await ethers.getContractFactory("DerivedPriceFeed"); - - const derivedPriceFeedBytecode = `${ - DerivedPriceFeed.bytecode - }${ethers.utils.defaultAbiCoder - .encode( - ["address", "address", "string"], - [nativeOracleAddress, tokenOracleAddress, description] - ) - .slice(2)}`; - - const derivedPriceFeedBComputedAddr = await deployerInstance.addressOf(salt); - console.log( - "Derived Price Feed Computed Address: ", - derivedPriceFeedBComputedAddr - ); - const isContractDeployed = await isContract( - derivedPriceFeedBComputedAddr, - provider - ); - if (!isContractDeployed) { - try { - await deployContract( - feedSalt, - derivedPriceFeedBComputedAddr, - salt, - derivedPriceFeedBytecode, - deployerInstance - ); - await delay(5000); - } catch (err) { - console.log(err); - console.log("issue with the deployment"); - return ethers.constants.AddressZero; - } - try { - await run(`verify:verify`, { - address: derivedPriceFeedBComputedAddr, - constructorArguments: [ - nativeOracleAddress, - tokenOracleAddress, - description, - ], - }); - } catch (err) { - console.log( - "issue with the verification ", - derivedPriceFeedBComputedAddr - ); - - return derivedPriceFeedBComputedAddr; - } - } else { - console.log( - "Derived Price Feed is Already deployed with address ", - derivedPriceFeedBComputedAddr - ); - } - return derivedPriceFeedBComputedAddr; -} - -async function setTokenOracle( - oracleAggregatorInstance: ChainlinkOracleAggregator, - tokenAddress: string, - priceFeedAddress: string, - priceFeedDecimals: number, - priceFeedFunctionName: string -) { - const PriceFeedContract = await ethers.getContractAt( - "FeedInterface", - priceFeedAddress - ); - - // Find the function ABI based on the provided function name - // @ts-ignore - const functionAbi = - PriceFeedContract.interface.functions[ - priceFeedFunctionName as keyof typeof PriceFeedContract.functions - ]; - - // Generate the function data based on the function ABI - const functionData = - PriceFeedContract.interface.encodeFunctionData(functionAbi); - - const tx = await oracleAggregatorInstance.setTokenOracle( - tokenAddress, - priceFeedAddress, - priceFeedDecimals, - functionData, - true - ); - const receipt = await tx.wait(); - console.log( - `Oracle set for ${tokenAddress} with tx hash ${receipt.transactionHash}` - ); -} - -/* - * This function is added to support the flow with pre-deploying the deployer contract - * using the `deployer-contract.deploy.ts` script. - */ -async function getPredeployedDeployerContractInstanceDEV(): Promise { - const code = await provider.getCode(DEPLOYER_CONTRACT_ADDRESS_DEV); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Deployer not deployed on chain ${chainId}, deploy it with deployer-contract.deploy.ts script before using this script.` - ); - throw new Error("Deployer not deployed"); - } else { - console.log( - "Deploying with EOA %s through Deployer Contract %s", - signer.address, - DEPLOYER_CONTRACT_ADDRESS_DEV - ); - return Deployer__factory.connect(DEPLOYER_CONTRACT_ADDRESS_DEV, signer); - } -} - -async function getPredeployedDeployerContractInstancePROD(): Promise { - const code = await provider.getCode(DEPLOYER_CONTRACT_ADDRESS_PROD); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Deployer not deployed on chain ${chainId}, deploy it with deployer-contract.deploy.ts script before using this script.` - ); - throw new Error("Deployer not deployed"); - } else { - console.log( - "Deploying with EOA %s through Deployer Contract %s", - signer.address, - DEPLOYER_CONTRACT_ADDRESS_PROD - ); - return Deployer__factory.connect(DEPLOYER_CONTRACT_ADDRESS_PROD, signer); - } -} - -async function getChainlinkOracleAggregatorContractInstance( - oracleAggregatorAddress: string -): Promise { - const code = await provider.getCode(oracleAggregatorAddress); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `ChainlinkOracleAggregator not deployed on chain ${chainId}, It should have been deployed as part of this script.` - ); - throw new Error("ChainlinkOracleAggregator not deployed"); - } else { - console.log( - "Returning instance connected with EOA %s and address %s", - signer.address, - oracleAggregatorAddress - ); - return ChainlinkOracleAggregator__factory.connect( - oracleAggregatorAddress, - signer - ); - } -} - -async function getTokenPaymasterContractInstance( - tokenPaymasterAddress: string -): Promise { - const code = await provider.getCode(tokenPaymasterAddress); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Biconomy Token Paymaster not deployed on chain ${chainId}, It should have been deployed as part of this script.` - ); - throw new Error("Biconomy Token Paymaster not deployed"); - } else { - console.log( - "Returning instance connected with EOA %s and address %s", - signer.address, - tokenPaymasterAddress - ); - return BiconomyTokenPaymaster__factory.connect( - tokenPaymasterAddress, - signer - ); - } -} - -async function main() { - let tx, receipt; - const provider = ethers.provider; - - const accounts = await ethers.getSigners(); - const earlyOwner = await accounts[0].getAddress(); - - const deployerInstanceDEV = await getPredeployedDeployerContractInstanceDEV(); - console.log("========================================="); - - const deployerInstancePROD = - await getPredeployedDeployerContractInstancePROD(); - console.log("========================================="); - - // 1. Deploy Chainlink Oracle Aggregator - // @note: owner is kept the deployer because we need to perform more actions on this contract using owner as part of other scripts - // @note: ownership should be transferred at the end - const oracleAggregatorAddress = await deployChainlinkOracleAggregatorContract( - deployerInstancePROD, - earlyOwner - ); - console.log( - "==================oracleAggregatorAddress=======================", - oracleAggregatorAddress - ); - await delay(5000); - - // 2. Deploy Token paymaster - const tokenPaymasterAddress = await deployTokenPaymasterContract( - deployerInstancePROD, - earlyOwner - ); - console.log( - "==================tokenPaymasterAddress=======================", - tokenPaymasterAddress - ); - await delay(5000); - - let oracleAggregatorInstance; - if (oracleAggregatorAddress) { - oracleAggregatorInstance = - await getChainlinkOracleAggregatorContractInstance( - oracleAggregatorAddress - ); - console.log( - "==================oracleAggregatorInstance=======================" - ); - } - - // 3a. Deploy the derived price feeds for all chainlink supported ERC20 tokens - for (const token of tokenConfig.tokens) { - const { - symbol, - address, - nativeOracleAddress, - tokenOracleAddress, - priceFeedAddress, - description, - priceFeedFunction, - feedSalt, - derivedFeed, - } = token; - let derivedPriceFeedAddress = priceFeedAddress; - - if (derivedPriceFeedAddress == "") { - derivedPriceFeedAddress = await deployDerivedPriceFeed( - deployerInstanceDEV, - nativeOracleAddress, - tokenOracleAddress, - description, - feedSalt - ); - console.log( - `==================${symbol} PriceFeedAddress=======================`, - derivedPriceFeedAddress - ); - await delay(5000); - } - - // Continue with other steps like setting token oracle, transferring ownership, etc. - // Use the derivedPriceFeedAddress and other token-specific information as needed - // ... - - // 4. Set token oracle on oracle aggregator - if (oracleAggregatorInstance) { - let feedAddress = derivedPriceFeedAddress; - if (priceFeedFunction == "latestAnswer()" || derivedFeed == false) { - feedAddress = priceFeedAddress; - } - // TODO - // This should not hardcode tokenOracleDeciamls to 18 - // It works in case of derived price feeds and chainlink feeds which are in the erc20 / native base and quote format. - await setTokenOracle( - oracleAggregatorInstance, - address, - feedAddress, - 18, - priceFeedFunction - ); - } - } - - if (tokenPaymasterAddress) { - // 5b. transfer ownership of token paymaster to the owner - const tokenPaymasterInstance = await getTokenPaymasterContractInstance( - tokenPaymasterAddress - ); - console.log( - "==================tokenPaymasterInstance=======================" - ); - - - } -} - -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); diff --git a/scripts/deploy-mumbai.ts b/scripts/deploy-mumbai.ts deleted file mode 100644 index d42b894..0000000 --- a/scripts/deploy-mumbai.ts +++ /dev/null @@ -1,483 +0,0 @@ -import { ethers, run, network } from "hardhat"; -import { mumbaiConfigInfoProd } from "./configs"; -import { Token, TokenConfig } from "./utils/Types"; -import { - deployContract, - DEPLOYMENT_SALTS, - encodeParam, - getDeployerInstance, - isContract, -} from "./utils"; -import { - BiconomyTokenPaymaster, - BiconomyTokenPaymaster__factory, - ChainlinkOracleAggregator, - ChainlinkOracleAggregator__factory, - Deployer, - Deployer__factory, -} from "../typechain-types"; - -const tokenConfig: TokenConfig = mumbaiConfigInfoProd; - -const provider = ethers.provider; -const entryPointAddress = - process.env.ENTRY_POINT_ADDRESS || - "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789"; -const owner = process.env.PAYMASTER_OWNER_ADDRESS_PROD || ""; -const verifyingSigner = process.env.PAYMASTER_SIGNER_ADDRESS_PROD || ""; -const DEPLOYER_CONTRACT_ADDRESS_DEV = - process.env.DEPLOYER_CONTRACT_ADDRESS_DEV || ""; -const DEPLOYER_CONTRACT_ADDRESS_PROD = - process.env.DEPLOYER_CONTRACT_ADDRESS_PROD || ""; - -function delay(ms: number) { - return new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, ms); - }); -} - -async function deployChainlinkOracleAggregatorContract( - deployerInstance: Deployer, - earlyOwnerAddress: string -): Promise { - const ORACLE_AGGREGATOR_SALT = ethers.utils.keccak256( - ethers.utils.toUtf8Bytes(DEPLOYMENT_SALTS.ORACLE_AGGREGATOR) - ); - - const OracleAggregator = await ethers.getContractFactory( - "ChainlinkOracleAggregator" - ); - const oracleAggregatorBytecode = `${OracleAggregator.bytecode}${encodeParam( - "address", - earlyOwnerAddress - ).slice(2)}`; - const oracleAggregatorComputedAddr = await deployerInstance.addressOf( - ORACLE_AGGREGATOR_SALT - ); - console.log( - "Chainlink Oracle Aggregator Computed Address: ", - oracleAggregatorComputedAddr - ); - - const isOracleAggregatorDeployed = await isContract( - oracleAggregatorComputedAddr, - provider - ); // true (deployed on-chain) - if (!isOracleAggregatorDeployed) { - try { - await deployContract( - DEPLOYMENT_SALTS.ORACLE_AGGREGATOR, - oracleAggregatorComputedAddr, - ORACLE_AGGREGATOR_SALT, - oracleAggregatorBytecode, - deployerInstance - ); - await delay(10000); - } catch (err) { - console.log("issue with the deployment"); - console.log(err); - return ethers.constants.AddressZero; - } - - try { - await run(`verify:verify`, { - address: oracleAggregatorComputedAddr, - constructorArguments: [earlyOwnerAddress], - }); - } catch (err) { - console.log("issue with the verification ", oracleAggregatorComputedAddr); - - return oracleAggregatorComputedAddr; - } - } else { - console.log( - "Chainlink Oracle Aggregator is already deployed with address ", - oracleAggregatorComputedAddr - ); - } - return oracleAggregatorComputedAddr; -} - -async function deployTokenPaymasterContract( - deployerInstance: Deployer, - earlyOwnerAddress: string -): Promise { - const salt = ethers.utils.keccak256( - ethers.utils.toUtf8Bytes(DEPLOYMENT_SALTS.TOKEN_PAYMASTER) - ); - - const BiconomyTokenPaymaster = await ethers.getContractFactory( - "BiconomyTokenPaymaster" - ); - const tokenPaymasterBytecode = `${ - BiconomyTokenPaymaster.bytecode - }${encodeParam("address", earlyOwnerAddress).slice(2)}${encodeParam( - "address", - entryPointAddress - ).slice(2)}${encodeParam("address", verifyingSigner).slice(2)}`; - - const tokenPaymasterComputedAddr = await deployerInstance.addressOf(salt); - console.log("Token paymaster Computed Address: ", tokenPaymasterComputedAddr); - const isContractDeployed = await isContract( - tokenPaymasterComputedAddr, - provider - ); - if (!isContractDeployed) { - try { - await deployContract( - DEPLOYMENT_SALTS.TOKEN_PAYMASTER, - tokenPaymasterComputedAddr, - salt, - tokenPaymasterBytecode, - deployerInstance - ); - await delay(5000); - } catch (err) { - console.log(err); - console.log("issue with the deployment"); - return ethers.constants.AddressZero; - } - try { - await run(`verify:verify`, { - address: tokenPaymasterComputedAddr, - constructorArguments: [ - earlyOwnerAddress, - entryPointAddress, - verifyingSigner, - ], - }); - } catch (err) { - console.log("issue with the verification ", tokenPaymasterComputedAddr); - - return tokenPaymasterComputedAddr; - } - } else { - console.log( - "Token Paymaster is Already deployed with address ", - tokenPaymasterComputedAddr - ); - } - return tokenPaymasterComputedAddr; -} - -async function deployDerivedPriceFeed( - deployerInstance: Deployer, - nativeOracleAddress: string, - tokenOracleAddress: string, - description: string, - feedSalt: string -): Promise { - const salt = ethers.utils.keccak256(ethers.utils.toUtf8Bytes(feedSalt)); - - const DerivedPriceFeed = await ethers.getContractFactory("DerivedPriceFeed"); - - const derivedPriceFeedBytecode = `${ - DerivedPriceFeed.bytecode - }${ethers.utils.defaultAbiCoder - .encode( - ["address", "address", "string"], - [nativeOracleAddress, tokenOracleAddress, description] - ) - .slice(2)}`; - - const derivedPriceFeedBComputedAddr = await deployerInstance.addressOf(salt); - console.log( - "Derived Price Feed Computed Address: ", - derivedPriceFeedBComputedAddr - ); - const isContractDeployed = await isContract( - derivedPriceFeedBComputedAddr, - provider - ); - if (!isContractDeployed) { - try { - await deployContract( - feedSalt, - derivedPriceFeedBComputedAddr, - salt, - derivedPriceFeedBytecode, - deployerInstance - ); - await delay(5000); - } catch (err) { - console.log(err); - console.log("issue with the deployment"); - return ethers.constants.AddressZero; - } - try { - await run(`verify:verify`, { - address: derivedPriceFeedBComputedAddr, - constructorArguments: [ - nativeOracleAddress, - tokenOracleAddress, - description, - ], - }); - } catch (err) { - console.log( - "issue with the verification ", - derivedPriceFeedBComputedAddr - ); - - return derivedPriceFeedBComputedAddr; - } - } else { - console.log( - "Derived Price Feed is Already deployed with address ", - derivedPriceFeedBComputedAddr - ); - } - return derivedPriceFeedBComputedAddr; -} - -async function setTokenOracle( - oracleAggregatorInstance: ChainlinkOracleAggregator, - tokenAddress: string, - priceFeedAddress: string, - priceFeedDecimals: number, - priceFeedFunctionName: string -) { - const PriceFeedContract = await ethers.getContractAt( - "FeedInterface", - priceFeedAddress - ); - - // Find the function ABI based on the provided function name - // @ts-ignore - const functionAbi = - PriceFeedContract.interface.functions[ - priceFeedFunctionName as keyof typeof PriceFeedContract.functions - ]; - - // Generate the function data based on the function ABI - const functionData = - PriceFeedContract.interface.encodeFunctionData(functionAbi); - - const tx = await oracleAggregatorInstance.setTokenOracle( - tokenAddress, - priceFeedAddress, - priceFeedDecimals, - functionData, - true - ); - const receipt = await tx.wait(); - console.log( - `Oracle set for ${tokenAddress} with tx hash ${receipt.transactionHash}` - ); -} - -/* - * This function is added to support the flow with pre-deploying the deployer contract - * using the `deployer-contract.deploy.ts` script. - */ -async function getPredeployedDeployerContractInstanceDEV(): Promise { - const code = await provider.getCode(DEPLOYER_CONTRACT_ADDRESS_DEV); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Deployer not deployed on chain ${chainId}, deploy it with deployer-contract.deploy.ts script before using this script.` - ); - throw new Error("Deployer not deployed"); - } else { - console.log( - "Deploying with EOA %s through Deployer Contract %s", - signer.address, - DEPLOYER_CONTRACT_ADDRESS_DEV - ); - return Deployer__factory.connect(DEPLOYER_CONTRACT_ADDRESS_DEV, signer); - } -} - -async function getPredeployedDeployerContractInstancePROD(): Promise { - const code = await provider.getCode(DEPLOYER_CONTRACT_ADDRESS_PROD); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Deployer not deployed on chain ${chainId}, deploy it with deployer-contract.deploy.ts script before using this script.` - ); - throw new Error("Deployer not deployed"); - } else { - console.log( - "Deploying with EOA %s through Deployer Contract %s", - signer.address, - DEPLOYER_CONTRACT_ADDRESS_PROD - ); - return Deployer__factory.connect(DEPLOYER_CONTRACT_ADDRESS_PROD, signer); - } -} - -async function getChainlinkOracleAggregatorContractInstance( - oracleAggregatorAddress: string -): Promise { - const code = await provider.getCode(oracleAggregatorAddress); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `ChainlinkOracleAggregator not deployed on chain ${chainId}, It should have been deployed as part of this script.` - ); - throw new Error("ChainlinkOracleAggregator not deployed"); - } else { - console.log( - "Returning instance connected with EOA %s and address %s", - signer.address, - oracleAggregatorAddress - ); - return ChainlinkOracleAggregator__factory.connect( - oracleAggregatorAddress, - signer - ); - } -} - -async function getTokenPaymasterContractInstance( - tokenPaymasterAddress: string -): Promise { - const code = await provider.getCode(tokenPaymasterAddress); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Biconomy Token Paymaster not deployed on chain ${chainId}, It should have been deployed as part of this script.` - ); - throw new Error("Biconomy Token Paymaster not deployed"); - } else { - console.log( - "Returning instance connected with EOA %s and address %s", - signer.address, - tokenPaymasterAddress - ); - return BiconomyTokenPaymaster__factory.connect( - tokenPaymasterAddress, - signer - ); - } -} - -async function main() { - let tx, receipt; - const provider = ethers.provider; - - const accounts = await ethers.getSigners(); - const earlyOwner = await accounts[0].getAddress(); - - const deployerInstanceDEV = await getPredeployedDeployerContractInstanceDEV(); - console.log("========================================="); - - const deployerInstancePROD = - await getPredeployedDeployerContractInstancePROD(); - console.log("========================================="); - - // 1. Deploy Chainlink Oracle Aggregator - // @note: owner is kept the deployer because we need to perform more actions on this contract using owner as part of other scripts - // @note: ownership should be transferred at the end - const oracleAggregatorAddress = await deployChainlinkOracleAggregatorContract( - deployerInstancePROD, - earlyOwner - ); - console.log( - "==================oracleAggregatorAddress=======================", - oracleAggregatorAddress - ); - await delay(5000); - - // 2. Deploy Token paymaster - const tokenPaymasterAddress = await deployTokenPaymasterContract( - deployerInstancePROD, - earlyOwner - ); - console.log( - "==================tokenPaymasterAddress=======================", - tokenPaymasterAddress - ); - await delay(5000); - - let oracleAggregatorInstance; - if (oracleAggregatorAddress) { - oracleAggregatorInstance = - await getChainlinkOracleAggregatorContractInstance( - oracleAggregatorAddress - ); - console.log( - "==================oracleAggregatorInstance=======================" - ); - } - - // 3a. Deploy the derived price feeds for all chainlink supported ERC20 tokens - for (const token of tokenConfig.tokens) { - const { - symbol, - address, - nativeOracleAddress, - tokenOracleAddress, - priceFeedAddress, - description, - priceFeedFunction, - feedSalt, - derivedFeed, - } = token; - let derivedPriceFeedAddress = priceFeedAddress; - - if (derivedPriceFeedAddress == "") { - derivedPriceFeedAddress = await deployDerivedPriceFeed( - deployerInstanceDEV, - nativeOracleAddress, - tokenOracleAddress, - description, - feedSalt - ); - console.log( - `==================${symbol} PriceFeedAddress=======================`, - derivedPriceFeedAddress - ); - await delay(5000); - } - - // Continue with other steps like setting token oracle, transferring ownership, etc. - // Use the derivedPriceFeedAddress and other token-specific information as needed - // ... - - // 4. Set token oracle on oracle aggregator - if (oracleAggregatorInstance) { - let feedAddress = derivedPriceFeedAddress; - if (priceFeedFunction == "latestAnswer()" || derivedFeed == false) { - feedAddress = priceFeedAddress; - } - // TODO - // This should not hardcode tokenOracleDeciamls to 18 - // It works in case of derived price feeds and chainlink feeds which are in the erc20 / native base and quote format. - await setTokenOracle( - oracleAggregatorInstance, - address, - feedAddress, - 18, - priceFeedFunction - ); - } - } - - if (tokenPaymasterAddress) { - // 5b. transfer ownership of token paymaster to the owner - const tokenPaymasterInstance = await getTokenPaymasterContractInstance( - tokenPaymasterAddress - ); - console.log( - "==================tokenPaymasterInstance=======================" - ); - - - } -} - -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); diff --git a/scripts/deploy-optimism-goerli.ts b/scripts/deploy-optimism-goerli.ts deleted file mode 100644 index b1886fd..0000000 --- a/scripts/deploy-optimism-goerli.ts +++ /dev/null @@ -1,483 +0,0 @@ -import { ethers, run, network } from "hardhat"; -import { optimismGoerliConfigInfoProd } from "./configs"; -import { Token, TokenConfig } from "./utils/Types"; -import { - deployContract, - DEPLOYMENT_SALTS, - encodeParam, - getDeployerInstance, - isContract, -} from "./utils"; -import { - BiconomyTokenPaymaster, - BiconomyTokenPaymaster__factory, - ChainlinkOracleAggregator, - ChainlinkOracleAggregator__factory, - Deployer, - Deployer__factory, -} from "../typechain-types"; - -const tokenConfig: TokenConfig = optimismGoerliConfigInfoProd; - -const provider = ethers.provider; -const entryPointAddress = - process.env.ENTRY_POINT_ADDRESS || - "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789"; -const owner = process.env.PAYMASTER_OWNER_ADDRESS_DEV || ""; -const verifyingSigner = process.env.PAYMASTER_SIGNER_ADDRESS_DEV || ""; -const DEPLOYER_CONTRACT_ADDRESS_DEV = - process.env.DEPLOYER_CONTRACT_ADDRESS_DEV || ""; -const DEPLOYER_CONTRACT_ADDRESS_PROD = - process.env.DEPLOYER_CONTRACT_ADDRESS_PROD || ""; - -function delay(ms: number) { - return new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, ms); - }); -} - -async function deployChainlinkOracleAggregatorContract( - deployerInstance: Deployer, - earlyOwnerAddress: string -): Promise { - const ORACLE_AGGREGATOR_SALT = ethers.utils.keccak256( - ethers.utils.toUtf8Bytes(DEPLOYMENT_SALTS.ORACLE_AGGREGATOR) - ); - - const OracleAggregator = await ethers.getContractFactory( - "ChainlinkOracleAggregator" - ); - const oracleAggregatorBytecode = `${OracleAggregator.bytecode}${encodeParam( - "address", - earlyOwnerAddress - ).slice(2)}`; - const oracleAggregatorComputedAddr = await deployerInstance.addressOf( - ORACLE_AGGREGATOR_SALT - ); - console.log( - "Chainlink Oracle Aggregator Computed Address: ", - oracleAggregatorComputedAddr - ); - - const isOracleAggregatorDeployed = await isContract( - oracleAggregatorComputedAddr, - provider - ); // true (deployed on-chain) - if (!isOracleAggregatorDeployed) { - try { - await deployContract( - DEPLOYMENT_SALTS.ORACLE_AGGREGATOR, - oracleAggregatorComputedAddr, - ORACLE_AGGREGATOR_SALT, - oracleAggregatorBytecode, - deployerInstance - ); - await delay(10000); - } catch (err) { - console.log("issue with the deployment"); - console.log(err); - return ethers.constants.AddressZero; - } - - try { - await run(`verify:verify`, { - address: oracleAggregatorComputedAddr, - constructorArguments: [earlyOwnerAddress], - }); - } catch (err) { - console.log("issue with the verification ", oracleAggregatorComputedAddr); - - return oracleAggregatorComputedAddr; - } - } else { - console.log( - "Chainlink Oracle Aggregator is already deployed with address ", - oracleAggregatorComputedAddr - ); - } - return oracleAggregatorComputedAddr; -} - -async function deployTokenPaymasterContract( - deployerInstance: Deployer, - earlyOwnerAddress: string -): Promise { - const salt = ethers.utils.keccak256( - ethers.utils.toUtf8Bytes(DEPLOYMENT_SALTS.TOKEN_PAYMASTER) - ); - - const BiconomyTokenPaymaster = await ethers.getContractFactory( - "BiconomyTokenPaymaster" - ); - const tokenPaymasterBytecode = `${ - BiconomyTokenPaymaster.bytecode - }${encodeParam("address", earlyOwnerAddress).slice(2)}${encodeParam( - "address", - entryPointAddress - ).slice(2)}${encodeParam("address", verifyingSigner).slice(2)}`; - - const tokenPaymasterComputedAddr = await deployerInstance.addressOf(salt); - console.log("Token paymaster Computed Address: ", tokenPaymasterComputedAddr); - const isContractDeployed = await isContract( - tokenPaymasterComputedAddr, - provider - ); - if (!isContractDeployed) { - try { - await deployContract( - DEPLOYMENT_SALTS.TOKEN_PAYMASTER, - tokenPaymasterComputedAddr, - salt, - tokenPaymasterBytecode, - deployerInstance - ); - await delay(5000); - } catch (err) { - console.log(err); - console.log("issue with the deployment"); - return ethers.constants.AddressZero; - } - try { - await run(`verify:verify`, { - address: tokenPaymasterComputedAddr, - constructorArguments: [ - earlyOwnerAddress, - entryPointAddress, - verifyingSigner, - ], - }); - } catch (err) { - console.log("issue with the verification ", tokenPaymasterComputedAddr); - - return tokenPaymasterComputedAddr; - } - } else { - console.log( - "Token Paymaster is Already deployed with address ", - tokenPaymasterComputedAddr - ); - } - return tokenPaymasterComputedAddr; -} - -async function deployDerivedPriceFeed( - deployerInstance: Deployer, - nativeOracleAddress: string, - tokenOracleAddress: string, - description: string, - feedSalt: string -): Promise { - const salt = ethers.utils.keccak256(ethers.utils.toUtf8Bytes(feedSalt)); - - const DerivedPriceFeed = await ethers.getContractFactory("DerivedPriceFeed"); - - const derivedPriceFeedBytecode = `${ - DerivedPriceFeed.bytecode - }${ethers.utils.defaultAbiCoder - .encode( - ["address", "address", "string"], - [nativeOracleAddress, tokenOracleAddress, description] - ) - .slice(2)}`; - - const derivedPriceFeedBComputedAddr = await deployerInstance.addressOf(salt); - console.log( - "Derived Price Feed Computed Address: ", - derivedPriceFeedBComputedAddr - ); - const isContractDeployed = await isContract( - derivedPriceFeedBComputedAddr, - provider - ); - if (!isContractDeployed) { - try { - await deployContract( - feedSalt, - derivedPriceFeedBComputedAddr, - salt, - derivedPriceFeedBytecode, - deployerInstance - ); - await delay(5000); - } catch (err) { - console.log(err); - console.log("issue with the deployment"); - return ethers.constants.AddressZero; - } - try { - await run(`verify:verify`, { - address: derivedPriceFeedBComputedAddr, - constructorArguments: [ - nativeOracleAddress, - tokenOracleAddress, - description, - ], - }); - } catch (err) { - console.log( - "issue with the verification ", - derivedPriceFeedBComputedAddr - ); - - return derivedPriceFeedBComputedAddr; - } - } else { - console.log( - "Derived Price Feed is Already deployed with address ", - derivedPriceFeedBComputedAddr - ); - } - return derivedPriceFeedBComputedAddr; -} - -async function setTokenOracle( - oracleAggregatorInstance: ChainlinkOracleAggregator, - tokenAddress: string, - priceFeedAddress: string, - priceFeedDecimals: number, - priceFeedFunctionName: string -) { - const PriceFeedContract = await ethers.getContractAt( - "FeedInterface", - priceFeedAddress - ); - - // Find the function ABI based on the provided function name - // @ts-ignore - const functionAbi = - PriceFeedContract.interface.functions[ - priceFeedFunctionName as keyof typeof PriceFeedContract.functions - ]; - - // Generate the function data based on the function ABI - const functionData = - PriceFeedContract.interface.encodeFunctionData(functionAbi); - - const tx = await oracleAggregatorInstance.setTokenOracle( - tokenAddress, - priceFeedAddress, - priceFeedDecimals, - functionData, - true - ); - const receipt = await tx.wait(); - console.log( - `Oracle set for ${tokenAddress} with tx hash ${receipt.transactionHash}` - ); -} - -/* - * This function is added to support the flow with pre-deploying the deployer contract - * using the `deployer-contract.deploy.ts` script. - */ -async function getPredeployedDeployerContractInstanceDEV(): Promise { - const code = await provider.getCode(DEPLOYER_CONTRACT_ADDRESS_DEV); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Deployer not deployed on chain ${chainId}, deploy it with deployer-contract.deploy.ts script before using this script.` - ); - throw new Error("Deployer not deployed"); - } else { - console.log( - "Deploying with EOA %s through Deployer Contract %s", - signer.address, - DEPLOYER_CONTRACT_ADDRESS_DEV - ); - return Deployer__factory.connect(DEPLOYER_CONTRACT_ADDRESS_DEV, signer); - } -} - -async function getPredeployedDeployerContractInstancePROD(): Promise { - const code = await provider.getCode(DEPLOYER_CONTRACT_ADDRESS_PROD); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Deployer not deployed on chain ${chainId}, deploy it with deployer-contract.deploy.ts script before using this script.` - ); - throw new Error("Deployer not deployed"); - } else { - console.log( - "Deploying with EOA %s through Deployer Contract %s", - signer.address, - DEPLOYER_CONTRACT_ADDRESS_PROD - ); - return Deployer__factory.connect(DEPLOYER_CONTRACT_ADDRESS_PROD, signer); - } -} - -async function getChainlinkOracleAggregatorContractInstance( - oracleAggregatorAddress: string -): Promise { - const code = await provider.getCode(oracleAggregatorAddress); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `ChainlinkOracleAggregator not deployed on chain ${chainId}, It should have been deployed as part of this script.` - ); - throw new Error("ChainlinkOracleAggregator not deployed"); - } else { - console.log( - "Returning instance connected with EOA %s and address %s", - signer.address, - oracleAggregatorAddress - ); - return ChainlinkOracleAggregator__factory.connect( - oracleAggregatorAddress, - signer - ); - } -} - -async function getTokenPaymasterContractInstance( - tokenPaymasterAddress: string -): Promise { - const code = await provider.getCode(tokenPaymasterAddress); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Biconomy Token Paymaster not deployed on chain ${chainId}, It should have been deployed as part of this script.` - ); - throw new Error("Biconomy Token Paymaster not deployed"); - } else { - console.log( - "Returning instance connected with EOA %s and address %s", - signer.address, - tokenPaymasterAddress - ); - return BiconomyTokenPaymaster__factory.connect( - tokenPaymasterAddress, - signer - ); - } -} - -async function main() { - let tx, receipt; - const provider = ethers.provider; - - const accounts = await ethers.getSigners(); - const earlyOwner = await accounts[0].getAddress(); - - const deployerInstanceDEV = await getPredeployedDeployerContractInstanceDEV(); - console.log("========================================="); - - const deployerInstancePROD = - await getPredeployedDeployerContractInstancePROD(); - console.log("========================================="); - - // 1. Deploy Chainlink Oracle Aggregator - // @note: owner is kept the deployer because we need to perform more actions on this contract using owner as part of other scripts - // @note: ownership should be transferred at the end - const oracleAggregatorAddress = await deployChainlinkOracleAggregatorContract( - deployerInstancePROD, - earlyOwner - ); - console.log( - "==================oracleAggregatorAddress=======================", - oracleAggregatorAddress - ); - await delay(5000); - - // 2. Deploy Token paymaster - const tokenPaymasterAddress = await deployTokenPaymasterContract( - deployerInstancePROD, - earlyOwner - ); - console.log( - "==================tokenPaymasterAddress=======================", - tokenPaymasterAddress - ); - await delay(5000); - - let oracleAggregatorInstance; - if (oracleAggregatorAddress) { - oracleAggregatorInstance = - await getChainlinkOracleAggregatorContractInstance( - oracleAggregatorAddress - ); - console.log( - "==================oracleAggregatorInstance=======================" - ); - } - - // 3a. Deploy the derived price feeds for all chainlink supported ERC20 tokens - for (const token of tokenConfig.tokens) { - const { - symbol, - address, - nativeOracleAddress, - tokenOracleAddress, - priceFeedAddress, - description, - priceFeedFunction, - feedSalt, - derivedFeed, - } = token; - let derivedPriceFeedAddress = priceFeedAddress; - - if (derivedPriceFeedAddress == "") { - derivedPriceFeedAddress = await deployDerivedPriceFeed( - deployerInstanceDEV, - nativeOracleAddress, - tokenOracleAddress, - description, - feedSalt - ); - console.log( - `==================${symbol} PriceFeedAddress=======================`, - derivedPriceFeedAddress - ); - await delay(5000); - } - - // Continue with other steps like setting token oracle, transferring ownership, etc. - // Use the derivedPriceFeedAddress and other token-specific information as needed - // ... - - // 4. Set token oracle on oracle aggregator - if (oracleAggregatorInstance) { - let feedAddress = derivedPriceFeedAddress; - if (priceFeedFunction == "latestAnswer()" || derivedFeed == false) { - feedAddress = priceFeedAddress; - } - // TODO - // This should not hardcode tokenOracleDeciamls to 18 - // It works in case of derived price feeds and chainlink feeds which are in the erc20 / native base and quote format. - await setTokenOracle( - oracleAggregatorInstance, - address, - feedAddress, - 18, - priceFeedFunction - ); - } - } - - if (tokenPaymasterAddress) { - // 5b. transfer ownership of token paymaster to the owner - const tokenPaymasterInstance = await getTokenPaymasterContractInstance( - tokenPaymasterAddress - ); - console.log( - "==================tokenPaymasterInstance=======================" - ); - - - } -} - -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); diff --git a/scripts/deploy-optimism-mainnet.ts b/scripts/deploy-optimism-mainnet.ts deleted file mode 100644 index 7672ad2..0000000 --- a/scripts/deploy-optimism-mainnet.ts +++ /dev/null @@ -1,481 +0,0 @@ -import { ethers, run, network } from "hardhat"; -import { optimismMainnetConfigInfoProd } from "./configs"; -import { Token, TokenConfig } from "./utils/Types"; -import { - deployContract, - DEPLOYMENT_SALTS, - encodeParam, - getDeployerInstance, - isContract, -} from "./utils"; -import { - BiconomyTokenPaymaster, - BiconomyTokenPaymaster__factory, - ChainlinkOracleAggregator, - ChainlinkOracleAggregator__factory, - Deployer, - Deployer__factory, -} from "../typechain-types"; - -const tokenConfig: TokenConfig = optimismMainnetConfigInfoProd; - -const provider = ethers.provider; -const entryPointAddress = - process.env.ENTRY_POINT_ADDRESS || - "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789"; -const owner = process.env.PAYMASTER_OWNER_ADDRESS_DEV || ""; -const verifyingSigner = process.env.PAYMASTER_SIGNER_ADDRESS_DEV || ""; -const DEPLOYER_CONTRACT_ADDRESS_DEV = - process.env.DEPLOYER_CONTRACT_ADDRESS_DEV || ""; -const DEPLOYER_CONTRACT_ADDRESS_PROD = - process.env.DEPLOYER_CONTRACT_ADDRESS_PROD || ""; - -function delay(ms: number) { - return new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, ms); - }); -} - -async function deployChainlinkOracleAggregatorContract( - deployerInstance: Deployer, - earlyOwnerAddress: string -): Promise { - const ORACLE_AGGREGATOR_SALT = ethers.utils.keccak256( - ethers.utils.toUtf8Bytes(DEPLOYMENT_SALTS.ORACLE_AGGREGATOR) - ); - - const OracleAggregator = await ethers.getContractFactory( - "ChainlinkOracleAggregator" - ); - const oracleAggregatorBytecode = `${OracleAggregator.bytecode}${encodeParam( - "address", - earlyOwnerAddress - ).slice(2)}`; - const oracleAggregatorComputedAddr = await deployerInstance.addressOf( - ORACLE_AGGREGATOR_SALT - ); - console.log( - "Chainlink Oracle Aggregator Computed Address: ", - oracleAggregatorComputedAddr - ); - - const isOracleAggregatorDeployed = await isContract( - oracleAggregatorComputedAddr, - provider - ); // true (deployed on-chain) - if (!isOracleAggregatorDeployed) { - try { - await deployContract( - DEPLOYMENT_SALTS.ORACLE_AGGREGATOR, - oracleAggregatorComputedAddr, - ORACLE_AGGREGATOR_SALT, - oracleAggregatorBytecode, - deployerInstance - ); - await delay(10000); - } catch (err) { - console.log("issue with the deployment"); - console.log(err); - return ethers.constants.AddressZero; - } - - try { - await run(`verify:verify`, { - address: oracleAggregatorComputedAddr, - constructorArguments: [earlyOwnerAddress], - }); - } catch (err) { - console.log("issue with the verification ", oracleAggregatorComputedAddr); - - return oracleAggregatorComputedAddr; - } - } else { - console.log( - "Chainlink Oracle Aggregator is already deployed with address ", - oracleAggregatorComputedAddr - ); - } - return oracleAggregatorComputedAddr; -} - -async function deployTokenPaymasterContract( - deployerInstance: Deployer, - earlyOwnerAddress: string -): Promise { - const salt = ethers.utils.keccak256( - ethers.utils.toUtf8Bytes(DEPLOYMENT_SALTS.TOKEN_PAYMASTER) - ); - - const BiconomyTokenPaymaster = await ethers.getContractFactory( - "BiconomyTokenPaymaster" - ); - const tokenPaymasterBytecode = `${ - BiconomyTokenPaymaster.bytecode - }${encodeParam("address", earlyOwnerAddress).slice(2)}${encodeParam( - "address", - entryPointAddress - ).slice(2)}${encodeParam("address", verifyingSigner).slice(2)}`; - - const tokenPaymasterComputedAddr = await deployerInstance.addressOf(salt); - console.log("Token paymaster Computed Address: ", tokenPaymasterComputedAddr); - const isContractDeployed = await isContract( - tokenPaymasterComputedAddr, - provider - ); - if (!isContractDeployed) { - try { - await deployContract( - DEPLOYMENT_SALTS.TOKEN_PAYMASTER, - tokenPaymasterComputedAddr, - salt, - tokenPaymasterBytecode, - deployerInstance - ); - await delay(10000); - } catch (err) { - console.log(err); - console.log("issue with the deployment"); - return ethers.constants.AddressZero; - } - try { - await run(`verify:verify`, { - address: tokenPaymasterComputedAddr, - constructorArguments: [ - earlyOwnerAddress, - entryPointAddress, - verifyingSigner, - ], - }); - } catch (err) { - console.log("issue with the verification ", tokenPaymasterComputedAddr); - - return tokenPaymasterComputedAddr; - } - } else { - console.log( - "Token Paymaster is Already deployed with address ", - tokenPaymasterComputedAddr - ); - } - return tokenPaymasterComputedAddr; -} - -async function deployDerivedPriceFeed( - deployerInstance: Deployer, - nativeOracleAddress: string, - tokenOracleAddress: string, - description: string, - feedSalt: string -): Promise { - const salt = ethers.utils.keccak256(ethers.utils.toUtf8Bytes(feedSalt)); - - const DerivedPriceFeed = await ethers.getContractFactory("DerivedPriceFeed"); - - const derivedPriceFeedBytecode = `${ - DerivedPriceFeed.bytecode - }${ethers.utils.defaultAbiCoder - .encode( - ["address", "address", "string"], - [nativeOracleAddress, tokenOracleAddress, description] - ) - .slice(2)}`; - - const derivedPriceFeedBComputedAddr = await deployerInstance.addressOf(salt); - console.log( - "Derived Price Feed Computed Address: ", - derivedPriceFeedBComputedAddr - ); - const isContractDeployed = await isContract( - derivedPriceFeedBComputedAddr, - provider - ); - if (!isContractDeployed) { - try { - await deployContract( - feedSalt, - derivedPriceFeedBComputedAddr, - salt, - derivedPriceFeedBytecode, - deployerInstance - ); - await delay(10000); - } catch (err) { - console.log(err); - console.log("issue with the deployment"); - return ethers.constants.AddressZero; - } - try { - await run(`verify:verify`, { - address: derivedPriceFeedBComputedAddr, - constructorArguments: [ - nativeOracleAddress, - tokenOracleAddress, - description, - ], - }); - } catch (err) { - console.log( - "issue with the verification ", - derivedPriceFeedBComputedAddr - ); - - return derivedPriceFeedBComputedAddr; - } - } else { - console.log( - "Derived Price Feed is Already deployed with address ", - derivedPriceFeedBComputedAddr - ); - } - return derivedPriceFeedBComputedAddr; -} - -async function setTokenOracle( - oracleAggregatorInstance: ChainlinkOracleAggregator, - tokenAddress: string, - priceFeedAddress: string, - priceFeedDecimals: number, - priceFeedFunctionName: string -) { - const PriceFeedContract = await ethers.getContractAt( - "FeedInterface", - priceFeedAddress - ); - - // Find the function ABI based on the provided function name - // @ts-ignore - const functionAbi = - PriceFeedContract.interface.functions[ - priceFeedFunctionName as keyof typeof PriceFeedContract.functions - ]; - - // Generate the function data based on the function ABI - const functionData = - PriceFeedContract.interface.encodeFunctionData(functionAbi); - - const tx = await oracleAggregatorInstance.setTokenOracle( - tokenAddress, - priceFeedAddress, - priceFeedDecimals, - functionData, - true - ); - const receipt = await tx.wait(); - console.log( - `Oracle set for ${tokenAddress} with tx hash ${receipt.transactionHash}` - ); -} - -/* - * This function is added to support the flow with pre-deploying the deployer contract - * using the `deployer-contract.deploy.ts` script. - */ -async function getPredeployedDeployerContractInstanceDEV(): Promise { - const code = await provider.getCode(DEPLOYER_CONTRACT_ADDRESS_DEV); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Deployer not deployed on chain ${chainId}, deploy it with deployer-contract.deploy.ts script before using this script.` - ); - throw new Error("Deployer not deployed"); - } else { - console.log( - "Deploying with EOA %s through Deployer Contract %s", - signer.address, - DEPLOYER_CONTRACT_ADDRESS_DEV - ); - return Deployer__factory.connect(DEPLOYER_CONTRACT_ADDRESS_DEV, signer); - } -} - -async function getPredeployedDeployerContractInstancePROD(): Promise { - const code = await provider.getCode(DEPLOYER_CONTRACT_ADDRESS_PROD); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Deployer not deployed on chain ${chainId}, deploy it with deployer-contract.deploy.ts script before using this script.` - ); - throw new Error("Deployer not deployed"); - } else { - console.log( - "Deploying with EOA %s through Deployer Contract %s", - signer.address, - DEPLOYER_CONTRACT_ADDRESS_PROD - ); - return Deployer__factory.connect(DEPLOYER_CONTRACT_ADDRESS_PROD, signer); - } -} - -async function getChainlinkOracleAggregatorContractInstance( - oracleAggregatorAddress: string -): Promise { - const code = await provider.getCode(oracleAggregatorAddress); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `ChainlinkOracleAggregator not deployed on chain ${chainId}, It should have been deployed as part of this script.` - ); - throw new Error("ChainlinkOracleAggregator not deployed"); - } else { - console.log( - "Returning instance connected with EOA %s and address %s", - signer.address, - oracleAggregatorAddress - ); - return ChainlinkOracleAggregator__factory.connect( - oracleAggregatorAddress, - signer - ); - } -} - -async function getTokenPaymasterContractInstance( - tokenPaymasterAddress: string -): Promise { - const code = await provider.getCode(tokenPaymasterAddress); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Biconomy Token Paymaster not deployed on chain ${chainId}, It should have been deployed as part of this script.` - ); - throw new Error("Biconomy Token Paymaster not deployed"); - } else { - console.log( - "Returning instance connected with EOA %s and address %s", - signer.address, - tokenPaymasterAddress - ); - return BiconomyTokenPaymaster__factory.connect( - tokenPaymasterAddress, - signer - ); - } -} - -async function main() { - let tx, receipt; - const provider = ethers.provider; - - const accounts = await ethers.getSigners(); - const earlyOwner = await accounts[0].getAddress(); - - const deployerInstanceDEV = await getPredeployedDeployerContractInstanceDEV(); - console.log("========================================="); - - const deployerInstancePROD = - await getPredeployedDeployerContractInstancePROD(); - console.log("========================================="); - - // 1. Deploy Chainlink Oracle Aggregator - // @note: owner is kept the deployer because we need to perform more actions on this contract using owner as part of other scripts - // @note: ownership should be transferred at the end - const oracleAggregatorAddress = await deployChainlinkOracleAggregatorContract( - deployerInstancePROD, - earlyOwner - ); - console.log( - "==================oracleAggregatorAddress=======================", - oracleAggregatorAddress - ); - await delay(10000); - - // 2. Deploy Token paymaster - const tokenPaymasterAddress = await deployTokenPaymasterContract( - deployerInstancePROD, - earlyOwner - ); - console.log( - "==================tokenPaymasterAddress=======================", - tokenPaymasterAddress - ); - await delay(10000); - - let oracleAggregatorInstance; - if (oracleAggregatorAddress) { - oracleAggregatorInstance = - await getChainlinkOracleAggregatorContractInstance( - oracleAggregatorAddress - ); - console.log( - "==================oracleAggregatorInstance=======================" - ); - } - - // 3a. Deploy the derived price feeds for all chainlink supported ERC20 tokens - for (const token of tokenConfig.tokens) { - const { - symbol, - address, - nativeOracleAddress, - tokenOracleAddress, - priceFeedAddress, - description, - priceFeedFunction, - feedSalt, - derivedFeed, - } = token; - let derivedPriceFeedAddress = priceFeedAddress; - - if (derivedPriceFeedAddress == "") { - derivedPriceFeedAddress = await deployDerivedPriceFeed( - deployerInstanceDEV, - nativeOracleAddress, - tokenOracleAddress, - description, - feedSalt - ); - console.log( - `==================${symbol} PriceFeedAddress=======================`, - derivedPriceFeedAddress - ); - await delay(10000); - } - - // Continue with other steps like setting token oracle, transferring ownership, etc. - // Use the derivedPriceFeedAddress and other token-specific information as needed - // ... - - // 4. Set token oracle on oracle aggregator - if (oracleAggregatorInstance) { - let feedAddress = derivedPriceFeedAddress; - if (priceFeedFunction == "latestAnswer()" || derivedFeed == false) { - feedAddress = priceFeedAddress; - } - // TODO - // This should not hardcode tokenOracleDeciamls to 18 - // It works in case of derived price feeds and chainlink feeds which are in the erc20 / native base and quote format. - await setTokenOracle( - oracleAggregatorInstance, - address, - feedAddress, - 18, - priceFeedFunction - ); - } - } - - if (tokenPaymasterAddress) { - // 5b. transfer ownership of token paymaster to the owner - const tokenPaymasterInstance = await getTokenPaymasterContractInstance( - tokenPaymasterAddress - ); - console.log( - "==================tokenPaymasterInstance=======================" - ); - } -} - -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); diff --git a/scripts/deploy-polygon-mainnet.ts b/scripts/deploy-polygon-mainnet.ts deleted file mode 100644 index ae79527..0000000 --- a/scripts/deploy-polygon-mainnet.ts +++ /dev/null @@ -1,486 +0,0 @@ -import { ethers, run, network } from "hardhat"; -import { polygonMainnetConfigInfoProd } from "./configs"; -import { Token, TokenConfig } from "./utils/Types"; -import { - deployContract, - DEPLOYMENT_SALTS, - encodeParam, - getDeployerInstance, - isContract, -} from "./utils"; -import { - BiconomyTokenPaymaster, - BiconomyTokenPaymaster__factory, - ChainlinkOracleAggregator, - ChainlinkOracleAggregator__factory, - Deployer, - Deployer__factory, -} from "../typechain-types"; - -const tokenConfig: TokenConfig = polygonMainnetConfigInfoProd; - -const provider = ethers.provider; -const entryPointAddress = - process.env.ENTRY_POINT_ADDRESS || - "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789"; -const owner = process.env.PAYMASTER_OWNER_ADDRESS_DEV || ""; -const verifyingSigner = process.env.PAYMASTER_SIGNER_ADDRESS_DEV || ""; -const DEPLOYER_CONTRACT_ADDRESS_DEV = - process.env.DEPLOYER_CONTRACT_ADDRESS_DEV || ""; -const DEPLOYER_CONTRACT_ADDRESS_PROD = - process.env.DEPLOYER_CONTRACT_ADDRESS_PROD || ""; - -function delay(ms: number) { - return new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, ms); - }); -} - -async function deployChainlinkOracleAggregatorContract( - deployerInstance: Deployer, - earlyOwnerAddress: string -): Promise { - const ORACLE_AGGREGATOR_SALT = ethers.utils.keccak256( - ethers.utils.toUtf8Bytes(DEPLOYMENT_SALTS.ORACLE_AGGREGATOR) - ); - - const OracleAggregator = await ethers.getContractFactory( - "ChainlinkOracleAggregator" - ); - const oracleAggregatorBytecode = `${OracleAggregator.bytecode}${encodeParam( - "address", - earlyOwnerAddress - ).slice(2)}`; - const oracleAggregatorComputedAddr = await deployerInstance.addressOf( - ORACLE_AGGREGATOR_SALT - ); - console.log( - "Chainlink Oracle Aggregator Computed Address: ", - oracleAggregatorComputedAddr - ); - - const isOracleAggregatorDeployed = await isContract( - oracleAggregatorComputedAddr, - provider - ); // true (deployed on-chain) - if (!isOracleAggregatorDeployed) { - try { - await deployContract( - DEPLOYMENT_SALTS.ORACLE_AGGREGATOR, - oracleAggregatorComputedAddr, - ORACLE_AGGREGATOR_SALT, - oracleAggregatorBytecode, - deployerInstance - ); - await delay(4000); - } catch (err) { - console.log("issue with the deployment"); - console.log(err); - return ethers.constants.AddressZero; - } - - try { - await run(`verify:verify`, { - address: oracleAggregatorComputedAddr, - constructorArguments: [earlyOwnerAddress], - }); - } catch (err) { - console.log("issue with the verification ", oracleAggregatorComputedAddr); - - return oracleAggregatorComputedAddr; - } - } else { - console.log( - "Chainlink Oracle Aggregator is already deployed with address ", - oracleAggregatorComputedAddr - ); - } - return oracleAggregatorComputedAddr; -} - -async function deployTokenPaymasterContract( - deployerInstance: Deployer, - earlyOwnerAddress: string -): Promise { - const salt = ethers.utils.keccak256( - ethers.utils.toUtf8Bytes(DEPLOYMENT_SALTS.TOKEN_PAYMASTER) - ); - - const BiconomyTokenPaymaster = await ethers.getContractFactory( - "BiconomyTokenPaymaster" - ); - const tokenPaymasterBytecode = `${ - BiconomyTokenPaymaster.bytecode - }${encodeParam("address", earlyOwnerAddress).slice(2)}${encodeParam( - "address", - entryPointAddress - ).slice(2)}${encodeParam("address", verifyingSigner).slice(2)}`; - - const tokenPaymasterComputedAddr = await deployerInstance.addressOf(salt); - console.log("Token paymaster Computed Address: ", tokenPaymasterComputedAddr); - const isContractDeployed = await isContract( - tokenPaymasterComputedAddr, - provider - ); - if (!isContractDeployed) { - try { - await deployContract( - DEPLOYMENT_SALTS.TOKEN_PAYMASTER, - tokenPaymasterComputedAddr, - salt, - tokenPaymasterBytecode, - deployerInstance - ); - await delay(4000); - } catch (err) { - console.log(err); - console.log("issue with the deployment"); - return ethers.constants.AddressZero; - } - try { - await run(`verify:verify`, { - address: tokenPaymasterComputedAddr, - constructorArguments: [ - earlyOwnerAddress, - entryPointAddress, - verifyingSigner, - ], - }); - } catch (err) { - console.log("issue with the verification ", tokenPaymasterComputedAddr); - - return tokenPaymasterComputedAddr; - } - } else { - console.log( - "Token Paymaster is Already deployed with address ", - tokenPaymasterComputedAddr - ); - } - return tokenPaymasterComputedAddr; -} - -async function deployDerivedPriceFeed( - deployerInstance: Deployer, - nativeOracleAddress: string, - tokenOracleAddress: string, - description: string, - feedSalt: string -): Promise { - const salt = ethers.utils.keccak256(ethers.utils.toUtf8Bytes(feedSalt)); - - const DerivedPriceFeed = await ethers.getContractFactory("DerivedPriceFeed"); - - const derivedPriceFeedBytecode = `${ - DerivedPriceFeed.bytecode - }${ethers.utils.defaultAbiCoder - .encode( - ["address", "address", "string"], - [nativeOracleAddress, tokenOracleAddress, description] - ) - .slice(2)}`; - - const derivedPriceFeedBComputedAddr = await deployerInstance.addressOf(salt); - console.log( - "Derived Price Feed Computed Address: ", - derivedPriceFeedBComputedAddr - ); - const isContractDeployed = await isContract( - derivedPriceFeedBComputedAddr, - provider - ); - if (!isContractDeployed) { - try { - await deployContract( - feedSalt, - derivedPriceFeedBComputedAddr, - salt, - derivedPriceFeedBytecode, - deployerInstance - ); - await delay(4000); - } catch (err) { - console.log(err); - console.log("issue with the deployment"); - return ethers.constants.AddressZero; - } - try { - await run(`verify:verify`, { - address: derivedPriceFeedBComputedAddr, - constructorArguments: [ - nativeOracleAddress, - tokenOracleAddress, - description, - ], - }); - } catch (err) { - console.log( - "issue with the verification ", - derivedPriceFeedBComputedAddr - ); - - return derivedPriceFeedBComputedAddr; - } - } else { - console.log( - "Derived Price Feed is Already deployed with address ", - derivedPriceFeedBComputedAddr - ); - } - return derivedPriceFeedBComputedAddr; -} - -async function setTokenOracle( - oracleAggregatorInstance: ChainlinkOracleAggregator, - tokenAddress: string, - priceFeedAddress: string, - priceFeedDecimals: number, - priceFeedFunctionName: string -) { - const PriceFeedContract = await ethers.getContractAt( - "FeedInterface", - priceFeedAddress - ); - - // Find the function ABI based on the provided function name - // @ts-ignore - const functionAbi = - PriceFeedContract.interface.functions[ - priceFeedFunctionName as keyof typeof PriceFeedContract.functions - ]; - - // Generate the function data based on the function ABI - const functionData = - PriceFeedContract.interface.encodeFunctionData(functionAbi); - - const tx = await oracleAggregatorInstance.setTokenOracle( - tokenAddress, - priceFeedAddress, - priceFeedDecimals, - functionData, - true - ); - const receipt = await tx.wait(); - console.log( - `Oracle set for ${tokenAddress} with tx hash ${receipt.transactionHash}` - ); -} - -/* - * This function is added to support the flow with pre-deploying the deployer contract - * using the `deployer-contract.deploy.ts` script. - */ -async function getPredeployedDeployerContractInstanceDEV(): Promise { - const code = await provider.getCode(DEPLOYER_CONTRACT_ADDRESS_DEV); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Deployer not deployed on chain ${chainId}, deploy it with deployer-contract.deploy.ts script before using this script.` - ); - throw new Error("Deployer not deployed"); - } else { - console.log( - "Deploying with EOA %s through Deployer Contract %s", - signer.address, - DEPLOYER_CONTRACT_ADDRESS_DEV - ); - return Deployer__factory.connect(DEPLOYER_CONTRACT_ADDRESS_DEV, signer); - } -} - -async function getPredeployedDeployerContractInstancePROD(): Promise { - const code = await provider.getCode(DEPLOYER_CONTRACT_ADDRESS_PROD); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Deployer not deployed on chain ${chainId}, deploy it with deployer-contract.deploy.ts script before using this script.` - ); - throw new Error("Deployer not deployed"); - } else { - console.log( - "Deploying with EOA %s through Deployer Contract %s", - signer.address, - DEPLOYER_CONTRACT_ADDRESS_PROD - ); - return Deployer__factory.connect(DEPLOYER_CONTRACT_ADDRESS_PROD, signer); - } -} - -async function getChainlinkOracleAggregatorContractInstance( - oracleAggregatorAddress: string -): Promise { - const code = await provider.getCode(oracleAggregatorAddress); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `ChainlinkOracleAggregator not deployed on chain ${chainId}, It should have been deployed as part of this script.` - ); - throw new Error("ChainlinkOracleAggregator not deployed"); - } else { - console.log( - "Returning instance connected with EOA %s and address %s", - signer.address, - oracleAggregatorAddress - ); - return ChainlinkOracleAggregator__factory.connect( - oracleAggregatorAddress, - signer - ); - } -} - -async function getTokenPaymasterContractInstance( - tokenPaymasterAddress: string -): Promise { - const code = await provider.getCode(tokenPaymasterAddress); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Biconomy Token Paymaster not deployed on chain ${chainId}, It should have been deployed as part of this script.` - ); - throw new Error("Biconomy Token Paymaster not deployed"); - } else { - console.log( - "Returning instance connected with EOA %s and address %s", - signer.address, - tokenPaymasterAddress - ); - return BiconomyTokenPaymaster__factory.connect( - tokenPaymasterAddress, - signer - ); - } -} - -async function main() { - let tx, receipt; - const provider = ethers.provider; - - const accounts = await ethers.getSigners(); - const earlyOwner = await accounts[0].getAddress(); - - const deployerInstanceDEV = await getPredeployedDeployerContractInstanceDEV(); - console.log("========================================="); - - const deployerInstancePROD = - await getPredeployedDeployerContractInstancePROD(); - console.log("========================================="); - - // 1. Deploy Chainlink Oracle Aggregator - // @note: owner is kept the deployer because we need to perform more actions on this contract using owner as part of other scripts - // @note: ownership should be transferred at the end - const oracleAggregatorAddress = await deployChainlinkOracleAggregatorContract( - deployerInstancePROD, - earlyOwner - ); - console.log( - "==================oracleAggregatorAddress=======================", - oracleAggregatorAddress - ); - await delay(4000); - - // 2. Deploy Token paymaster - const tokenPaymasterAddress = await deployTokenPaymasterContract( - deployerInstancePROD, - earlyOwner - ); - console.log( - "==================tokenPaymasterAddress=======================", - tokenPaymasterAddress - ); - await delay(4000); - - let oracleAggregatorInstance; - if (oracleAggregatorAddress) { - oracleAggregatorInstance = - await getChainlinkOracleAggregatorContractInstance( - oracleAggregatorAddress - ); - console.log( - "==================oracleAggregatorInstance=======================" - ); - } - - // 3a. Deploy the derived price feeds for all chainlink supported ERC20 tokens - for (const token of tokenConfig.tokens) { - const { - symbol, - address, - nativeOracleAddress, - tokenOracleAddress, - priceFeedAddress, - description, - priceFeedFunction, - feedSalt, - derivedFeed, - } = token; - let derivedPriceFeedAddress = priceFeedAddress; - console.log( - `derived price feed address for token ${symbol} is ${derivedPriceFeedAddress}` - ); - - if (derivedPriceFeedAddress == "") { - derivedPriceFeedAddress = await deployDerivedPriceFeed( - deployerInstanceDEV, - nativeOracleAddress, - tokenOracleAddress, - description, - feedSalt - ); - console.log( - `==================${symbol} PriceFeedAddress=======================`, - derivedPriceFeedAddress - ); - await delay(4000); - } - - // Continue with other steps like setting token oracle, transferring ownership, etc. - // Use the derivedPriceFeedAddress and other token-specific information as needed - // ... - - // 4. Set token oracle on oracle aggregator - if (oracleAggregatorInstance) { - let feedAddress = derivedPriceFeedAddress; - if (priceFeedFunction == "latestAnswer()" || derivedFeed == false) { - feedAddress = priceFeedAddress; - } - // TODO - // This should not hardcode tokenOracleDeciamls to 18 - // It works in case of derived price feeds and chainlink feeds which are in the erc20 / native base and quote format. - await setTokenOracle( - oracleAggregatorInstance, - address, - feedAddress, - 18, - priceFeedFunction - ); - } - } - - if (tokenPaymasterAddress) { - // 5b. transfer ownership of token paymaster to the owner - const tokenPaymasterInstance = await getTokenPaymasterContractInstance( - tokenPaymasterAddress - ); - console.log( - "==================tokenPaymasterInstance=======================" - ); - - - } -} - -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); diff --git a/scripts/deploy-sepolia.ts b/scripts/deploy-sepolia.ts deleted file mode 100644 index e4a197b..0000000 --- a/scripts/deploy-sepolia.ts +++ /dev/null @@ -1,483 +0,0 @@ -import { ethers, run, network } from "hardhat"; -import { sepoliaConfigInfoProd } from "./configs"; -import { Token, TokenConfig } from "./utils/Types"; -import { - deployContract, - DEPLOYMENT_SALTS, - encodeParam, - getDeployerInstance, - isContract, -} from "./utils"; -import { - BiconomyTokenPaymaster, - BiconomyTokenPaymaster__factory, - ChainlinkOracleAggregator, - ChainlinkOracleAggregator__factory, - Deployer, - Deployer__factory, -} from "../typechain-types"; - -const tokenConfig: TokenConfig = sepoliaConfigInfoProd; - -const provider = ethers.provider; -const entryPointAddress = - process.env.ENTRY_POINT_ADDRESS || - "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789"; -const owner = process.env.PAYMASTER_OWNER_ADDRESS_DEV || ""; -const verifyingSigner = process.env.PAYMASTER_SIGNER_ADDRESS_DEV || ""; -const DEPLOYER_CONTRACT_ADDRESS_DEV = - process.env.DEPLOYER_CONTRACT_ADDRESS_DEV || ""; -const DEPLOYER_CONTRACT_ADDRESS_PROD = - process.env.DEPLOYER_CONTRACT_ADDRESS_PROD || ""; - -function delay(ms: number) { - return new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, ms); - }); -} - -async function deployChainlinkOracleAggregatorContract( - deployerInstance: Deployer, - earlyOwnerAddress: string -): Promise { - const ORACLE_AGGREGATOR_SALT = ethers.utils.keccak256( - ethers.utils.toUtf8Bytes(DEPLOYMENT_SALTS.ORACLE_AGGREGATOR) - ); - - const OracleAggregator = await ethers.getContractFactory( - "ChainlinkOracleAggregator" - ); - const oracleAggregatorBytecode = `${OracleAggregator.bytecode}${encodeParam( - "address", - earlyOwnerAddress - ).slice(2)}`; - const oracleAggregatorComputedAddr = await deployerInstance.addressOf( - ORACLE_AGGREGATOR_SALT - ); - console.log( - "Chainlink Oracle Aggregator Computed Address: ", - oracleAggregatorComputedAddr - ); - - const isOracleAggregatorDeployed = await isContract( - oracleAggregatorComputedAddr, - provider - ); // true (deployed on-chain) - if (!isOracleAggregatorDeployed) { - try { - await deployContract( - DEPLOYMENT_SALTS.ORACLE_AGGREGATOR, - oracleAggregatorComputedAddr, - ORACLE_AGGREGATOR_SALT, - oracleAggregatorBytecode, - deployerInstance - ); - await delay(10000); - } catch (err) { - console.log("issue with the deployment"); - console.log(err); - return ethers.constants.AddressZero; - } - - try { - await run(`verify:verify`, { - address: oracleAggregatorComputedAddr, - constructorArguments: [earlyOwnerAddress], - }); - } catch (err) { - console.log("issue with the verification ", oracleAggregatorComputedAddr); - - return oracleAggregatorComputedAddr; - } - } else { - console.log( - "Chainlink Oracle Aggregator is already deployed with address ", - oracleAggregatorComputedAddr - ); - } - return oracleAggregatorComputedAddr; -} - -async function deployTokenPaymasterContract( - deployerInstance: Deployer, - earlyOwnerAddress: string -): Promise { - const salt = ethers.utils.keccak256( - ethers.utils.toUtf8Bytes(DEPLOYMENT_SALTS.TOKEN_PAYMASTER) - ); - - const BiconomyTokenPaymaster = await ethers.getContractFactory( - "BiconomyTokenPaymaster" - ); - const tokenPaymasterBytecode = `${ - BiconomyTokenPaymaster.bytecode - }${encodeParam("address", earlyOwnerAddress).slice(2)}${encodeParam( - "address", - entryPointAddress - ).slice(2)}${encodeParam("address", verifyingSigner).slice(2)}`; - - const tokenPaymasterComputedAddr = await deployerInstance.addressOf(salt); - console.log("Token paymaster Computed Address: ", tokenPaymasterComputedAddr); - const isContractDeployed = await isContract( - tokenPaymasterComputedAddr, - provider - ); - if (!isContractDeployed) { - try { - await deployContract( - DEPLOYMENT_SALTS.TOKEN_PAYMASTER, - tokenPaymasterComputedAddr, - salt, - tokenPaymasterBytecode, - deployerInstance - ); - await delay(5000); - } catch (err) { - console.log(err); - console.log("issue with the deployment"); - return ethers.constants.AddressZero; - } - try { - await run(`verify:verify`, { - address: tokenPaymasterComputedAddr, - constructorArguments: [ - earlyOwnerAddress, - entryPointAddress, - verifyingSigner, - ], - }); - } catch (err) { - console.log("issue with the verification ", tokenPaymasterComputedAddr); - - return tokenPaymasterComputedAddr; - } - } else { - console.log( - "Token Paymaster is Already deployed with address ", - tokenPaymasterComputedAddr - ); - } - return tokenPaymasterComputedAddr; -} - -async function deployDerivedPriceFeed( - deployerInstance: Deployer, - nativeOracleAddress: string, - tokenOracleAddress: string, - description: string, - feedSalt: string -): Promise { - const salt = ethers.utils.keccak256(ethers.utils.toUtf8Bytes(feedSalt)); - - const DerivedPriceFeed = await ethers.getContractFactory("DerivedPriceFeed"); - - const derivedPriceFeedBytecode = `${ - DerivedPriceFeed.bytecode - }${ethers.utils.defaultAbiCoder - .encode( - ["address", "address", "string"], - [nativeOracleAddress, tokenOracleAddress, description] - ) - .slice(2)}`; - - const derivedPriceFeedBComputedAddr = await deployerInstance.addressOf(salt); - console.log( - "Derived Price Feed Computed Address: ", - derivedPriceFeedBComputedAddr - ); - const isContractDeployed = await isContract( - derivedPriceFeedBComputedAddr, - provider - ); - if (!isContractDeployed) { - try { - await deployContract( - feedSalt, - derivedPriceFeedBComputedAddr, - salt, - derivedPriceFeedBytecode, - deployerInstance - ); - await delay(5000); - } catch (err) { - console.log(err); - console.log("issue with the deployment"); - return ethers.constants.AddressZero; - } - try { - await run(`verify:verify`, { - address: derivedPriceFeedBComputedAddr, - constructorArguments: [ - nativeOracleAddress, - tokenOracleAddress, - description, - ], - }); - } catch (err) { - console.log( - "issue with the verification ", - derivedPriceFeedBComputedAddr - ); - - return derivedPriceFeedBComputedAddr; - } - } else { - console.log( - "Derived Price Feed is Already deployed with address ", - derivedPriceFeedBComputedAddr - ); - } - return derivedPriceFeedBComputedAddr; -} - -async function setTokenOracle( - oracleAggregatorInstance: ChainlinkOracleAggregator, - tokenAddress: string, - priceFeedAddress: string, - priceFeedDecimals: number, - priceFeedFunctionName: string -) { - const PriceFeedContract = await ethers.getContractAt( - "FeedInterface", - priceFeedAddress - ); - - // Find the function ABI based on the provided function name - // @ts-ignore - const functionAbi = - PriceFeedContract.interface.functions[ - priceFeedFunctionName as keyof typeof PriceFeedContract.functions - ]; - - // Generate the function data based on the function ABI - const functionData = - PriceFeedContract.interface.encodeFunctionData(functionAbi); - - const tx = await oracleAggregatorInstance.setTokenOracle( - tokenAddress, - priceFeedAddress, - priceFeedDecimals, - functionData, - true - ); - const receipt = await tx.wait(); - console.log( - `Oracle set for ${tokenAddress} with tx hash ${receipt.transactionHash}` - ); -} - -/* - * This function is added to support the flow with pre-deploying the deployer contract - * using the `deployer-contract.deploy.ts` script. - */ -async function getPredeployedDeployerContractInstanceDEV(): Promise { - const code = await provider.getCode(DEPLOYER_CONTRACT_ADDRESS_DEV); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Deployer not deployed on chain ${chainId}, deploy it with deployer-contract.deploy.ts script before using this script.` - ); - throw new Error("Deployer not deployed"); - } else { - console.log( - "Deploying with EOA %s through Deployer Contract %s", - signer.address, - DEPLOYER_CONTRACT_ADDRESS_DEV - ); - return Deployer__factory.connect(DEPLOYER_CONTRACT_ADDRESS_DEV, signer); - } -} - -async function getPredeployedDeployerContractInstancePROD(): Promise { - const code = await provider.getCode(DEPLOYER_CONTRACT_ADDRESS_PROD); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Deployer not deployed on chain ${chainId}, deploy it with deployer-contract.deploy.ts script before using this script.` - ); - throw new Error("Deployer not deployed"); - } else { - console.log( - "Deploying with EOA %s through Deployer Contract %s", - signer.address, - DEPLOYER_CONTRACT_ADDRESS_PROD - ); - return Deployer__factory.connect(DEPLOYER_CONTRACT_ADDRESS_PROD, signer); - } -} - -async function getChainlinkOracleAggregatorContractInstance( - oracleAggregatorAddress: string -): Promise { - const code = await provider.getCode(oracleAggregatorAddress); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `ChainlinkOracleAggregator not deployed on chain ${chainId}, It should have been deployed as part of this script.` - ); - throw new Error("ChainlinkOracleAggregator not deployed"); - } else { - console.log( - "Returning instance connected with EOA %s and address %s", - signer.address, - oracleAggregatorAddress - ); - return ChainlinkOracleAggregator__factory.connect( - oracleAggregatorAddress, - signer - ); - } -} - -async function getTokenPaymasterContractInstance( - tokenPaymasterAddress: string -): Promise { - const code = await provider.getCode(tokenPaymasterAddress); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Biconomy Token Paymaster not deployed on chain ${chainId}, It should have been deployed as part of this script.` - ); - throw new Error("Biconomy Token Paymaster not deployed"); - } else { - console.log( - "Returning instance connected with EOA %s and address %s", - signer.address, - tokenPaymasterAddress - ); - return BiconomyTokenPaymaster__factory.connect( - tokenPaymasterAddress, - signer - ); - } -} - -async function main() { - let tx, receipt; - const provider = ethers.provider; - - const accounts = await ethers.getSigners(); - const earlyOwner = await accounts[0].getAddress(); - - const deployerInstanceDEV = await getPredeployedDeployerContractInstanceDEV(); - console.log("========================================="); - - const deployerInstancePROD = - await getPredeployedDeployerContractInstancePROD(); - console.log("========================================="); - - // 1. Deploy Chainlink Oracle Aggregator - // @note: owner is kept the deployer because we need to perform more actions on this contract using owner as part of other scripts - // @note: ownership should be transferred at the end - const oracleAggregatorAddress = await deployChainlinkOracleAggregatorContract( - deployerInstancePROD, - earlyOwner - ); - console.log( - "==================oracleAggregatorAddress=======================", - oracleAggregatorAddress - ); - await delay(5000); - - // 2. Deploy Token paymaster - const tokenPaymasterAddress = await deployTokenPaymasterContract( - deployerInstancePROD, - earlyOwner - ); - console.log( - "==================tokenPaymasterAddress=======================", - tokenPaymasterAddress - ); - await delay(5000); - - let oracleAggregatorInstance; - if (oracleAggregatorAddress) { - oracleAggregatorInstance = - await getChainlinkOracleAggregatorContractInstance( - oracleAggregatorAddress - ); - console.log( - "==================oracleAggregatorInstance=======================" - ); - } - - // 3a. Deploy the derived price feeds for all chainlink supported ERC20 tokens - for (const token of tokenConfig.tokens) { - const { - symbol, - address, - nativeOracleAddress, - tokenOracleAddress, - priceFeedAddress, - description, - priceFeedFunction, - feedSalt, - derivedFeed, - } = token; - let derivedPriceFeedAddress = priceFeedAddress; - - if (derivedPriceFeedAddress == "") { - derivedPriceFeedAddress = await deployDerivedPriceFeed( - deployerInstanceDEV, - nativeOracleAddress, - tokenOracleAddress, - description, - feedSalt - ); - console.log( - `==================${symbol} PriceFeedAddress=======================`, - derivedPriceFeedAddress - ); - await delay(5000); - } - - // Continue with other steps like setting token oracle, transferring ownership, etc. - // Use the derivedPriceFeedAddress and other token-specific information as needed - // ... - - // 4. Set token oracle on oracle aggregator - if (oracleAggregatorInstance) { - let feedAddress = derivedPriceFeedAddress; - if (priceFeedFunction == "latestAnswer()" || derivedFeed == false) { - feedAddress = priceFeedAddress; - } - // TODO - // This should not hardcode tokenOracleDeciamls to 18 - // It works in case of derived price feeds and chainlink feeds which are in the erc20 / native base and quote format. - await setTokenOracle( - oracleAggregatorInstance, - address, - feedAddress, - 18, - priceFeedFunction - ); - } - } - - if (tokenPaymasterAddress) { - // 5b. transfer ownership of token paymaster to the owner - const tokenPaymasterInstance = await getTokenPaymasterContractInstance( - tokenPaymasterAddress - ); - console.log( - "==================tokenPaymasterInstance=======================" - ); - - - } -} - -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); diff --git a/scripts/gas-calcs/deploy-sample-paymaster.ts b/scripts/gas-calcs/deploy-sample-paymaster.ts index 19c64fe..076188e 100644 --- a/scripts/gas-calcs/deploy-sample-paymaster.ts +++ b/scripts/gas-calcs/deploy-sample-paymaster.ts @@ -7,6 +7,9 @@ async function main() { const accounts = await ethers.getSigners(); const earlyOwner = await accounts[0].getAddress(); + if (earlyOwner === undefined) { + throw new Error("earlyOwner is undefined"); + } const verifyingSigner = "0x37ca4D86A0e33502F7CD93e0C88AFa2F172d39a1"; const entryPoint = process.env.ENTRY_POINT_ADDRESS || diff --git a/scripts/set-token-oracle-chainlink-aggregator.ts b/scripts/set-token-oracle-chainlink-aggregator.ts deleted file mode 100644 index d6f5593..0000000 --- a/scripts/set-token-oracle-chainlink-aggregator.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { ethers } from "hardhat"; - -function delay(ms: number) { - return new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, ms); - }); -} - -// WIP on existing oracle aggregator given price feeds are already deployed go ahead and set oracle aggregator - -async function main() { - let tx, receipt; - const provider = ethers.provider; - - // Polygon Mainnet example - - const chainlinkAggregatorAddress = - "0xDc1c19fB74aC9dD6C7b1fafb7bF604F8277e4927"; - - // example - const sandAddress = "0xBbba073C31bF03b8ACf7c28EF0738DeCF3695683"; - const sandPriceFeedAddress = "0x985eBa99eB4612B97E94060bBc582B209c7Be28d"; - - const gasPrices = { maxFeePerGas: 250e9, maxPriorityFeePerGas: 80e9 }; - const oracleAggregator = await ethers.getContractAt( - "contracts/token/oracles/ChainlinkOracleAggregator.sol:ChainlinkOracleAggregator", - chainlinkAggregatorAddress - ); - - const priceFeedSand = await ethers.getContractAt( - "FeedInterface", - sandPriceFeedAddress - ); - - const priceFeedTxSand: any = - await priceFeedSand.populateTransaction.getThePrice(); - - console.log("priceFeedTxSand ", priceFeedTxSand); - - tx = await oracleAggregator.setTokenOracle( - sandAddress, - sandPriceFeedAddress, - 18, - priceFeedTxSand.data, - true - ); - receipt = await tx.wait(); - console.log("Oracle set for SAND"); - await delay(10000); -} - -// We recommend this pattern to be able to use async/await everywhere -// and properly handle errors. -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); diff --git a/scripts/token-paymaster-v2/deploy-token-paymaster-mumbai.ts b/scripts/token-paymaster-v2/deploy-token-paymaster-mumbai.ts new file mode 100644 index 0000000..5df02f5 --- /dev/null +++ b/scripts/token-paymaster-v2/deploy-token-paymaster-mumbai.ts @@ -0,0 +1,238 @@ +import { ethers, run } from "hardhat"; +import { + deployContract, + DEPLOYMENT_SALTS, + encodeParam, + isContract, + delay, +} from "../utils"; +import { + BiconomyTokenPaymaster, + BiconomyTokenPaymaster__factory, + Deployer, + Deployer__factory, +} from "../../typechain-types"; +import { mumbaiConfigInfoProd } from "../configs"; +import { TokenConfig } from "../utils/Types"; + +// TODO : add chainId key in config.json and make it unified +// filter based on chain and make single script based on chainId +const tokenConfig: TokenConfig = mumbaiConfigInfoProd; + +const provider = ethers.provider; +const contractsDeployed: Record = {}; +const entryPointAddress = + process.env.ENTRY_POINT_ADDRESS || + "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789"; +const verifyingSigner = process.env.PAYMASTER_SIGNER_ADDRESS_PROD || ""; +const DEPLOYER_CONTRACT_ADDRESS = + process.env.DEPLOYER_CONTRACT_ADDRESS_PROD || ""; + +export async function deployGeneric( + deployerInstance: Deployer, + salt: string, + bytecode: string, + contractName: string, + constructorArguments: any[] +): Promise { + try { + const derivedSalt = ethers.utils.keccak256(ethers.utils.toUtf8Bytes(salt)); + const computedAddress = await deployerInstance.addressOf(derivedSalt); + + console.log(`${contractName} Computed Address: ${computedAddress}`); + + const isDeployed = await isContract(computedAddress, provider); // true (deployed on-chain) + if (!isDeployed) { + await deployContract( + salt, + computedAddress, + derivedSalt, + bytecode, + deployerInstance + ); + } else { + console.log( + `${contractName} is Already deployed with address ${computedAddress}` + ); + } + + await delay(10000); + + try { + await run("verify:verify", { + address: computedAddress, + constructorArguments, + }); + } catch (err) { + console.log(err); + } + + contractsDeployed[contractName] = computedAddress; + + return computedAddress; + } catch (err) { + console.log(err); + return ""; + } +} + +async function deployTokenPaymasterContract( + deployerInstance: Deployer, + earlyOwnerAddress: string +): Promise { + try { + const tokenPaymasterAddress = await deployGeneric( + deployerInstance, + DEPLOYMENT_SALTS.TOKEN_PAYMASTER_V2, + `${BiconomyTokenPaymaster__factory.bytecode}${encodeParam( + "address", + earlyOwnerAddress + ).slice(2)}${encodeParam("address", entryPointAddress).slice( + 2 + )}${encodeParam("address", verifyingSigner).slice(2)}`, + "BiconomyTokenPaymasterV2", + [earlyOwnerAddress, entryPointAddress, verifyingSigner] + ); + return tokenPaymasterAddress; + } catch (err) { + console.log(err); + } +} + +/* + * This function is added to support the flow with pre-deploying the deployer contract + * using the `deployer-contract.deploy.ts` script. + */ +async function getPredeployedDeployerContractInstance(): Promise { + const code = await provider.getCode(DEPLOYER_CONTRACT_ADDRESS); + const chainId = (await provider.getNetwork()).chainId; + const [signer] = await ethers.getSigners(); + + if (code === "0x") { + console.log( + `Deployer not deployed on chain ${chainId}, deploy it with deployer-contract.deploy.ts script before using this script.` + ); + throw new Error("Deployer not deployed"); + } else { + console.log( + "Deploying with EOA %s through Deployer Contract %s", + signer.address, + DEPLOYER_CONTRACT_ADDRESS + ); + return Deployer__factory.connect(DEPLOYER_CONTRACT_ADDRESS, signer); + } +} + +async function setTokenOracle( + tokenPaymasterInstance: BiconomyTokenPaymaster, + tokenAddress: string, + tokenOracle: string, + nativeOracle: string, + isDerivedFeed: boolean, + priceUpdateThreshold: number = 172800 // 2 days +) { + // Connect as the owner of the token paymaster + const tx = await tokenPaymasterInstance.setTokenOracle( + tokenAddress, + tokenOracle, + nativeOracle, + isDerivedFeed, + priceUpdateThreshold + ); + const receipt = await tx.wait(); + console.log( + `Oracle set for ${tokenAddress} with tx hash ${receipt.transactionHash}` + ); +} + +async function getTokenPaymasterContractInstance( + tokenPaymasterAddress: string +): Promise { + const code = await provider.getCode(tokenPaymasterAddress); + const chainId = (await provider.getNetwork()).chainId; + const [signer] = await ethers.getSigners(); + + if (code === "0x") { + console.log( + `Biconomy Token Paymaster not deployed on chain ${chainId}, It should have been deployed as part of this script.` + ); + throw new Error("Biconomy Token Paymaster not deployed"); + } else { + console.log( + "Returning instance connected with EOA %s and address %s", + signer.address, + tokenPaymasterAddress + ); + return BiconomyTokenPaymaster__factory.connect( + tokenPaymasterAddress, + signer + ); + } +} + +async function main() { + const accounts = await ethers.getSigners(); + const earlyOwner = await accounts[0].getAddress(); + if (earlyOwner === undefined) { + throw new Error("earlyOwner is undefined"); + } + + const deployerInstance = await getPredeployedDeployerContractInstance(); + console.log("========================================="); + + // Deploy Token paymaster + const tokenPaymasterAddress = await deployTokenPaymasterContract( + deployerInstance, + earlyOwner + ); + console.log( + "==================tokenPaymasterAddress=======================", + tokenPaymasterAddress + ); + + let tokenPaymasterInstance; + if (tokenPaymasterAddress) { + tokenPaymasterInstance = await getTokenPaymasterContractInstance( + tokenPaymasterAddress + ); + console.log( + "==================tokenPaymasterInstance=======================" + ); + } + + for (const token of tokenConfig.tokens) { + // Note: In the config priceFeedAddress becomes the tokenOracleAddress + const { + // symbol, + address, + nativeOracleAddress, + tokenOracleAddress, + derivedFeed, + } = token; + + let priceUpdateThreshold = token.priceUpdateThreshold; + + if (priceUpdateThreshold === null || priceUpdateThreshold === undefined) { + priceUpdateThreshold = 172800; // 2 days default + } + + if (!address) { + throw new Error("token address can not be undefined"); + } + if (tokenPaymasterInstance) { + await setTokenOracle( + tokenPaymasterInstance, + address, + nativeOracleAddress, + tokenOracleAddress, + derivedFeed, + priceUpdateThreshold + ); + } + } +} + +main().catch((error) => { + console.error(error); + process.exitCode = 1; +}); diff --git a/scripts/utils/Types.ts b/scripts/utils/Types.ts index 867f494..8a05dc8 100644 --- a/scripts/utils/Types.ts +++ b/scripts/utils/Types.ts @@ -1,16 +1,13 @@ -export interface TokenConfig { - tokens: Token[]; -} - export interface Token { address: string; - priceFeedAddress: string; - priceFeedFunction: string; - description: string; nativeOracleAddress: string; tokenOracleAddress: string; symbol: string; - feedSalt: string; derivedFeed: boolean; + priceUpdateThreshold?: number; // Add any other required properties for each token } + +export interface TokenConfig { + tokens: Token[]; +} diff --git a/scripts/utils/index.ts b/scripts/utils/index.ts index 629be36..aec806c 100644 --- a/scripts/utils/index.ts +++ b/scripts/utils/index.ts @@ -1,14 +1,6 @@ import { ethers as hardhatEthersInstance } from "hardhat"; +import { BigNumber, BigNumberish, Contract, ethers } from "ethers"; import { - BigNumber, - BigNumberish, - Contract, - ethers, - Signer, - ContractFactory, -} from "ethers"; -import { - getContractAddress, arrayify, hexConcat, hexlify, @@ -16,6 +8,7 @@ import { keccak256, Interface, } from "ethers/lib/utils"; +// eslint-disable-next-line node/no-extraneous-import import { TransactionReceipt, Provider } from "@ethersproject/providers"; import { Deployer, Deployer__factory } from "../../typechain-types"; @@ -33,44 +26,20 @@ export const factoryTxHash = const factoryDeploymentFee = (0.0247 * 1e18).toString(); // 0.0247 const options = { gasLimit: 7000000 /*, gasPrice: 70000000000 */ }; -// TODO -// remove TEST for production deployments - -// 0xD3f89753278E419c8bda1eFe1366206B3D30C44f : Deployer address -/* export enum DEPLOYMENT_SALTS { // DEV - ORACLE_AGGREGATOR = "DEVX_CHAINLINK_ORACLE_AGGREGATOR_V0_27062023_bBee55b", // 0x0000065b8abb967271817555f23945eedf08015c - TOKEN_PAYMASTER = "DEVX_TOKEN_PAYMASTER_V0_08072023_h5AFKLa", // 0x0000023d6c240ae3c9610d519510004d2616c9ec - PRICE_FEED_USDC = "DEVX_PRICE_FEED_USDC_V0_27062023_uiaqdyv", // 0x000005abae3deadbe1fbd12105f950efba9eaec4 - PRICE_FEED_USDT = "DEVX_PRICE_FEED_USDT_V0_27062023_dIos1Nw", // 0x000001e2c2b39542c30a3fe57c4487030bc03adf - PRICE_FEED_DAI = "DEVX_PRICE_FEED_DAI_V0_27062023_1m7JNWQ", // 0x000000d2da196474046c7a4d94ab0e566b26d054 - PRICE_FEED_SAND = "DEVX_PRICE_FEED_SAND_V0_27062023_eHPqgeR", // 0x00000980455efb131c1908efa908c1eaf19db352 - PRICE_FEED_AAVE = "DEVX_PRICE_FEED_AAVE_V0_28062023_HsugnpY", // 0x0000af22a276f86b405835c18863e1c2a679d9e3 - PRICE_FEED_CAKE = "DEVX_PRICE_FEED_CAKE_V0_27062023_1BKpzde", // 0x000007198738f877c01d9b7e4a4e1bd17e46e4a8 - PRICE_FEED_LINK = "DEVX_PRICE_FEED_LINK_V0_27062023_JHIxs6o", // 0x00000da809fe7be1297ee731f998141ba352778d - PRICE_FEED_1INCH = "DEVX_PRICE_FEED_1INCH_V0_27062023_XhXA3sd", // 0x00000c451fa0b0a79a36c82820f061683e26714c - PRICE_FEED_TWT = "DEVX_PRICE_FEED_TWT_V0_27062023_92Xklvq", // 0x00000e862312c82af2301e6c433e75099665649d - PRICE_FEED_UNI = "DEVX_PRICE_FEED_UNI_V0_27062023_PBQ6vdq" // 0x0000095cce092e83e5826cfeb0f03cfa74915b41 -} */ - export enum DEPLOYMENT_SALTS { // PROD // 0x988C135a1049Ce61730724afD342fb7C56CD2776 : Deployer address ORACLE_AGGREGATOR = "PROD_CHAINLINK_ORACLE_AGGREGATOR_V0_27062023_UT8R11e", // 0x00000f7748595e46527413574a9327942e744e91 TOKEN_PAYMASTER = "PROD_TOKEN_PAYMASTER_V0_08072023_cONP4xM", // 0x00000f7365ca6c59a2c93719ad53d567ed49c14c + TOKEN_PAYMASTER_V2 = "PROD_TOKEN_PAYMASTER_V2_07022024_cONP4xM", + // when using deployer DEV // ORACLE_AGGREGATOR = "DEVX_CHAINLINK_ORACLE_AGGREGATOR_V0_27062023_bBee55b", // 0x0000065b8abb967271817555f23945eedf08015c // when using deployer DEV // TOKEN_PAYMASTER = "DEVX_TOKEN_PAYMASTER_V0_08072023_h5AFKLa", // 0x0000023d6c240ae3c9610d519510004d2616c9ec - // V1.1.0 - SINGELTON_PAYMASTER = "PROD_SINGLETON_PAYMASTER_V1_06082023_II1mWTr", // 0x00000f79b7faf42eebadba19acc07cd08af44789 - - // 0xD3f89753278E419c8bda1eFe1366206B3D30C44f : Deployer address - - // V1.1.0 - // when using deployer DEV - // SINGELTON_PAYMASTER = "DEVX_SINGLETON_PAYMASTER_V1_03082023_0Af0vtw", // 0x0000064e9c653e373af18ef27f70be83df5476b7 + SPONSORSHIP_PAYMASTER = "PROD_SPONSORSHIP_PAYMASTER_040124_V2", PRICE_FEED_USDC = "DEVX_PRICE_FEED_USDC_V0_27062023_uiaqdyv", // 0x000005abae3deadbe1fbd12105f950efba9eaec4 PRICE_FEED_USDT = "DEVX_PRICE_FEED_USDT_V0_27062023_dIos1Nw", // 0x000001e2c2b39542c30a3fe57c4487030bc03adf @@ -313,6 +282,14 @@ export const deployContract = async ( return "0x"; }; +export const delay = (ms: number) => { + return new Promise((resolve) => { + setTimeout(() => { + resolve(); + }, ms); + }); +}; + /** * deploy a contract using our EIP-2470 deployer. * The delpoyer is deployed (unless it is already deployed) diff --git a/test/TokenPaymaster.t.sol b/test/TokenPaymaster.t.sol deleted file mode 100644 index 67b747d..0000000 --- a/test/TokenPaymaster.t.sol +++ /dev/null @@ -1,572 +0,0 @@ -// SPDX-License-Identifier: Unlicense -pragma solidity >=0.8.0; - -import {stdStorage, StdStorage, Test} from "forge-std/Test.sol"; -import {Utilities} from "./utils/Utilities.sol"; -import {console2} from "forge-std/console2.sol"; -import {Vm} from "forge-std/Vm.sol"; - -import {ChainlinkOracleAggregator} from "../contracts/token/oracles/ChainlinkOracleAggregator.sol"; -import {IOracleAggregator} from "../contracts/token/oracles/IOracleAggregator.sol"; -import {BiconomyTokenPaymaster} from "../contracts/token/BiconomyTokenPaymaster.sol"; -import "./BytesLib.sol"; -import "../contracts/test/helpers/TestCounter.sol"; - -import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; -import {IEntryPoint} from "@account-abstraction/contracts/interfaces/IEntryPoint.sol"; -import {EntryPoint} from "@account-abstraction/contracts/core/EntryPoint.sol"; -import {UserOperation} from "@account-abstraction/contracts/interfaces/UserOperation.sol"; -import {IStakeManager} from "@account-abstraction/contracts/interfaces/IStakeManager.sol"; -import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; - -import {SmartAccountFactory} from "@biconomy-devx/account-contracts-v2/contracts/smart-account/factory/SmartAccountFactory.sol"; -import {SmartAccount} from "@biconomy-devx/account-contracts-v2/contracts/smart-account/SmartAccount.sol"; -import {EcdsaOwnershipRegistryModule} from "@biconomy-devx/account-contracts-v2/contracts/smart-account/modules/EcdsaOwnershipRegistryModule.sol"; - - -import {MockToken} from "../contracts/test/helpers/MockToken.sol"; -import {MockPriceFeed} from "../contracts/test/helpers/MockPriceFeed.sol"; - -import {FeedInterface} from "../contracts/token/oracles/FeedInterface.sol"; - -error SetupIncomplete(); - -using ECDSA for bytes32; - -contract TokenPaymasterTest is Test { - using stdStorage for StdStorage; - - Utilities internal utils; - address payable[] internal users; - - address internal alice; // owner - address internal bob; // verifyingSigner - address internal charlie; // wallet owner - address internal factoryOwner; - address payable beneficiary; - address internal unauthorized; - - uint256 internal keyUser; - uint256 internal keyVerifyingSigner; - - ChainlinkOracleAggregator public _oa1; - BiconomyTokenPaymaster public _btpm; - IEntryPoint public _ep; - MockToken usdc; - MockPriceFeed usdcMaticFeed; - SmartAccountFactory smartAccountFactory; - SmartAccount smartAccount; - // Modules - EcdsaOwnershipRegistryModule ecdsaOwnershipRegistryModule; - - TestCounter counter; - - function setUp() public { - utils = new Utilities(); - users = utils.createUsers(5); - - beneficiary = payable(makeAddr("beneficiary")); - alice = payable(makeAddr("Alice")); - (bob, keyVerifyingSigner) = makeAddrAndKey("Bob"); - (charlie, keyUser) = makeAddrAndKey("Charlie"); - unauthorized = makeAddr("Unauthorized"); - - _ep = new EntryPoint(); - _btpm = new BiconomyTokenPaymaster(alice, _ep, bob); - _oa1 = new ChainlinkOracleAggregator(alice); - usdc = new MockToken(); - usdcMaticFeed = new MockPriceFeed(); - counter = new TestCounter(); - - // setting price oracle for token - bytes memory _data = abi.encodeWithSelector(FeedInterface.getThePrice.selector); - - vm.prank(alice); - // could also make a .call using selector and handle success - _oa1.setTokenOracle(address(usdc), address(usdcMaticFeed), 18, _data, true); - - uint256 priceToLog = _oa1.getTokenValueOfOneNativeToken((address(usdc))); - console2.log(priceToLog); - - smartAccount = new SmartAccount(_ep); - vm.label(address(smartAccount), "Smart Account Implementation"); - - factoryOwner = users[4]; - smartAccountFactory = new SmartAccountFactory(address(smartAccount),factoryOwner); - vm.label(address(smartAccountFactory), "Smart Account Factory"); - - ecdsaOwnershipRegistryModule = new EcdsaOwnershipRegistryModule(); - vm.label( - address(ecdsaOwnershipRegistryModule), - "ECDSA Ownership Registry Module" - ); - - smartAccount = getSmartAccountWithModule( - address(ecdsaOwnershipRegistryModule), - getEcdsaOwnershipRegistryModuleSetupData(charlie), - 0, - "Smart Account with ECDSA Ownership Registry Module" - ); - - address accountAddress = address(smartAccount); - - vm.deal(charlie, 2 ether); - vm.prank(charlie); - _ep.depositTo{value: 2 ether}(address(_btpm)); - - // mint tokens to addresses - usdc.mint(charlie, 100e6); - usdc.mint(accountAddress, 100e6); - vm.warp(1680509051); - } - - // Utility Functions - function getSmartAccountWithModule( - address _moduleSetupContract, - bytes memory _moduleSetupData, - uint256 _index, - string memory _label - ) internal returns (SmartAccount sa) { - sa = SmartAccount( - payable( - smartAccountFactory.deployCounterFactualAccount( - _moduleSetupContract, - _moduleSetupData, - _index - ) - ) - ); - vm.label(address(sa), _label); - } - - // Module Setup Data Helpers - function getEcdsaOwnershipRegistryModuleSetupData( - address _owner - ) internal pure returns (bytes memory) { - return - abi.encodeCall( - EcdsaOwnershipRegistryModule.initForSmartAccount, - (_owner) - ); - } - - function testDeploy() external { - BiconomyTokenPaymaster testArtifact = new BiconomyTokenPaymaster( - alice, - _ep, - bob - ); - assertEq(address(testArtifact.owner()), address(alice)); - assertEq(address(testArtifact.entryPoint()), address(_ep)); - assertEq(address(testArtifact.verifyingSigner()), address(bob)); - assertEq(address(testArtifact.feeReceiver()), address(testArtifact)); - } - - function testCheckStates() public { - assertEq(_btpm.owner(), alice); - assertEq(_btpm.verifyingSigner(), bob); - assertEq(_btpm.feeReceiver(), address(_btpm)); - } - - function testOwnershipTransfer() external { - vm.startPrank(alice); - assertEq(_btpm.owner(), alice); - _btpm.transferOwnership(beneficiary); - assertEq(_btpm.owner(), beneficiary); - vm.stopPrank(); - } - - function testWithdrawERC20(uint256 _amount) external { - vm.assume(_amount < usdc.totalSupply()); - usdc.mint(address(_btpm), _amount); - vm.startPrank(alice); - _btpm.withdrawERC20(usdc, beneficiary, _amount); - assertEq(usdc.balanceOf(address(_btpm)), 0); - assertEq(usdc.balanceOf(beneficiary), _amount); - vm.stopPrank(); - } - - function testWithdrawERC20FailNotOwner(uint256 _amount) external { - vm.assume(_amount < usdc.totalSupply()); - usdc.mint(address(_btpm), _amount); - vm.startPrank(beneficiary); - vm.expectRevert("Ownable: caller is not the owner"); - _btpm.withdrawERC20(usdc, beneficiary, _amount); - vm.stopPrank(); - } - - // WIP // TODO - function testParsePaymasterData() public { - bytes memory paymasterAndData = - "0x0987404beb853f24f36c76c3e18adcad7ab44f930100000000000000000000000000000000000000000000000000000000deadbeef00000000000000000000000000000000000000000000000000000000000012340000000000000000000000002791bca1f2de4661ed88a30c99a7a9449aa841740000000000000000000000007ed8428288323e8583defc90bfdf2dad91cff88900000000000000000000000000000000000000000000000000000000000d34e300000000000000000000000000000000000000000000000000000000000000001984ae5a976a7eb4ee0292a2fa344721f074ce31a90d3182318bdbcec8b447f55690ffa572e58e1f40e93d3e7060b0a20a8b3493226d269adf3cb4d467e9996d1c"; - bytes memory paymasterAndDataBytes = bytes(paymasterAndData); - // [FAIL. Reason: Conversion into non-existent enum type] - // _btpm.parsePaymasterAndData(abi.encodePacked(paymasterAndDataBytes)); - } - - // sanity check for everything works without paymaster - function testCall() external { - vm.deal(address(smartAccount), 1e18); - (UserOperation memory op, uint256 prefund) = - fillUserOp(smartAccount, keyUser, address(counter), 0, abi.encodeWithSelector(TestCounter.count.selector)); - op.signature = signUserOp(op, keyUser); - UserOperation[] memory ops = new UserOperation[](1); - ops[0] = op; - _ep.handleOps(ops, beneficiary); - } - - // with token paymaster - function testTokenPaymasterRefund() external { - vm.deal(address(smartAccount), 1e18); - usdc.mint(address(smartAccount), 100e6); // 100 usdc; - usdc.mint(address(_btpm), 100e6); // 100 usdc; - console2.log("paymaster balance before ", usdc.balanceOf(address(_btpm))); - (UserOperation memory op, uint256 prefund) = fillUserOp( - smartAccount, - keyUser, - address(usdc), - 0, - abi.encodeWithSelector(ERC20.approve.selector, address(_btpm), 10e6) - ); - bytes memory pmSig = signPaymasterSignature(op, keyVerifyingSigner); - - BiconomyTokenPaymaster.ExchangeRateSource priceSource = BiconomyTokenPaymaster.ExchangeRateSource.ORACLE_BASED; - uint48 validUntil = 3735928559; - uint48 validAfter = 4660; - uint256 exchangeRate = 977100; - uint32 priceMarkup = 1100000; - - op.paymasterAndData = abi.encodePacked( - address(_btpm), - priceSource, - abi.encode(validUntil, validAfter, address(usdc), address(_oa1), exchangeRate, priceMarkup), - pmSig - ); - op.signature = signUserOp(op, keyUser); - UserOperation[] memory ops = new UserOperation[](1); - ops[0] = op; - _ep.handleOps(ops, beneficiary); - - // todo // review fails to validate updated balances - console2.log("paymaster balance after ", usdc.balanceOf(address(_btpm))); - assertNotEq(usdc.balanceOf(address(smartAccount)), 100e6); - } - - function testTokenPaymasterFailInvalidPMSignatureLength() external { - vm.deal(address(smartAccount), 1e18); - usdc.mint(address(smartAccount), 100e6); // 100 usdc; - usdc.mint(address(_btpm), 100e6); // 100 usdc; - console2.log("paymaster balance before ", usdc.balanceOf(address(_btpm))); - (UserOperation memory op, uint256 prefund) = fillUserOp( - smartAccount, - keyUser, - address(usdc), - 0, - abi.encodeWithSelector(ERC20.approve.selector, address(_btpm), 10e6) - ); - bytes memory pmSig = "0x1234"; - - BiconomyTokenPaymaster.ExchangeRateSource priceSource = BiconomyTokenPaymaster.ExchangeRateSource.ORACLE_BASED; - uint48 validUntil = 3735928559; - uint48 validAfter = 4660; - uint256 exchangeRate = 977100; - uint32 priceMarkup = 1100000; - - op.paymasterAndData = abi.encodePacked( - address(_btpm), - priceSource, - abi.encode(validUntil, validAfter, address(usdc), address(_oa1), exchangeRate, priceMarkup), - pmSig - ); - op.signature = signUserOp(op, keyUser); - UserOperation[] memory ops = new UserOperation[](1); - ops[0] = op; - vm.expectRevert( - abi.encodeWithSelector( - IEntryPoint.FailedOp.selector, - uint256(0), - "AA33 reverted: BTPM: invalid signature length in paymasterAndData" - ) - ); - _ep.handleOps(ops, beneficiary); - } - - function testTokenPaymasterFailInvalidPaymasteDataLength() external { - vm.deal(address(smartAccount), 1e18); - usdc.mint(address(smartAccount), 100e6); // 100 usdc; - usdc.mint(address(_btpm), 100e6); // 100 usdc; - console2.log("paymaster balance before ", usdc.balanceOf(address(_btpm))); - (UserOperation memory op, uint256 prefund) = fillUserOp( - smartAccount, - keyUser, - address(usdc), - 0, - abi.encodeWithSelector(ERC20.approve.selector, address(_btpm), 10e6) - ); - - op.paymasterAndData = "0x1234"; - op.signature = signUserOp(op, keyUser); - UserOperation[] memory ops = new UserOperation[](1); - ops[0] = op; - vm.expectRevert("AA93 invalid paymasterAndData"); - _ep.handleOps(ops, beneficiary); - } - - function test2TokenPaymasterFailInvalidPaymasteDataLength() external { - vm.deal(address(smartAccount), 1e18); - usdc.mint(address(smartAccount), 100e6); // 100 usdc; - usdc.mint(address(_btpm), 100e6); // 100 usdc; - console2.log("paymaster balance before ", usdc.balanceOf(address(_btpm))); - (UserOperation memory op, uint256 prefund) = fillUserOp( - smartAccount, - keyUser, - address(usdc), - 0, - abi.encodeWithSelector(ERC20.approve.selector, address(_btpm), 10e6) - ); - - bytes memory pmSig = "0x1234"; - op.paymasterAndData = abi.encodePacked(address(_btpm), pmSig); - op.signature = signUserOp(op, keyUser); - UserOperation[] memory ops = new UserOperation[](1); - ops[0] = op; - vm.expectRevert( - abi.encodeWithSelector( - IEntryPoint.FailedOp.selector, uint256(0), "AA33 reverted: BTPM: Invalid length for paymasterAndData" - ) - ); - _ep.handleOps(ops, beneficiary); - } - - function testTokenPaymasterFailInvalidPMSignature() external { - vm.deal(address(smartAccount), 1e18); - usdc.mint(address(smartAccount), 100e6); // 100 usdc; - usdc.mint(address(_btpm), 100e6); // 100 usdc; - console2.log("paymaster balance before ", usdc.balanceOf(address(_btpm))); - (UserOperation memory op, uint256 prefund) = fillUserOp( - smartAccount, - keyUser, - address(usdc), - 0, - abi.encodeWithSelector(ERC20.approve.selector, address(_btpm), 10e6) - ); - bytes memory pmSig = - "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; - - BiconomyTokenPaymaster.ExchangeRateSource priceSource = BiconomyTokenPaymaster.ExchangeRateSource.ORACLE_BASED; - uint48 validUntil = 3735928559; - uint48 validAfter = 4660; - uint256 exchangeRate = 977100; - uint32 priceMarkup = 1100000; - - op.paymasterAndData = abi.encodePacked( - address(_btpm), - priceSource, - abi.encode(validUntil, validAfter, address(usdc), address(_oa1), exchangeRate, priceMarkup), - pmSig - ); - op.signature = signUserOp(op, keyUser); - UserOperation[] memory ops = new UserOperation[](1); - ops[0] = op; - vm.expectRevert(); - _ep.handleOps(ops, beneficiary); - - // TODO // Review why below doesn't capture while it does in hardhat test and in above tests - /*vm.expectRevert( - abi.encodeWithSelector( - IEntryPoint.FailedOp.selector, uint256(0), "AA33 reverted: ECDSA: invalid signature" - ) - ); - _ep.simulateValidation(ops[0]);*/ - } - - function testTokenPaymasterFailWrongPMSignature() external { - vm.deal(address(smartAccount), 1e18); - usdc.mint(address(smartAccount), 100e6); // 100 usdc; - usdc.mint(address(_btpm), 100e6); // 100 usdc; - console2.log("paymaster balance before ", usdc.balanceOf(address(_btpm))); - (UserOperation memory op, uint256 prefund) = fillUserOp( - smartAccount, - keyUser, - address(usdc), - 0, - abi.encodeWithSelector(ERC20.approve.selector, address(_btpm), 10e6) - ); - - bytes32 hash = keccak256((abi.encodePacked("some message"))); - (uint8 v, bytes32 r, bytes32 s) = vm.sign(keyVerifyingSigner, hash.toEthSignedMessageHash()); - bytes memory pmSig = abi.encodePacked(r, s, v); - - BiconomyTokenPaymaster.ExchangeRateSource priceSource = BiconomyTokenPaymaster.ExchangeRateSource.ORACLE_BASED; - uint48 validUntil = 3735928559; - uint48 validAfter = 4660; - uint256 exchangeRate = 977100; - uint32 priceMarkup = 1100000; - - op.paymasterAndData = abi.encodePacked( - address(_btpm), - priceSource, - abi.encode(validUntil, validAfter, address(usdc), address(_oa1), exchangeRate, priceMarkup), - pmSig - ); - op.signature = signUserOp(op, keyUser); - UserOperation[] memory ops = new UserOperation[](1); - ops[0] = op; - vm.expectRevert(); - // TODO // Review why below doesn't capture while it does in hardhat test and in above tests - // vm.expectRevert("AA34 signature error"); - _ep.handleOps(ops, beneficiary); - } - - function testTokenPaymasterFailHighPriceMarkup() external { - vm.deal(address(smartAccount), 1e18); - usdc.mint(address(smartAccount), 100e6); // 100 usdc; - usdc.mint(address(_btpm), 100e6); // 100 usdc; - console2.log("paymaster balance before ", usdc.balanceOf(address(_btpm))); - (UserOperation memory op, uint256 prefund) = fillUserOp( - smartAccount, - keyUser, - address(usdc), - 0, - abi.encodeWithSelector(ERC20.approve.selector, address(_btpm), 10e6) - ); - - BiconomyTokenPaymaster.ExchangeRateSource priceSource = BiconomyTokenPaymaster.ExchangeRateSource.ORACLE_BASED; - uint48 validUntil = 3735928559; - uint48 validAfter = 4660; - uint256 exchangeRate = 977100; - uint32 priceMarkup = 2200000; - - bytes32 hash = _btpm.getHash( - op, priceSource, validUntil, validAfter, address(usdc), address(_oa1), exchangeRate, priceMarkup - ); - (uint8 v, bytes32 r, bytes32 s) = vm.sign(keyVerifyingSigner, hash.toEthSignedMessageHash()); - bytes memory pmSig = abi.encodePacked(r, s, v); - - op.paymasterAndData = abi.encodePacked( - address(_btpm), - priceSource, - abi.encode(validUntil, validAfter, address(usdc), address(_oa1), exchangeRate, priceMarkup), - pmSig - ); - op.signature = signUserOp(op, keyUser); - UserOperation[] memory ops = new UserOperation[](1); - ops[0] = op; - vm.expectRevert( - abi.encodeWithSelector( - IEntryPoint.FailedOp.selector, uint256(0), "AA33 reverted: BTPM: price markup percentage too high" - ) - ); - - _ep.handleOps(ops, beneficiary); - } - - function fillUserOp( - SmartAccount _sender, - uint256 _key, - address _to, - uint256 _value, - bytes memory _data - ) public returns (UserOperation memory op, uint256 prefund) { - op.sender = address(_sender); - op.nonce = _ep.getNonce(address(_sender), 0); - op.callData = abi.encodeWithSelector(SmartAccount.execute_ncC.selector, _to, _value, _data); - op.callGasLimit = 50000; - op.verificationGasLimit = 80000; - op.preVerificationGas = 50000; - op.maxFeePerGas = 1000000000; - op.maxPriorityFeePerGas = 100; - op.signature = signUserOp(op, _key); - (op, prefund) = simulateVerificationGas(_ep, op); - op.callGasLimit = simulateCallGas(_ep, op); - - //op.signature = signUserOp(op, _name); - - op.signature = abi.encode( - op.signature, - address(ecdsaOwnershipRegistryModule) - ); - } - - function signUserOp(UserOperation memory op, uint256 _key) public returns (bytes memory signature) { - bytes32 hash = _ep.getUserOpHash(op); - (uint8 v, bytes32 r, bytes32 s) = vm.sign(_key, hash.toEthSignedMessageHash()); - signature = abi.encodePacked(r, s, v); - signature = abi.encode( - signature, - address(ecdsaOwnershipRegistryModule) - ); - } - - function signPaymasterSignature(UserOperation memory op, uint256 _key) public returns (bytes memory signature) { - BiconomyTokenPaymaster.ExchangeRateSource priceSource = BiconomyTokenPaymaster.ExchangeRateSource.ORACLE_BASED; - uint48 validUntil = 3735928559; - uint48 validAfter = 4660; - uint256 exchangeRate = 977100; - uint32 priceMarkup = 1100000; - - bytes32 hash = _btpm.getHash( - op, priceSource, validUntil, validAfter, address(usdc), address(_oa1), exchangeRate, priceMarkup - ); - (uint8 v, bytes32 r, bytes32 s) = vm.sign(_key, hash.toEthSignedMessageHash()); - signature = abi.encodePacked(r, s, v); - } - - function simulateVerificationGas(IEntryPoint _entrypoint, UserOperation memory op) - public - returns (UserOperation memory, uint256 preFund) - { - (bool success, bytes memory ret) = - address(_entrypoint).call(abi.encodeWithSelector(EntryPoint.simulateValidation.selector, op)); - require(!success); - bytes memory data = BytesLib.slice(ret, 4, ret.length - 4); - (IEntryPoint.ReturnInfo memory retInfo,,,) = abi.decode( - data, (IEntryPoint.ReturnInfo, IStakeManager.StakeInfo, IStakeManager.StakeInfo, IStakeManager.StakeInfo) - ); - op.preVerificationGas = retInfo.preOpGas; - op.verificationGasLimit = retInfo.preOpGas; - op.maxFeePerGas = retInfo.prefund * 11 / (retInfo.preOpGas * 10); - op.maxPriorityFeePerGas = 1; - return (op, retInfo.prefund); - } - - function simulateCallGas(IEntryPoint _entrypoint, UserOperation memory op) internal returns (uint256) { - try this.calcGas(_entrypoint, op.sender, op.callData) { - revert("Should have failed"); - } catch Error(string memory reason) { - uint256 gas = abi.decode(bytes(reason), (uint256)); - return gas * 11 / 10; - } catch { - revert("Should have failed"); - } - } - - // not used internally - function calcGas(IEntryPoint _entrypoint, address _to, bytes memory _data) external { - vm.startPrank(address(_entrypoint)); - uint256 g = gasleft(); - (bool success,) = _to.call(_data); - require(success); - g = g - gasleft(); - bytes memory r = abi.encode(g); - vm.stopPrank(); - require(false, string(r)); - } - - function testDecode() external view{ - bytes memory d = - hex"0000023d6c240ae3c9610d519510004d2616c9ec010000000000000000000000000000000000000000000000000000000065157c23000000000000000000000000000000000000000000000000000000006515751b0000000000000000000000008ac76a51cc950d9822d68b83fe1ad97b32cd580d0000000000000000000000000000065b8abb967271817555f23945eedf08015c00000000000000000000000000000000000000000000000b88f7f3bb38595e8a000000000000000000000000000000000000000000000000000000000010c8e019b54af51b156531fb11b7aabf4dba0d0eae1e519e54d176633de65eac43d41c431ce06784f1bab9085771a86c1a006d944214c33272e022e7168e5062fd8fb01c"; - ( - BiconomyTokenPaymaster.ExchangeRateSource priceSource, - uint48 validUntil, - uint48 validAfter, - address feeToken, - address oracleAggregator, - uint256 exchangeRate, - uint32 priceMarkup, - bytes memory signature - ) = _btpm.parsePaymasterAndData(d); - - console2.log(validAfter, validUntil); - } -} diff --git a/test/bundler-integration/sponsorship-paymaster/biconomy-sponsorship-paymaster-specs.ts b/test/bundler-integration/sponsorship-paymaster/biconomy-sponsorship-paymaster-specs.ts new file mode 100644 index 0000000..50e25f3 --- /dev/null +++ b/test/bundler-integration/sponsorship-paymaster/biconomy-sponsorship-paymaster-specs.ts @@ -0,0 +1,417 @@ +/* eslint-disable node/no-missing-import */ +/* eslint-disable camelcase */ +import { expect } from "chai"; +import { ethers } from "hardhat"; + +import { + BiconomyAccountImplementation, + BiconomyAccountImplementation__factory, + BiconomyAccountFactory, + BiconomyAccountFactory__factory, + SponsorshipPaymaster, + SponsorshipPaymaster__factory, +} from "../../../typechain-types"; +import { fillAndSign } from "../../utils/userOp"; +import { + EntryPoint, + EntryPoint__factory, +} from "../../../lib/account-abstraction/typechain"; +import { + EcdsaOwnershipRegistryModule, + EcdsaOwnershipRegistryModule__factory, +} from "@biconomy-devx/account-contracts-v2/dist/types"; +import { arrayify, hexConcat, parseEther } from "ethers/lib/utils"; +import { BigNumber, Signer } from "ethers"; +import { + BundlerTestEnvironment, + EthSendUserOperationResult, + UserOperationSubmissionError, +} from "../environment/bundlerEnvironment"; +import { parseEvent } from "../../utils/testUtils"; + +export const AddressZero = ethers.constants.AddressZero; + +const UserOperationEventTopic = + "0x49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f"; + +const MOCK_VALID_UNTIL = "0x00000000deadbeef"; +const MOCK_VALID_AFTER = "0x0000000000001234"; +const dynamicMarkup = 1200000; // or 0 or 1100000 + +export async function deployEntryPoint( + provider = ethers.provider +): Promise { + const epf = await (await ethers.getContractFactory("EntryPoint")).deploy(); + return EntryPoint__factory.connect(epf.address, provider.getSigner()); +} + +describe("EntryPoint with VerifyingPaymaster Singleton", function () { + let entryPoint: EntryPoint; + let walletOwner: Signer; + let walletAddress: string, paymasterAddress: string; + let ethersSigner; + + let offchainSigner: Signer, deployer: Signer, feeCollector: Signer; + + let sponsorshipPaymaster: SponsorshipPaymaster; + let smartWalletImp: BiconomyAccountImplementation; + let ecdsaModule: EcdsaOwnershipRegistryModule; + let walletFactory: BiconomyAccountFactory; + + let environment: BundlerTestEnvironment; + + beforeEach(async function () { + // Setup the Bundler Environment + const chainId = (await ethers.provider.getNetwork()).chainId; + if (chainId !== BundlerTestEnvironment.BUNDLER_ENVIRONMENT_CHAIN_ID) { + this.skip(); + } + environment = await BundlerTestEnvironment.getDefaultInstance(); + + ethersSigner = await ethers.getSigners(); + entryPoint = EntryPoint__factory.connect(process.env.ENTRYPOINT!, deployer); + + deployer = ethersSigner[0]; + offchainSigner = ethersSigner[1]; + feeCollector = ethersSigner[3]; + walletOwner = deployer; // ethersSigner[0]; + + const offchainSignerAddress = await offchainSigner.getAddress(); + const walletOwnerAddress = await walletOwner.getAddress(); + const feeCollectorAddress = await feeCollector.getAddress(); + + ecdsaModule = await new EcdsaOwnershipRegistryModule__factory( + deployer + ).deploy(); + + sponsorshipPaymaster = await new SponsorshipPaymaster__factory( + deployer + ).deploy( + await deployer.getAddress(), + entryPoint.address, + offchainSignerAddress, + feeCollectorAddress + ); + + smartWalletImp = await new BiconomyAccountImplementation__factory( + deployer + ).deploy(entryPoint.address); + + walletFactory = await new BiconomyAccountFactory__factory(deployer).deploy( + smartWalletImp.address, + walletOwnerAddress + ); + + await walletFactory + .connect(deployer) + .addStake(entryPoint.address, 86400, { value: parseEther("2") }); + + const ecdsaOwnershipSetupData = ecdsaModule.interface.encodeFunctionData( + "initForSmartAccount", + [walletOwnerAddress] + ); + + const smartAccountDeploymentIndex = 0; + + await walletFactory.deployCounterFactualAccount( + ecdsaModule.address, + ecdsaOwnershipSetupData, + smartAccountDeploymentIndex + ); + const expected = await walletFactory.getAddressForCounterFactualAccount( + ecdsaModule.address, + ecdsaOwnershipSetupData, + smartAccountDeploymentIndex + ); + + walletAddress = expected; + console.log(" wallet address ", walletAddress); + + paymasterAddress = sponsorshipPaymaster.address; + console.log("Paymaster address is ", paymasterAddress); + + await entryPoint + .connect(deployer) + .depositTo(paymasterAddress, { value: parseEther("1") }); + + await sponsorshipPaymaster.connect(deployer).addStake(86400, { + value: parseEther("10"), + }); + }); + + after(async function () { + const chainId = (await ethers.provider.getNetwork()).chainId; + if (chainId === BundlerTestEnvironment.BUNDLER_ENVIRONMENT_CHAIN_ID) { + await Promise.all([ + environment.revert(environment.defaultSnapshot!), + environment.resetBundler(), + ]); + } + }); + + describe("#validatePaymasterUserOp", () => { + it("Should parse data properly", async () => { + const numVU = ethers.BigNumber.from(MOCK_VALID_UNTIL); + const numVA = ethers.BigNumber.from(MOCK_VALID_AFTER); + const paymasterAndData = hexConcat([ + paymasterAddress, + ethers.utils.hexZeroPad(await offchainSigner.getAddress(), 20), + ethers.utils.hexZeroPad(ethers.utils.hexlify(numVU.toNumber()), 6), // 6 byte + ethers.utils.hexZeroPad(ethers.utils.hexlify(numVA.toNumber()), 6), // 6 byte + ethers.utils.hexZeroPad(ethers.utils.hexlify(dynamicMarkup), 4), // 4 bytes + "0x" + "00".repeat(65), + ]); + + const res = await sponsorshipPaymaster.parsePaymasterAndData( + paymasterAndData + ); + + expect(res.paymasterId).to.equal(await offchainSigner.getAddress()); + expect(res.validUntil).to.equal(ethers.BigNumber.from(MOCK_VALID_UNTIL)); + expect(res.validAfter).to.equal(ethers.BigNumber.from(MOCK_VALID_AFTER)); + expect(res.priceMarkup).to.equal(dynamicMarkup); + expect(res.signature).to.equal("0x" + "00".repeat(65)); + }); + + it("succeed with valid signature", async () => { + const feeCollectorBalanceBefore = await sponsorshipPaymaster.getBalance( + await feeCollector.getAddress() + ); + expect(feeCollectorBalanceBefore).to.be.equal(BigNumber.from(0)); + const signer = await sponsorshipPaymaster.verifyingSigner(); + const offchainSignerAddress = await offchainSigner.getAddress(); + expect(signer).to.be.equal(offchainSignerAddress); + + await sponsorshipPaymaster.depositFor(await offchainSigner.getAddress(), { + value: ethers.utils.parseEther("1"), + }); + const userOp1 = await fillAndSign( + { + sender: walletAddress, + verificationGasLimit: 200000, // for positive case 200k + preVerificationGas: 55000, // min expected by bundler is 46k + }, + walletOwner, + entryPoint, + "nonce" + ); + + const hash = await sponsorshipPaymaster.getHash( + userOp1, + await offchainSigner.getAddress(), + MOCK_VALID_UNTIL, + MOCK_VALID_AFTER, + dynamicMarkup + ); + const sig = await offchainSigner.signMessage(arrayify(hash)); + const numVU = ethers.BigNumber.from(MOCK_VALID_UNTIL); + const numVA = ethers.BigNumber.from(MOCK_VALID_AFTER); + const userOp = await fillAndSign( + { + ...userOp1, + paymasterAndData: hexConcat([ + paymasterAddress, + ethers.utils.hexZeroPad(await offchainSigner.getAddress(), 20), + ethers.utils.hexZeroPad(ethers.utils.hexlify(numVU.toNumber()), 6), // 6 byte + ethers.utils.hexZeroPad(ethers.utils.hexlify(numVA.toNumber()), 6), // 6 byte + ethers.utils.hexZeroPad(ethers.utils.hexlify(dynamicMarkup), 4), // 4 bytes + sig, + ]), + }, + walletOwner, + entryPoint, + "nonce" + ); + + const signatureWithModuleAddress = ethers.utils.defaultAbiCoder.encode( + ["bytes", "address"], + [userOp.signature, ecdsaModule.address] + ); + userOp.signature = signatureWithModuleAddress; + + console.log("userop VGL ", userOp.verificationGasLimit.toString()); + console.log("userop PVG ", userOp.preVerificationGas.toString()); + + const result: EthSendUserOperationResult = + await environment.sendUserOperation(userOp, entryPoint.address); + + const receipt = (await environment.getUserOperationReceipt(result.result)) + .result; + + const event = parseEvent(receipt.receipt, UserOperationEventTopic); + + const eventLogs = entryPoint.interface.decodeEventLog( + "UserOperationEvent", + event[0].data + ); + + // eslint-disable-next-line no-unused-expressions + expect(eventLogs.success).to.be.true; + + await expect( + entryPoint.handleOps([userOp], await offchainSigner.getAddress()) + ).to.be.reverted; + + const feeCollectorBalanceAfter = await sponsorshipPaymaster.getBalance( + await feeCollector.getAddress() + ); + expect(feeCollectorBalanceAfter).to.be.greaterThan(BigNumber.from(0)); + }); + + it("fails if verificationGasLimit is not enough", async () => { + const feeCollectorBalanceBefore = await sponsorshipPaymaster.getBalance( + await feeCollector.getAddress() + ); + expect(feeCollectorBalanceBefore).to.be.equal(BigNumber.from(0)); + const signer = await sponsorshipPaymaster.verifyingSigner(); + const offchainSignerAddress = await offchainSigner.getAddress(); + expect(signer).to.be.equal(offchainSignerAddress); + + await sponsorshipPaymaster.depositFor(await offchainSigner.getAddress(), { + value: ethers.utils.parseEther("1"), + }); + const userOp1 = await fillAndSign( + { + sender: walletAddress, + verificationGasLimit: 50000, // for positive case 200k + preVerificationGas: 55000, // min expected by bundler is 46k + }, + walletOwner, + entryPoint, + "nonce" + ); + + const hash = await sponsorshipPaymaster.getHash( + userOp1, + await offchainSigner.getAddress(), + MOCK_VALID_UNTIL, + MOCK_VALID_AFTER, + dynamicMarkup + ); + const sig = await offchainSigner.signMessage(arrayify(hash)); + const numVU = ethers.BigNumber.from(MOCK_VALID_UNTIL); + const numVA = ethers.BigNumber.from(MOCK_VALID_AFTER); + const userOp = await fillAndSign( + { + ...userOp1, + paymasterAndData: hexConcat([ + paymasterAddress, + ethers.utils.hexZeroPad(await offchainSigner.getAddress(), 20), + ethers.utils.hexZeroPad(ethers.utils.hexlify(numVU.toNumber()), 6), // 6 byte + ethers.utils.hexZeroPad(ethers.utils.hexlify(numVA.toNumber()), 6), // 6 byte + ethers.utils.hexZeroPad(ethers.utils.hexlify(dynamicMarkup), 4), // 4 bytes + sig, + ]), + }, + walletOwner, + entryPoint, + "nonce" + ); + + const signatureWithModuleAddress = ethers.utils.defaultAbiCoder.encode( + ["bytes", "address"], + [userOp.signature, ecdsaModule.address] + ); + userOp.signature = signatureWithModuleAddress; + + console.log("userop VGL ", userOp.verificationGasLimit.toString()); + console.log("userop PVG ", userOp.preVerificationGas.toString()); + + let thrownError: Error | null = null; + + try { + await environment.sendUserOperation(userOp, entryPoint.address); + } catch (e) { + thrownError = e as Error; + } + + const expectedError = new UserOperationSubmissionError( + '{"message":"account validation failed: AA40 over verificationGasLimit' + ); + + expect(thrownError).to.contain(expectedError); + + await expect( + entryPoint.handleOps([userOp], await offchainSigner.getAddress()) + ).to.be.reverted; + }); + + it("fails if preVerificationGas is not enough", async () => { + const feeCollectorBalanceBefore = await sponsorshipPaymaster.getBalance( + await feeCollector.getAddress() + ); + expect(feeCollectorBalanceBefore).to.be.equal(BigNumber.from(0)); + const signer = await sponsorshipPaymaster.verifyingSigner(); + const offchainSignerAddress = await offchainSigner.getAddress(); + expect(signer).to.be.equal(offchainSignerAddress); + + await sponsorshipPaymaster.depositFor(await offchainSigner.getAddress(), { + value: ethers.utils.parseEther("1"), + }); + const userOp1 = await fillAndSign( + { + sender: walletAddress, + verificationGasLimit: 200000, // for positive case 200k + // preVerificationGas: 55000, // min expected by bundler is 46k + }, + walletOwner, + entryPoint, + "nonce" + ); + + const hash = await sponsorshipPaymaster.getHash( + userOp1, + await offchainSigner.getAddress(), + MOCK_VALID_UNTIL, + MOCK_VALID_AFTER, + dynamicMarkup + ); + const sig = await offchainSigner.signMessage(arrayify(hash)); + const numVU = ethers.BigNumber.from(MOCK_VALID_UNTIL); + const numVA = ethers.BigNumber.from(MOCK_VALID_AFTER); + const userOp = await fillAndSign( + { + ...userOp1, + paymasterAndData: hexConcat([ + paymasterAddress, + ethers.utils.hexZeroPad(await offchainSigner.getAddress(), 20), + ethers.utils.hexZeroPad(ethers.utils.hexlify(numVU.toNumber()), 6), // 6 byte + ethers.utils.hexZeroPad(ethers.utils.hexlify(numVA.toNumber()), 6), // 6 byte + ethers.utils.hexZeroPad(ethers.utils.hexlify(dynamicMarkup), 4), // 4 bytes + sig, + ]), + }, + walletOwner, + entryPoint, + "nonce" + ); + + const signatureWithModuleAddress = ethers.utils.defaultAbiCoder.encode( + ["bytes", "address"], + [userOp.signature, ecdsaModule.address] + ); + userOp.signature = signatureWithModuleAddress; + + console.log("userop VGL ", userOp.verificationGasLimit.toString()); + console.log("userop PVG ", userOp.preVerificationGas.toString()); + + let thrownError: Error | null = null; + + try { + await environment.sendUserOperation(userOp, entryPoint.address); + } catch (e) { + thrownError = e as Error; + } + + const expectedError = new UserOperationSubmissionError( + '{"message":"preVerificationGas too low: expected at least 45916' + ); + + expect(thrownError).to.contain(expectedError); + + // await expect( + // entryPoint.handleOps([userOp], await offchainSigner.getAddress()) + // ).to.be.reverted; + }); + }); +}); diff --git a/test/bundler-integration/token-paymaster/biconomy-token-paymaster-specs.ts b/test/bundler-integration/token-paymaster/biconomy-token-paymaster-specs.ts index 30557ae..811cf21 100644 --- a/test/bundler-integration/token-paymaster/biconomy-token-paymaster-specs.ts +++ b/test/bundler-integration/token-paymaster/biconomy-token-paymaster-specs.ts @@ -12,10 +12,9 @@ import { BiconomyAccountFactory__factory, BiconomyTokenPaymaster, BiconomyTokenPaymaster__factory, - ChainlinkOracleAggregator, - ChainlinkOracleAggregator__factory, MockPriceFeed__factory, MockToken, + MockOracle__factory, } from "../../../typechain-types"; // Review: Could import from scw-contracts submodules to be consistent @@ -31,7 +30,11 @@ import { } from "@biconomy-devx/account-contracts-v2/dist/types"; import { arrayify, parseEther } from "ethers/lib/utils"; import { BigNumber, BigNumberish, Signer } from "ethers"; -import { BundlerTestEnvironment } from "../environment/bundlerEnvironment"; +import { + BundlerTestEnvironment, + EthSendUserOperationResult, +} from "../environment/bundlerEnvironment"; +import { parseEvent } from "../../utils/testUtils"; export const AddressZero = ethers.constants.AddressZero; @@ -43,38 +46,25 @@ const DEFAULT_FEE_MARKUP = 1100000; const MOCK_FX: BigNumberish = "977100"; // matic to usdc approx +const UserOperationEventTopic = + "0x49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f"; + export async function deployEntryPoint( provider = ethers.provider ): Promise { return new EntryPoint__factory(provider.getSigner()).deploy(); } -export const encodePaymasterData = ( - feeToken = ethers.constants.AddressZero, - oracleAggregator = ethers.constants.AddressZero, - exchangeRate: BigNumberish = ethers.constants.Zero, - priceMarkup: BigNumberish = ethers.constants.Zero -) => { - return ethers.utils.defaultAbiCoder.encode( - ["uint48", "uint48", "address", "address", "uint256", "uint32"], - [ - MOCK_VALID_UNTIL, - MOCK_VALID_AFTER, - feeToken, - oracleAggregator, - exchangeRate, - priceMarkup, - ] - ); -}; - -export async function getUserOpEvent(ep: EntryPoint) { - const [log] = await ep.queryFilter( - ep.filters.UserOperationEvent(), - await ethers.provider.getBlockNumber() - ); - return log; -} +// export const encodePaymasterData = ( +// feeToken = ethers.constants.AddressZero, +// exchangeRate: BigNumberish = ethers.constants.Zero, +// priceMarkup: BigNumberish = ethers.constants.Zero +// ) => { +// return ethers.utils.defaultAbiCoder.encode( +// ["uint48", "uint48", "address", "uint256", "uint32"], +// [MOCK_VALID_UNTIL, MOCK_VALID_AFTER, feeToken, exchangeRate, priceMarkup] +// ); +// }; export const encodeERC20Approval = ( account: BiconomyAccountImplementation, @@ -99,7 +89,6 @@ describe("Biconomy Token Paymaster (with Bundler)", function () { let offchainSigner: Signer, deployer: Signer; let sampleTokenPaymaster: BiconomyTokenPaymaster; - let oracleAggregator: ChainlinkOracleAggregator; let smartWalletImp: BiconomyAccountImplementation; let ecdsaModule: EcdsaOwnershipRegistryModule; @@ -121,15 +110,11 @@ describe("Biconomy Token Paymaster (with Bundler)", function () { entryPoint = EntryPoint__factory.connect(process.env.ENTRYPOINT!, deployer); offchainSigner = ethersSigner[1]; - walletOwner = deployer; // ethersSigner[3]; + walletOwner = deployer; // ethersSigner[0]; // const offchainSignerAddress = await deployer.getAddress(); const walletOwnerAddress = await walletOwner.getAddress(); - oracleAggregator = await new ChainlinkOracleAggregator__factory( - deployer - ).deploy(walletOwnerAddress); - ecdsaModule = await new EcdsaOwnershipRegistryModule__factory( deployer ).deploy(); @@ -147,19 +132,13 @@ describe("Biconomy Token Paymaster (with Bundler)", function () { usdcMaticPriceFeedMock.address ); - const priceFeedTxUsdc: any = - await priceFeedUsdc.populateTransaction.getThePrice(); - - await oracleAggregator.setTokenOracle( - token.address, - usdcMaticPriceFeedMock.address, - 18, - priceFeedTxUsdc.data, - true + const nativeOracle = await new MockOracle__factory(deployer).deploy( + 82843594, + "MATIC/USD" ); - - const priceResult = await oracleAggregator.getTokenValueOfOneNativeToken( - token.address + const tokenOracle = await new MockOracle__factory(deployer).deploy( + 100000000, + "USDC/USD" ); sampleTokenPaymaster = await new BiconomyTokenPaymaster__factory( @@ -170,6 +149,17 @@ describe("Biconomy Token Paymaster (with Bundler)", function () { await offchainSigner.getAddress() ); + await sampleTokenPaymaster.setTokenOracle( + token.address, + tokenOracle.address, + nativeOracle.address, + true, + 172800 // 2 days + ); + + const priceResult = + await sampleTokenPaymaster.getTokenValueOfOneNativeToken(token.address); + smartWalletImp = await new BiconomyAccountImplementation__factory( deployer ).deploy(entryPoint.address); @@ -236,6 +226,9 @@ describe("Biconomy Token Paymaster (with Bundler)", function () { .connect(deployer) .transfer(walletAddress, ethers.utils.parseEther("100")); + const accountBalBefore = await token.balanceOf(walletAddress); + const feeReceiverBalBefore = await token.balanceOf(paymasterAddress); + const userOp1 = await fillAndSign( { sender: walletAddress, @@ -259,23 +252,126 @@ describe("Biconomy Token Paymaster (with Bundler)", function () { MOCK_VALID_UNTIL, MOCK_VALID_AFTER, token.address, - oracleAggregator.address, MOCK_FX, DEFAULT_FEE_MARKUP ); const sig = await offchainSigner.signMessage(arrayify(hash)); + const numVU = ethers.BigNumber.from(MOCK_VALID_UNTIL); + const numVA = ethers.BigNumber.from(MOCK_VALID_AFTER); + const numER = ethers.BigNumber.from(MOCK_FX); + const userOp = await fillAndSign( + { + ...userOp1, + paymasterAndData: ethers.utils.hexConcat([ + paymasterAddress, + ethers.utils.hexlify(1).slice(0, 4), + ethers.utils.hexZeroPad(ethers.utils.hexlify(numVU.toNumber()), 6), // 6 byte + ethers.utils.hexZeroPad(ethers.utils.hexlify(numVA.toNumber()), 6), // 6 byte + ethers.utils.hexZeroPad(token.address, 20), // 20 byte + ethers.utils.hexZeroPad(ethers.utils.hexlify(numER.toNumber()), 16), // 16 byte + ethers.utils.hexZeroPad( + ethers.utils.hexlify(DEFAULT_FEE_MARKUP), + 4 + ), // 4 byte + sig, + ]), + preVerificationGas: 55000, + }, + walletOwner, + entryPoint, + "nonce" + ); + + const signatureWithModuleAddress = ethers.utils.defaultAbiCoder.encode( + ["bytes", "address"], + [userOp.signature, ecdsaModule.address] + ); + + userOp.signature = signatureWithModuleAddress; + + const result: EthSendUserOperationResult = + await environment.sendUserOperation(userOp, entryPoint.address); + + const receipt = (await environment.getUserOperationReceipt(result.result)) + .result; + + const event = parseEvent(receipt.receipt, UserOperationEventTopic); + + const eventLogs = entryPoint.interface.decodeEventLog( + "UserOperationEvent", + event[0].data + ); + + expect(eventLogs.success).to.be.true; + + const accountBalAfter = await token.balanceOf(walletAddress); + const feeReceiverBalAfter = await token.balanceOf(paymasterAddress); + + expect(accountBalAfter).to.be.lt(accountBalBefore); + expect(feeReceiverBalAfter).to.be.gt(feeReceiverBalBefore); + + await expect( + entryPoint.handleOps([userOp], await offchainSigner.getAddress()) + ).to.be.reverted; + }); + + it("catch postOp is going revert and (don't process transaction by bundler)", async () => { + const userSCW: any = BiconomyAccountImplementation__factory.connect( + walletAddress, + deployer + ); + + await token + .connect(deployer) + .transfer(walletAddress, ethers.utils.parseEther("100")); + + const accountBalBefore = await token.balanceOf(walletAddress); + const feeReceiverBalBefore = await token.balanceOf(paymasterAddress); + + const userOp1 = await fillAndSign( + { + sender: walletAddress, + verificationGasLimit: 200000, + callData: encodeERC20Approval( + userSCW, + token, + paymasterAddress, + ethers.constants.Zero // making allowance 0 in execution + ), + preVerificationGas: 55000, + }, + walletOwner, + entryPoint, + "nonce" + ); + + const hash = await sampleTokenPaymaster.getHash( + userOp1, + ethers.utils.hexlify(1).slice(2, 4), + MOCK_VALID_UNTIL, + MOCK_VALID_AFTER, + token.address, + MOCK_FX, + DEFAULT_FEE_MARKUP + ); + const sig = await offchainSigner.signMessage(arrayify(hash)); + const numVU = ethers.BigNumber.from(MOCK_VALID_UNTIL); + const numVA = ethers.BigNumber.from(MOCK_VALID_AFTER); + const numER = ethers.BigNumber.from(MOCK_FX); const userOp = await fillAndSign( { ...userOp1, paymasterAndData: ethers.utils.hexConcat([ paymasterAddress, ethers.utils.hexlify(1).slice(0, 4), - encodePaymasterData( - token.address, - oracleAggregator.address, - MOCK_FX, - DEFAULT_FEE_MARKUP - ), + ethers.utils.hexZeroPad(ethers.utils.hexlify(numVU.toNumber()), 6), // 6 byte + ethers.utils.hexZeroPad(ethers.utils.hexlify(numVA.toNumber()), 6), // 6 byte + ethers.utils.hexZeroPad(token.address, 20), // 20 byte + ethers.utils.hexZeroPad(ethers.utils.hexlify(numER.toNumber()), 16), // 16 byte + ethers.utils.hexZeroPad( + ethers.utils.hexlify(DEFAULT_FEE_MARKUP), + 4 + ), // 4 byte sig, ]), preVerificationGas: 55000, @@ -292,10 +388,11 @@ describe("Biconomy Token Paymaster (with Bundler)", function () { userOp.signature = signatureWithModuleAddress; - await environment.sendUserOperation(userOp, entryPoint.address); + const result: EthSendUserOperationResult = + await environment.sendUserOperation(userOp, entryPoint.address); - const ev = await getUserOpEvent(entryPoint); - expect(ev.args.success).to.be.true; + const receipt = (await environment.getUserOperationReceipt(result.result)) + .result; await expect( entryPoint.handleOps([userOp], await offchainSigner.getAddress()) diff --git a/test/bundler-integration/token-paymaster/btpm-undeployed-wallet.ts b/test/bundler-integration/token-paymaster/btpm-undeployed-wallet.ts index 01bf57e..5fbd2cb 100644 --- a/test/bundler-integration/token-paymaster/btpm-undeployed-wallet.ts +++ b/test/bundler-integration/token-paymaster/btpm-undeployed-wallet.ts @@ -12,10 +12,9 @@ import { BiconomyAccountFactory__factory, BiconomyTokenPaymaster, BiconomyTokenPaymaster__factory, - ChainlinkOracleAggregator, - ChainlinkOracleAggregator__factory, MockPriceFeed__factory, MockToken, + MockOracle__factory, } from "../../../typechain-types"; import { EcdsaOwnershipRegistryModule, @@ -31,7 +30,11 @@ import { } from "../../../lib/account-abstraction/typechain"; import { arrayify, hexConcat, parseEther } from "ethers/lib/utils"; import { BigNumber, BigNumberish, Contract, Signer } from "ethers"; -import { BundlerTestEnvironment } from "../environment/bundlerEnvironment"; +import { + BundlerTestEnvironment, + EthSendUserOperationResult, +} from "../environment/bundlerEnvironment"; +import { getUserOpEvent, parseEvent } from "../../utils/testUtils"; export const AddressZero = ethers.constants.AddressZero; @@ -43,38 +46,25 @@ const DEFAULT_FEE_MARKUP = 1100000; const MOCK_FX: BigNumberish = "977100"; // matic to usdc approx +const UserOperationEventTopic = + "0x49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f"; + export async function deployEntryPoint( provider = ethers.provider ): Promise { return new EntryPoint__factory(provider.getSigner()).deploy(); } -export const encodePaymasterData = ( - feeToken = ethers.constants.AddressZero, - oracleAggregator = ethers.constants.AddressZero, - exchangeRate: BigNumberish = ethers.constants.Zero, - priceMarkup: BigNumberish = ethers.constants.Zero -) => { - return ethers.utils.defaultAbiCoder.encode( - ["uint48", "uint48", "address", "address", "uint256", "uint32"], - [ - MOCK_VALID_UNTIL, - MOCK_VALID_AFTER, - feeToken, - oracleAggregator, - exchangeRate, - priceMarkup, - ] - ); -}; - -export async function getUserOpEvent(ep: EntryPoint) { - const [log] = await ep.queryFilter( - ep.filters.UserOperationEvent(), - await ethers.provider.getBlockNumber() - ); - return log; -} +// export const encodePaymasterData = ( +// feeToken = ethers.constants.AddressZero, +// exchangeRate: BigNumberish = ethers.constants.Zero, +// priceMarkup: BigNumberish = ethers.constants.Zero +// ) => { +// return ethers.utils.defaultAbiCoder.encode( +// ["uint48", "uint48", "address", "uint256", "uint32"], +// [MOCK_VALID_UNTIL, MOCK_VALID_AFTER, feeToken, exchangeRate, priceMarkup] +// ); +// }; export const encodeERC20Approval = ( account: BiconomyAccountImplementation, @@ -99,7 +89,6 @@ describe("Biconomy Token Paymaster (with Bundler)", function () { let offchainSigner: Signer, deployer: Signer; let sampleTokenPaymaster: BiconomyTokenPaymaster; - let oracleAggregator: ChainlinkOracleAggregator; // Could also use published package or added submodule (for Account Implementation and Factory) let smartWalletImp: BiconomyAccountImplementation; @@ -123,15 +112,11 @@ describe("Biconomy Token Paymaster (with Bundler)", function () { entryPoint = EntryPoint__factory.connect(process.env.ENTRYPOINT!, deployer); offchainSigner = ethersSigner[1]; - walletOwner = deployer; // ethersSigner[3]; + walletOwner = deployer; // ethersSigner[0]; // const offchainSignerAddress = await deployer.getAddress(); const walletOwnerAddress = await walletOwner.getAddress(); - oracleAggregator = await new ChainlinkOracleAggregator__factory( - deployer - ).deploy(walletOwnerAddress); - ecdsaModule = await new EcdsaOwnershipRegistryModule__factory( deployer ).deploy(); @@ -149,15 +134,13 @@ describe("Biconomy Token Paymaster (with Bundler)", function () { usdcMaticPriceFeedMock.address ); - const priceFeedTxUsdc: any = - await priceFeedUsdc.populateTransaction.getThePrice(); - - await oracleAggregator.setTokenOracle( - token.address, - usdcMaticPriceFeedMock.address, - 18, - priceFeedTxUsdc.data, - true + const nativeOracle = await new MockOracle__factory(deployer).deploy( + 82843594, + "MATIC/USD" + ); + const tokenOracle = await new MockOracle__factory(deployer).deploy( + 100000000, + "USDC/USD" ); sampleTokenPaymaster = await new BiconomyTokenPaymaster__factory( @@ -168,6 +151,17 @@ describe("Biconomy Token Paymaster (with Bundler)", function () { await offchainSigner.getAddress() ); + await sampleTokenPaymaster.setTokenOracle( + token.address, + tokenOracle.address, + nativeOracle.address, + true, + 172800 // 2 days + ); + + const priceResult = + await sampleTokenPaymaster.getTokenValueOfOneNativeToken(token.address); + smartWalletImp = await new BiconomyAccountImplementation__factory( deployer ).deploy(entryPoint.address); @@ -228,6 +222,9 @@ describe("Biconomy Token Paymaster (with Bundler)", function () { .connect(deployer) .transfer(walletAddress, ethers.utils.parseEther("100")); + const accountBalBefore = await token.balanceOf(walletAddress); + const feeReceiverBalBefore = await token.balanceOf(paymasterAddress); + const owner = await walletOwner.getAddress(); const AccountFactory = await ethers.getContractFactory( "SmartAccountFactory" @@ -274,23 +271,27 @@ describe("Biconomy Token Paymaster (with Bundler)", function () { MOCK_VALID_UNTIL, MOCK_VALID_AFTER, token.address, - oracleAggregator.address, MOCK_FX, DEFAULT_FEE_MARKUP ); const sig = await offchainSigner.signMessage(arrayify(hash)); + const numVU = ethers.BigNumber.from(MOCK_VALID_UNTIL); + const numVA = ethers.BigNumber.from(MOCK_VALID_AFTER); + const numER = ethers.BigNumber.from(MOCK_FX); const userOp = await fillAndSign( { ...userOp1, paymasterAndData: ethers.utils.hexConcat([ paymasterAddress, ethers.utils.hexlify(1).slice(0, 4), - encodePaymasterData( - token.address, - oracleAggregator.address, - MOCK_FX, - DEFAULT_FEE_MARKUP - ), + ethers.utils.hexZeroPad(ethers.utils.hexlify(numVU.toNumber()), 6), // 6 byte + ethers.utils.hexZeroPad(ethers.utils.hexlify(numVA.toNumber()), 6), // 6 byte + ethers.utils.hexZeroPad(token.address, 20), // 20 byte + ethers.utils.hexZeroPad(ethers.utils.hexlify(numER.toNumber()), 16), // 16 byte + ethers.utils.hexZeroPad( + ethers.utils.hexlify(DEFAULT_FEE_MARKUP), + 4 + ), // 4 byte sig, ]), }, @@ -306,10 +307,26 @@ describe("Biconomy Token Paymaster (with Bundler)", function () { userOp.signature = signatureWithModuleAddress; - await environment.sendUserOperation(userOp, entryPoint.address); + const result: EthSendUserOperationResult = + await environment.sendUserOperation(userOp, entryPoint.address); + + const receipt = (await environment.getUserOperationReceipt(result.result)) + .result; + + const event = parseEvent(receipt.receipt, UserOperationEventTopic); + + const eventLogs = entryPoint.interface.decodeEventLog( + "UserOperationEvent", + event[0].data + ); + + expect(eventLogs.success).to.be.true; + + const accountBalAfter = await token.balanceOf(walletAddress); + const feeReceiverBalAfter = await token.balanceOf(paymasterAddress); - const ev = await getUserOpEvent(entryPoint); - expect(ev.args.success).to.be.true; + expect(accountBalAfter).to.be.lt(accountBalBefore); + expect(feeReceiverBalAfter).to.be.gt(feeReceiverBalBefore); await expect( entryPoint.handleOps([userOp], await offchainSigner.getAddress()) diff --git a/test/bundler-integration/token-paymaster/oracle-aggregator-specs.ts b/test/bundler-integration/token-paymaster/oracle-aggregator-specs.ts index 5f87455..55683df 100644 --- a/test/bundler-integration/token-paymaster/oracle-aggregator-specs.ts +++ b/test/bundler-integration/token-paymaster/oracle-aggregator-specs.ts @@ -12,15 +12,10 @@ import { BiconomyAccountFactory__factory, BiconomyTokenPaymaster, BiconomyTokenPaymaster__factory, - ChainlinkOracleAggregator, - ChainlinkOracleAggregator__factory, - MockChainlinkOracleAggregator__factory, - MockPriceFeed, MockStalePriceFeed__factory, - MockStalePriceFeed, MockPriceFeed__factory, MockToken, - MockChainlinkOracleAggregator, + MockOracle__factory, } from "../../../typechain-types"; import { EcdsaOwnershipRegistryModule, @@ -37,6 +32,7 @@ import { import { arrayify, parseEther } from "ethers/lib/utils"; import { BigNumber, BigNumberish, Contract, Signer } from "ethers"; import { BundlerTestEnvironment } from "../environment/bundlerEnvironment"; +import { getUserOpEvent, parseEvent } from "../../utils/testUtils"; export const AddressZero = ethers.constants.AddressZero; @@ -46,32 +42,19 @@ const DEFAULT_FEE_MARKUP = 1100000; const MOCK_FX: BigNumberish = "977100"; // matic to usdc approx -export const encodePaymasterData = ( - feeToken = ethers.constants.AddressZero, - oracleAggregator = ethers.constants.AddressZero, - exchangeRate: BigNumberish = ethers.constants.Zero, - priceMarkup: BigNumberish = ethers.constants.Zero -) => { - return ethers.utils.defaultAbiCoder.encode( - ["uint48", "uint48", "address", "address", "uint256", "uint32"], - [ - MOCK_VALID_UNTIL, - MOCK_VALID_AFTER, - feeToken, - oracleAggregator, - exchangeRate, - priceMarkup, - ] - ); -}; +const UserOperationEventTopic = + "0x49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f"; -export async function getUserOpEvent(ep: EntryPoint) { - const [log] = await ep.queryFilter( - ep.filters.UserOperationEvent(), - await ethers.provider.getBlockNumber() - ); - return log; -} +// export const encodePaymasterData = ( +// feeToken = ethers.constants.AddressZero, +// exchangeRate: BigNumberish = ethers.constants.Zero, +// priceMarkup: BigNumberish = ethers.constants.Zero +// ) => { +// return ethers.utils.defaultAbiCoder.encode( +// ["uint48", "uint48", "address", "uint256", "uint32"], +// [MOCK_VALID_UNTIL, MOCK_VALID_AFTER, feeToken, exchangeRate, priceMarkup] +// ); +// }; export const encodeERC20Approval = ( account: BiconomyAccountImplementation, @@ -96,8 +79,6 @@ describe("Biconomy Token Paymaster (With Bundler)", function () { let offchainSigner: Signer, deployer: Signer; let sampleTokenPaymaster: BiconomyTokenPaymaster; - let oracleAggregator: ChainlinkOracleAggregator; - let staleOracleAggregator: MockChainlinkOracleAggregator; // Could also use published package or added submodule (for Account Implementation and Factory) let smartWalletImp: BiconomyAccountImplementation; @@ -122,18 +103,11 @@ describe("Biconomy Token Paymaster (With Bundler)", function () { entryPoint = EntryPoint__factory.connect(process.env.ENTRYPOINT!, deployer); offchainSigner = ethersSigner[1]; - walletOwner = deployer; // ethersSigner[3]; + walletOwner = deployer; // ethersSigner[0]; // const offchainSignerAddress = await deployer.getAddress(); const walletOwnerAddress = await walletOwner.getAddress(); - oracleAggregator = await new ChainlinkOracleAggregator__factory( - deployer - ).deploy(walletOwnerAddress); - staleOracleAggregator = await new MockChainlinkOracleAggregator__factory( - deployer - ).deploy(walletOwnerAddress); - ecdsaModule = await new EcdsaOwnershipRegistryModule__factory( deployer ).deploy(); @@ -146,44 +120,13 @@ describe("Biconomy Token Paymaster (With Bundler)", function () { deployer ).deploy(); - const priceFeedUsdc = await ethers.getContractAt( - "FeedInterface", - usdcMaticPriceFeedMock.address - ); - - const priceFeedTxUsdc: any = - await priceFeedUsdc.populateTransaction.getThePrice(); - - await oracleAggregator.setTokenOracle( - token.address, - usdcMaticPriceFeedMock.address, - 18, - priceFeedTxUsdc.data, - true - ); - - const stalePriceFeedMock = await new MockStalePriceFeed__factory( - deployer - ).deploy(); - - const priceFeedStale = await ethers.getContractAt( - "FeedInterface", - stalePriceFeedMock.address - ); - - const priceFeedTxStale: any = - await priceFeedStale.populateTransaction.getThePrice(); - - await staleOracleAggregator.setTokenOracle( - token.address, - stalePriceFeedMock.address, - 18, - priceFeedTxStale.data, - true + const nativeOracle = await new MockOracle__factory(deployer).deploy( + 82843594, + "MATIC/USD" ); - - const priceResult = await oracleAggregator.getTokenValueOfOneNativeToken( - token.address + const tokenOracle = await new MockOracle__factory(deployer).deploy( + 100000000, + "USDC/USD" ); sampleTokenPaymaster = await new BiconomyTokenPaymaster__factory( @@ -194,6 +137,16 @@ describe("Biconomy Token Paymaster (With Bundler)", function () { await offchainSigner.getAddress() ); + await sampleTokenPaymaster.setTokenOracle( + token.address, + tokenOracle.address, + nativeOracle.address, + true, + 172800 // 2 days + ); + const priceResult = + await sampleTokenPaymaster.getTokenValueOfOneNativeToken(token.address); + smartWalletImp = await new BiconomyAccountImplementation__factory( deployer ).deploy(entryPoint.address); @@ -250,132 +203,13 @@ describe("Biconomy Token Paymaster (With Bundler)", function () { }); describe("Token Paymaster with good and bad oracle aggregator", () => { - it("succeed with fallback exchange rate in case price feed reverts", async () => { - const userSCW: any = BiconomyAccountImplementation__factory.connect( - walletAddress, - deployer - ); - - await token - .connect(deployer) - .transfer(walletAddress, ethers.utils.parseEther("100")); - - const owner = await walletOwner.getAddress(); - const AccountFactory = await ethers.getContractFactory( - "SmartAccountFactory" - ); - const ecdsaOwnershipSetupData = ecdsaModule.interface.encodeFunctionData( - "initForSmartAccount", - [owner] - ); - - const smartAccountDeploymentIndex = 0; - - const deploymentData = AccountFactory.interface.encodeFunctionData( - "deployCounterFactualAccount", - [ - ecdsaModule.address, - ecdsaOwnershipSetupData, - smartAccountDeploymentIndex, - ] - ); - - const userOp1 = await fillAndSign( - { - sender: walletAddress, - verificationGasLimit: 200000, - preVerificationGas: 50000, - callData: encodeERC20Approval( - userSCW, - token, - paymasterAddress, - ethers.constants.MaxUint256 - ), - }, - walletOwner, - entryPoint, - "nonce" - ); - - const hash = await sampleTokenPaymaster.getHash( - userOp1, - ethers.utils.hexlify(1).slice(2, 4), - MOCK_VALID_UNTIL, - MOCK_VALID_AFTER, - token.address, - staleOracleAggregator.address, - MOCK_FX, - DEFAULT_FEE_MARKUP - ); - const sig = await offchainSigner.signMessage(arrayify(hash)); - const userOp = await fillAndSign( - { - ...userOp1, - paymasterAndData: ethers.utils.hexConcat([ - paymasterAddress, - ethers.utils.hexlify(1).slice(0, 4), - encodePaymasterData( - token.address, - staleOracleAggregator.address, - MOCK_FX, - DEFAULT_FEE_MARKUP - ), - sig, - ]), - }, - walletOwner, - entryPoint, - "nonce" - ); - - const signatureWithModuleAddress = ethers.utils.defaultAbiCoder.encode( - ["bytes", "address"], - [userOp.signature, ecdsaModule.address] - ); - - userOp.signature = signatureWithModuleAddress; - - const { result: userOpHash } = await environment.sendUserOperation( - userOp, - entryPoint.address - ); - - const { - result: { - receipt: { transactionHash }, - }, - } = await environment.getUserOperationReceipt(userOpHash); - const receipt = await ethers.provider.getTransactionReceipt( - transactionHash - ); - - const ev = await getUserOpEvent(entryPoint); - expect(ev.args.success).to.be.true; - - const BiconomyTokenPaymaster = await ethers.getContractFactory( - "BiconomyTokenPaymaster" - ); - - const eventLogs = BiconomyTokenPaymaster.interface.decodeEventLog( - "TokenPaymasterOperation", - receipt.logs[3].data - ); - - // Confirming that it's using backup (external) exchange rate in case oracle aggregator / price feed is stale / anything goes wrong - expect(eventLogs.exchangeRate.toString()).to.be.equal(MOCK_FX); - - await expect( - entryPoint.handleOps([userOp], await offchainSigner.getAddress()) - ).to.be.reverted; - }); - it("succeed with exchange rate based on prcie feed in case everything goes well", async () => { const userSCW: any = BiconomyAccountImplementation__factory.connect( walletAddress, deployer ); - const rate1 = await oracleAggregator.getTokenValueOfOneNativeToken( + const rate1 = await sampleTokenPaymaster.getTokenValueOfOneNativeToken( token.address ); @@ -426,23 +260,27 @@ describe("Biconomy Token Paymaster (With Bundler)", function () { MOCK_VALID_UNTIL, MOCK_VALID_AFTER, token.address, - oracleAggregator.address, MOCK_FX, DEFAULT_FEE_MARKUP ); const sig = await offchainSigner.signMessage(arrayify(hash)); + const numVU = ethers.BigNumber.from(MOCK_VALID_UNTIL); + const numVA = ethers.BigNumber.from(MOCK_VALID_AFTER); + const numER = ethers.BigNumber.from(MOCK_FX); const userOp = await fillAndSign( { ...userOp1, paymasterAndData: ethers.utils.hexConcat([ paymasterAddress, ethers.utils.hexlify(1).slice(0, 4), - encodePaymasterData( - token.address, - oracleAggregator.address, - MOCK_FX, - DEFAULT_FEE_MARKUP - ), + ethers.utils.hexZeroPad(ethers.utils.hexlify(numVU.toNumber()), 6), // 6 byte + ethers.utils.hexZeroPad(ethers.utils.hexlify(numVA.toNumber()), 6), // 6 byte + ethers.utils.hexZeroPad(token.address, 20), // 20 byte + ethers.utils.hexZeroPad(ethers.utils.hexlify(numER.toNumber()), 16), // 16 byte + ethers.utils.hexZeroPad( + ethers.utils.hexlify(DEFAULT_FEE_MARKUP), + 4 + ), // 4 byte sig, ]), }, @@ -472,127 +310,15 @@ describe("Biconomy Token Paymaster (With Bundler)", function () { transactionHash ); - const ev = await getUserOpEvent(entryPoint); - expect(ev.args.success).to.be.true; - - const BiconomyTokenPaymaster = await ethers.getContractFactory( - "BiconomyTokenPaymaster" - ); - - const eventLogs = BiconomyTokenPaymaster.interface.decodeEventLog( - "TokenPaymasterOperation", - receipt.logs[3].data - ); - - // Confirming that it's using backup (external) exchange rate in case oracle aggregator / price feed is stale / anything goes wrong - expect(eventLogs.exchangeRate).to.be.equal(rate1); - - await expect( - entryPoint.handleOps([userOp], await offchainSigner.getAddress()) - ).to.be.reverted; - }); - - it("succeed with fallback exchange rate in case oracle aggregator is 0 address", async () => { - const userSCW: any = BiconomyAccountImplementation__factory.connect( - walletAddress, - deployer - ); - - await token - .connect(deployer) - .transfer(walletAddress, ethers.utils.parseEther("100")); + const event = parseEvent(receipt, UserOperationEventTopic); - const owner = await walletOwner.getAddress(); - const AccountFactory = await ethers.getContractFactory( - "SmartAccountFactory" + const eventLogsUserop = entryPoint.interface.decodeEventLog( + "UserOperationEvent", + event[0].data ); - const ecdsaOwnershipSetupData = ecdsaModule.interface.encodeFunctionData( - "initForSmartAccount", - [owner] - ); - - const smartAccountDeploymentIndex = 0; - const deploymentData = AccountFactory.interface.encodeFunctionData( - "deployCounterFactualAccount", - [ - ecdsaModule.address, - ecdsaOwnershipSetupData, - smartAccountDeploymentIndex, - ] - ); - - const userOp1 = await fillAndSign( - { - sender: walletAddress, - verificationGasLimit: 200000, - preVerificationGas: 50000, - callData: encodeERC20Approval( - userSCW, - token, - paymasterAddress, - ethers.constants.MaxUint256 - ), - }, - walletOwner, - entryPoint, - "nonce" - ); - - const hash = await sampleTokenPaymaster.getHash( - userOp1, - ethers.utils.hexlify(1).slice(2, 4), - MOCK_VALID_UNTIL, - MOCK_VALID_AFTER, - token.address, - ethers.constants.AddressZero, - MOCK_FX, - DEFAULT_FEE_MARKUP - ); - const sig = await offchainSigner.signMessage(arrayify(hash)); - const userOp = await fillAndSign( - { - ...userOp1, - paymasterAndData: ethers.utils.hexConcat([ - paymasterAddress, - ethers.utils.hexlify(1).slice(0, 4), - encodePaymasterData( - token.address, - ethers.constants.AddressZero, - MOCK_FX, - DEFAULT_FEE_MARKUP - ), - sig, - ]), - }, - walletOwner, - entryPoint, - "nonce" - ); - - const signatureWithModuleAddress = ethers.utils.defaultAbiCoder.encode( - ["bytes", "address"], - [userOp.signature, ecdsaModule.address] - ); - - userOp.signature = signatureWithModuleAddress; - - const { result: userOpHash } = await environment.sendUserOperation( - userOp, - entryPoint.address - ); - - const { - result: { - receipt: { transactionHash }, - }, - } = await environment.getUserOperationReceipt(userOpHash); - const receipt = await ethers.provider.getTransactionReceipt( - transactionHash - ); - - const ev = await getUserOpEvent(entryPoint); - expect(ev.args.success).to.be.true; + // eslint-disable-next-line no-unused-expressions + expect(eventLogsUserop.success).to.be.true; const BiconomyTokenPaymaster = await ethers.getContractFactory( "BiconomyTokenPaymaster" @@ -604,11 +330,14 @@ describe("Biconomy Token Paymaster (With Bundler)", function () { ); // Confirming that it's using backup (external) exchange rate in case oracle aggregator / price feed is stale / anything goes wrong - expect(eventLogs.exchangeRate).to.be.equal(MOCK_FX); + expect(eventLogs.exchangeRate).to.be.equal(rate1); await expect( entryPoint.handleOps([userOp], await offchainSigner.getAddress()) ).to.be.reverted; }); + + // TODO + // it("succeed with fallback exchange rate in case price feed reverts", async () => { }); }); diff --git a/test/foundry/base/SATestBase.sol b/test/foundry/base/SATestBase.sol new file mode 100644 index 0000000..ca1e086 --- /dev/null +++ b/test/foundry/base/SATestBase.sol @@ -0,0 +1,333 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.23; + +import {Test, Vm} from "forge-std/Test.sol"; +import {MockToken} from "../../../contracts/test/helpers/MockToken.sol"; +import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; +import {IEntryPoint} from "@account-abstraction/contracts/interfaces/IEntryPoint.sol"; +import {EntryPoint} from "@account-abstraction/contracts/core/EntryPoint.sol"; +import {IStakeManager} from "@account-abstraction/contracts/interfaces/IStakeManager.sol"; +import {UserOperation} from "@account-abstraction/contracts/interfaces/UserOperation.sol"; +import {SmartAccountFactory} from + "@biconomy-devx/account-contracts-v2/contracts/smart-account/factory/SmartAccountFactory.sol"; +import {SmartAccount} from "@biconomy-devx/account-contracts-v2/contracts/smart-account/SmartAccount.sol"; +import {EcdsaOwnershipRegistryModule} from + "@biconomy-devx/account-contracts-v2/contracts/smart-account/modules/EcdsaOwnershipRegistryModule.sol"; +import "../../BytesLib.sol"; + +abstract contract SATestBase is Test { + using ECDSA for bytes32; + + // Test Environment Configuration + string constant mnemonic = "test test test test test test test test test test test junk"; + uint256 constant testAccountCount = 10; + uint256 constant initialMainAccountFunds = 100000 ether; + uint256 constant defaultPreVerificationGas = 21000; + // Event Topics + bytes32 constant userOperationEventTopic = 0x49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f; + bytes32 constant userOperationRevertReasonTopic = 0x1c4fada7374c0a9ee8841fc38afe82932dc0f8e69012e927f061a8bae611a201; + + uint32 nextKeyIndex; + + struct UserOperationEventData { + bytes32 userOpHash; + address sender; + address paymaster; + uint256 nonce; + bool success; + uint256 actualGasCost; + uint256 actualGasUsed; + } + + struct UserOperationRevertReasonEventData { + bytes32 userOpHash; + address sender; + uint256 nonce; + bytes revertReason; + } + + // Test Accounts + struct TestAccount { + address payable addr; + uint256 privateKey; + } + + TestAccount[] testAccounts; + TestAccount alice; + TestAccount bob; + TestAccount charlie; + TestAccount dan; + TestAccount emma; + TestAccount frank; + TestAccount george; + TestAccount henry; + TestAccount ida; + + TestAccount owner; + + // Test Tokens + MockToken token; + + // ERC4337 Contracts + EntryPoint entryPoint; + SmartAccount saImplementation; + SmartAccountFactory factory; + + // Modules + EcdsaOwnershipRegistryModule ecdsaOwnershipRegistryModule; + + function getNextPrivateKey() internal returns (uint256) { + return vm.deriveKey(mnemonic, ++nextKeyIndex); + } + + function setUp() public virtual { + // Generate Test Addresses + for (uint256 i = 0; i < testAccountCount; i++) { + uint256 privateKey = getNextPrivateKey(); + testAccounts.push(TestAccount(payable(vm.addr(privateKey)), privateKey)); + + deal(testAccounts[i].addr, initialMainAccountFunds); + } + + // Name Test Addresses + alice = testAccounts[0]; + vm.label(alice.addr, string.concat("Alice", vm.toString(uint256(0)))); + + bob = testAccounts[1]; + vm.label(bob.addr, string.concat("Bob", vm.toString(uint256(1)))); + + charlie = testAccounts[2]; + vm.label(charlie.addr, string.concat("Charlie", vm.toString(uint256(2)))); + + dan = testAccounts[3]; + vm.label(dan.addr, string.concat("Dan", vm.toString(uint256(3)))); + + emma = testAccounts[4]; + vm.label(emma.addr, string.concat("Emma", vm.toString(uint256(4)))); + + frank = testAccounts[5]; + vm.label(frank.addr, string.concat("Frank", vm.toString(uint256(5)))); + + george = testAccounts[6]; + vm.label(george.addr, string.concat("George", vm.toString(uint256(6)))); + + henry = testAccounts[7]; + vm.label(henry.addr, string.concat("Henry", vm.toString(uint256(7)))); + + ida = testAccounts[7]; + vm.label(ida.addr, string.concat("Ida", vm.toString(uint256(8)))); + + // Name Owner + owner = testAccounts[8]; + vm.label(owner.addr, string.concat("Owner", vm.toString(uint256(9)))); + + // Deploy Test Tokens + token = new MockToken(); + vm.label(address(token), "Test Token"); + + // Deploy ERC4337 Contracts + entryPoint = new EntryPoint(); + vm.label(address(entryPoint), "Entry Point"); + + saImplementation = new SmartAccount(entryPoint); + vm.label(address(saImplementation), "Smart Account Implementation"); + + factory = new SmartAccountFactory(address(saImplementation), owner.addr); + vm.label(address(factory), "Smart Account Factory"); + + // Deploy Modules + ecdsaOwnershipRegistryModule = new EcdsaOwnershipRegistryModule(); + vm.label(address(ecdsaOwnershipRegistryModule), "ECDSA Ownership Registry Module"); + } + + // Utility Functions + function getSmartAccountWithModule( + address _moduleSetupContract, + bytes memory _moduleSetupData, + uint256 _index, + string memory _label + ) internal returns (SmartAccount sa) { + sa = SmartAccount(payable(factory.deployCounterFactualAccount(_moduleSetupContract, _moduleSetupData, _index))); + vm.label(address(sa), _label); + } + + function getSmartAccountExecuteCalldata(address _dest, uint256 _value, bytes memory _calldata) + internal + pure + returns (bytes memory) + { + return abi.encodeCall(SmartAccount.execute, (_dest, _value, _calldata)); + } + + function getUserOperationEventData(Vm.Log[] memory _entries) + internal + returns (UserOperationEventData memory data) + { + for (uint256 i = 0; i < _entries.length; ++i) { + if (_entries[i].topics[0] != userOperationEventTopic) { + continue; + } + data.userOpHash = _entries[i].topics[1]; + data.sender = address(uint160(uint256(_entries[i].topics[2]))); + data.paymaster = address(uint160(uint256(_entries[i].topics[3]))); + (data.nonce, data.success, data.actualGasCost, data.actualGasUsed) = + abi.decode(_entries[i].data, (uint256, bool, uint256, uint256)); + return data; + } + fail("entries does not contain UserOperationEvent"); + } + + function getUserOperationRevertReasonEventData(Vm.Log[] memory _entries) + internal + returns (UserOperationRevertReasonEventData memory data) + { + for (uint256 i = 0; i < _entries.length; ++i) { + if (_entries[i].topics[0] != userOperationRevertReasonTopic) { + continue; + } + data.userOpHash = _entries[i].topics[1]; + data.sender = address(uint160(uint256(_entries[i].topics[2]))); + (data.nonce, data.revertReason) = abi.decode(_entries[i].data, (uint256, bytes)); + return data; + } + fail("entries does not contain UserOperationRevertReasonEvent"); + } + + function arraifyOps(UserOperation memory _op) internal pure returns (UserOperation[] memory) { + UserOperation[] memory ops = new UserOperation[](1); + ops[0] = _op; + return ops; + } + + function arraifyOps(UserOperation memory _op1, UserOperation memory _op2) + internal + pure + returns (UserOperation[] memory) + { + UserOperation[] memory ops = new UserOperation[](2); + ops[0] = _op1; + ops[1] = _op2; + return ops; + } + + function arraifyOps(UserOperation memory _op1, UserOperation memory _op2, UserOperation memory _op3) + internal + pure + returns (UserOperation[] memory) + { + UserOperation[] memory ops = new UserOperation[](3); + ops[0] = _op1; + ops[1] = _op2; + ops[2] = _op3; + return ops; + } + + // Module Setup Data Helpers + function getEcdsaOwnershipRegistryModuleSetupData(address _owner) internal pure returns (bytes memory) { + return abi.encodeCall(EcdsaOwnershipRegistryModule.initForSmartAccount, (_owner)); + } + + // Validation Module Op Creation Helpers + function makeEcdsaModuleUserOp( + bytes memory _calldata, + SmartAccount _sa, + uint192 _nonceKey, + TestAccount memory _signer, + bytes memory _pnd + ) internal view returns (UserOperation memory op) { + op = UserOperation({ + sender: address(_sa), + nonce: entryPoint.getNonce(address(_sa), _nonceKey), + initCode: bytes(""), + callData: _calldata, + // Review: If left to this some test fail + // callGasLimit: gasleft() / 100, + // verificationGasLimit: gasleft() / 100, + // preVerificationGas: defaultPreVerificationGas, + // maxFeePerGas: tx.gasprice, + // maxPriorityFeePerGas: tx.gasprice - block.basefee, + callGasLimit: 100000, + verificationGasLimit: 200000, + preVerificationGas: 50000, + maxFeePerGas: 100000000000, + maxPriorityFeePerGas: 40000000000, + paymasterAndData: _pnd, + signature: bytes("") + }); + + // Sign the UserOp + bytes32 userOpHash = entryPoint.getUserOpHash(op); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(_signer.privateKey, userOpHash); + op.signature = abi.encode(abi.encodePacked(r, s, v), ecdsaOwnershipRegistryModule); + } + + function signUserOp(UserOperation memory op, uint256 _key) public returns (bytes memory signature) { + bytes32 hash = entryPoint.getUserOpHash(op); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(_key, hash.toEthSignedMessageHash()); + signature = abi.encodePacked(r, s, v); + signature = abi.encode(signature, address(ecdsaOwnershipRegistryModule)); + } + + function simulateVerificationGas(IEntryPoint _entrypoint, UserOperation memory op) + public + returns (UserOperation memory, uint256 preFund) + { + (bool success, bytes memory ret) = + address(_entrypoint).call(abi.encodeWithSelector(EntryPoint.simulateValidation.selector, op)); + require(!success); + bytes memory data = BytesLib.slice(ret, 4, ret.length - 4); + (IEntryPoint.ReturnInfo memory retInfo,,,) = abi.decode( + data, (IEntryPoint.ReturnInfo, IStakeManager.StakeInfo, IStakeManager.StakeInfo, IStakeManager.StakeInfo) + ); + op.preVerificationGas = retInfo.preOpGas; + op.verificationGasLimit = retInfo.preOpGas; + op.maxFeePerGas = (retInfo.prefund * 11) / (retInfo.preOpGas * 10); + op.maxPriorityFeePerGas = 1; + return (op, retInfo.prefund); + } + + function simulateCallGas(IEntryPoint _entrypoint, UserOperation memory op) internal returns (uint256) { + try this.calcGas(_entrypoint, op.sender, op.callData) { + revert("Should have failed"); + } catch Error(string memory reason) { + uint256 gas = abi.decode(bytes(reason), (uint256)); + return (gas * 11) / 10; + } catch { + revert("Should have failed"); + } + } + + // not used internally + function calcGas(IEntryPoint _entrypoint, address _to, bytes memory _data) external { + vm.startPrank(address(_entrypoint)); + uint256 g = gasleft(); + (bool success,) = _to.call(_data); + require(success); + g = g - gasleft(); + bytes memory r = abi.encode(g); + vm.stopPrank(); + require(false, string(r)); + } + + function fillUserOp(SmartAccount _sender, uint256 _key, address _to, uint256 _value, bytes memory _data) + public + returns (UserOperation memory op, uint256 prefund) + { + op.sender = address(_sender); + op.nonce = entryPoint.getNonce(address(_sender), 0); + op.callData = abi.encodeWithSelector(SmartAccount.execute_ncC.selector, _to, _value, _data); + op.callGasLimit = 50000; + op.verificationGasLimit = 80000; + op.preVerificationGas = 50000; + op.maxFeePerGas = 1000000000; + op.maxPriorityFeePerGas = 100; + op.signature = signUserOp(op, _key); + (op, prefund) = simulateVerificationGas(entryPoint, op); + op.callGasLimit = simulateCallGas(entryPoint, op); + + //op.signature = signUserOp(op, _name); + + op.signature = abi.encode(op.signature, address(ecdsaOwnershipRegistryModule)); + } +} diff --git a/test/foundry/token-paymaster/TokenPaymaster.t.sol b/test/foundry/token-paymaster/TokenPaymaster.t.sol new file mode 100644 index 0000000..34d6e0a --- /dev/null +++ b/test/foundry/token-paymaster/TokenPaymaster.t.sol @@ -0,0 +1,332 @@ +// SPDX-License-Identifier: Unlicense +pragma solidity >=0.8.0; + +import {stdStorage, StdStorage, Test} from "forge-std/Test.sol"; +import {Utilities} from "../../utils/Utilities.sol"; +import {console2} from "forge-std/console2.sol"; +import {Vm} from "forge-std/Vm.sol"; + +import {BiconomyTokenPaymaster} from "../../../contracts/token/BiconomyTokenPaymaster.sol"; +import {IBiconomyTokenPaymaster} from "../../../contracts/interfaces/paymasters/IBiconomyTokenPaymaster.sol"; +import "../../BytesLib.sol"; +import "../../../contracts/test/helpers/TestCounter.sol"; + +import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; +import {IEntryPoint} from "@account-abstraction/contracts/interfaces/IEntryPoint.sol"; +import {UserOperation} from "@account-abstraction/contracts/interfaces/UserOperation.sol"; +import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; +import {SmartAccount} from "@biconomy-devx/account-contracts-v2/contracts/smart-account/SmartAccount.sol"; +import {EcdsaOwnershipRegistryModule} from + "@biconomy-devx/account-contracts-v2/contracts/smart-account/modules/EcdsaOwnershipRegistryModule.sol"; + +import {MockToken} from "../../../contracts/test/helpers/MockToken.sol"; +// import {MockPriceFeed} from "../../../contracts/test/helpers/MockPriceFeed.sol"; +import {MockOracle} from "../../../contracts/test/helpers/MockOracle.sol"; +import {FeedInterface} from "../../../contracts/token/oracles/FeedInterface.sol"; +import {SATestBase} from "../base/SATestBase.sol"; +import { MathLib } from "../../../contracts/libs/MathLib.sol"; + +error SetupIncomplete(); + +using ECDSA for bytes32; + +contract TokenPaymasterTest is SATestBase { + SmartAccount sa; + + uint256 internal keyUser; + uint256 internal keyVerifyingSigner; + + BiconomyTokenPaymaster public _btpm; + MockToken usdc; + MockOracle nativeOracle; + MockOracle tokenOracle; + TestCounter counter; + + function setUp() public virtual override { + super.setUp(); + + /*uint256 testResult = MathLib.minuint256( + 50, + 60 + ); + + console2.log("testResult ", testResult); + + uint256 testResult2 = MathLib.minuint32( + 50, + 60 + ); + + console2.log("testResult2 ", testResult2);*/ + + vm.warp(1680509051); + console2.log("current block timestamp ", block.timestamp); + + // Deploy Smart Account with default module + uint256 smartAccountDeploymentIndex = 0; + bytes memory moduleSetupData = getEcdsaOwnershipRegistryModuleSetupData(alice.addr); + sa = getSmartAccountWithModule( + address(ecdsaOwnershipRegistryModule), moduleSetupData, smartAccountDeploymentIndex, "aliceSA" + ); + + keyUser = alice.privateKey; + keyVerifyingSigner = bob.privateKey; + + _btpm = new BiconomyTokenPaymaster(alice.addr, entryPoint, bob.addr); + usdc = new MockToken(); + nativeOracle = new MockOracle(82843594, "MATIC/USD"); + tokenOracle = new MockOracle(100000000, "USDC/USD"); + counter = new TestCounter(); + + // setting price oracle for token + bytes memory _data = abi.encodeWithSelector(FeedInterface.getThePrice.selector); + + vm.startPrank(alice.addr); + // could also make a .call using selector and handle success + // append 2 days price threshold + _btpm.setTokenOracle(address(usdc), address(tokenOracle), address(nativeOracle), true, 172800); + vm.stopPrank(); + + uint256 priceToLog = _btpm.getTokenValueOfOneNativeToken((address(usdc))); + // console2.log(priceToLog); + + address accountAddress = address(sa); + + vm.startPrank(charlie.addr); + entryPoint.depositTo{value: 2 ether}(address(_btpm)); + + // mint tokens to addresses + usdc.mint(charlie.addr, 100e6); + usdc.mint(accountAddress, 100e6); + vm.stopPrank(); + } + + function testDeploy() external { + BiconomyTokenPaymaster testArtifact = new BiconomyTokenPaymaster(alice.addr, entryPoint, bob.addr); + assertEq(address(testArtifact.owner()), address(alice.addr)); + assertEq(address(testArtifact.entryPoint()), address(entryPoint)); + assertEq(address(testArtifact.verifyingSigner()), address(bob.addr)); + assertEq(address(testArtifact.feeReceiver()), address(testArtifact)); + } + + function testCheckStates() public { + assertEq(_btpm.owner(), alice.addr); + assertEq(_btpm.verifyingSigner(), bob.addr); + assertEq(_btpm.feeReceiver(), address(_btpm)); + } + + function testOwnershipTransfer() external { + vm.startPrank(alice.addr); + assertEq(_btpm.owner(), alice.addr); + _btpm.transferOwnership(dan.addr); + assertEq(_btpm.owner(), dan.addr); + vm.stopPrank(); + } + + function testWithdrawERC20(uint256 _amount) external { + vm.assume(_amount < usdc.totalSupply()); + usdc.mint(address(_btpm), _amount); + vm.startPrank(alice.addr); + _btpm.withdrawERC20(usdc, dan.addr, _amount); + assertEq(usdc.balanceOf(address(_btpm)), 0); + assertEq(usdc.balanceOf(dan.addr), _amount); + vm.stopPrank(); + } + + function testWithdrawERC20FailNotOwner(uint256 _amount) external { + vm.assume(_amount < usdc.totalSupply()); + usdc.mint(address(_btpm), _amount); + vm.startPrank(dan.addr); + vm.expectRevert("Ownable: caller is not the owner"); + _btpm.withdrawERC20(usdc, dan.addr, _amount); + vm.stopPrank(); + } + + // sanity check for everything works without paymaster + function testCall() external { + vm.deal(address(sa), 1e18); + + bytes memory data = + getSmartAccountExecuteCalldata(address(counter), 0, abi.encodeWithSelector(TestCounter.count.selector)); + + UserOperation memory op = makeEcdsaModuleUserOp(data, sa, 0, alice, bytes("")); + entryPoint.handleOps(arraifyOps(op), dan.addr); + } + + // with token paymaster + function testTokenPaymasterRefund() external { + vm.deal(address(sa), 1e18); + usdc.mint(address(sa), 100e6); // 100 usdc; + usdc.mint(address(_btpm), 100e6); // 100 usdc; + console2.log("paymaster balance before ", usdc.balanceOf(address(_btpm))); + + bytes memory data = getSmartAccountExecuteCalldata( + address(usdc), 0, abi.encodeWithSelector(ERC20.approve.selector, address(_btpm), 10e6) + ); + + UserOperation memory op = makeEcdsaModuleUserOp(data, sa, 0, alice, bytes("")); + + bytes memory pmSig = signPaymasterSignature(op, keyVerifyingSigner); + + IBiconomyTokenPaymaster.ExchangeRateSource priceSource = IBiconomyTokenPaymaster.ExchangeRateSource.ORACLE_BASED; + uint48 validUntil = 3735928559; + uint48 validAfter = 4660; + uint128 exchangeRate = 977100; + uint32 priceMarkup = 1100000; + + op.paymasterAndData = abi.encodePacked( + address(_btpm), priceSource, validUntil, validAfter, address(usdc), exchangeRate, priceMarkup, pmSig + ); + + op.signature = signUserOp(op, keyUser); + + entryPoint.handleOps(arraifyOps(op), dan.addr); + + console2.log("paymaster balance after ", usdc.balanceOf(address(_btpm))); + assertNotEq(usdc.balanceOf(address(sa)), 100e6); + } + + function testTokenPaymasterFailInvalidPaymasteDataLength() external { + vm.deal(address(sa), 1e18); + usdc.mint(address(sa), 100e6); // 100 usdc; + usdc.mint(address(_btpm), 100e6); // 100 usdc; + console2.log("paymaster balance before ", usdc.balanceOf(address(_btpm))); + (UserOperation memory op, uint256 prefund) = fillUserOp( + sa, keyUser, address(usdc), 0, abi.encodeWithSelector(ERC20.approve.selector, address(_btpm), 10e6) + ); + + op.paymasterAndData = "0x1234"; + op.signature = signUserOp(op, keyUser); + UserOperation[] memory ops = new UserOperation[](1); + ops[0] = op; + vm.expectRevert("AA93 invalid paymasterAndData"); + entryPoint.handleOps(ops, dan.addr); + } + + function test2TokenPaymasterFailInvalidPaymasteDataLength() external { + vm.deal(address(sa), 1e18); + usdc.mint(address(sa), 100e6); // 100 usdc; + usdc.mint(address(_btpm), 100e6); // 100 usdc; + console2.log("paymaster balance before ", usdc.balanceOf(address(_btpm))); + (UserOperation memory op, uint256 prefund) = fillUserOp( + sa, keyUser, address(usdc), 0, abi.encodeWithSelector(ERC20.approve.selector, address(_btpm), 10e6) + ); + + bytes memory pmSig = "0x1234"; + op.paymasterAndData = abi.encodePacked(address(_btpm), pmSig); + op.signature = signUserOp(op, keyUser); + UserOperation[] memory ops = new UserOperation[](1); + ops[0] = op; + vm.expectRevert( + abi.encodeWithSelector( + IEntryPoint.FailedOp.selector, uint256(0), "AA33 reverted: BTPM: Invalid length for paymasterAndData" + ) + ); + entryPoint.handleOps(ops, dan.addr); + } + + function testTokenPaymasterFailInvalidPMSignature() external { + vm.deal(address(sa), 1e18); + usdc.mint(address(sa), 100e6); // 100 usdc; + usdc.mint(address(_btpm), 100e6); // 100 usdc; + console2.log("paymaster balance before ", usdc.balanceOf(address(_btpm))); + (UserOperation memory op, uint256 prefund) = fillUserOp( + sa, keyUser, address(usdc), 0, abi.encodeWithSelector(ERC20.approve.selector, address(_btpm), 10e6) + ); + bytes memory pmSig = + "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + + IBiconomyTokenPaymaster.ExchangeRateSource priceSource = IBiconomyTokenPaymaster.ExchangeRateSource.ORACLE_BASED; + uint48 validUntil = 3735928559; + uint48 validAfter = 4660; + uint128 exchangeRate = 977100; + uint32 priceMarkup = 1100000; + + op.paymasterAndData = abi.encodePacked( + address(_btpm), priceSource, validUntil, validAfter, address(usdc), exchangeRate, priceMarkup, pmSig + ); + op.signature = signUserOp(op, keyUser); + UserOperation[] memory ops = new UserOperation[](1); + ops[0] = op; + vm.expectRevert(); + entryPoint.handleOps(ops, dan.addr); + } + + function testTokenPaymasterFailWrongPMSignature() external { + vm.deal(address(sa), 1e18); + usdc.mint(address(sa), 100e6); // 100 usdc; + usdc.mint(address(_btpm), 100e6); // 100 usdc; + console2.log("paymaster balance before ", usdc.balanceOf(address(_btpm))); + (UserOperation memory op, uint256 prefund) = fillUserOp( + sa, keyUser, address(usdc), 0, abi.encodeWithSelector(ERC20.approve.selector, address(_btpm), 10e6) + ); + + bytes32 hash = keccak256((abi.encodePacked("some message"))); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(keyVerifyingSigner, hash.toEthSignedMessageHash()); + bytes memory pmSig = abi.encodePacked(r, s, v); + + IBiconomyTokenPaymaster.ExchangeRateSource priceSource = IBiconomyTokenPaymaster.ExchangeRateSource.ORACLE_BASED; + uint48 validUntil = 3735928559; + uint48 validAfter = 4660; + uint128 exchangeRate = 977100; + uint32 priceMarkup = 1100000; + + op.paymasterAndData = abi.encodePacked( + address(_btpm), priceSource, validUntil, validAfter, address(usdc), exchangeRate, priceMarkup, pmSig + ); + op.signature = signUserOp(op, keyUser); + UserOperation[] memory ops = new UserOperation[](1); + ops[0] = op; + vm.expectRevert(); + // TODO // Review why below doesn't capture while it does in hardhat test and in above tests + // vm.expectRevert("AA34 signature error"); + entryPoint.handleOps(ops, dan.addr); + } + + function testTokenPaymasterFailHighPriceMarkup() external { + vm.deal(address(sa), 1e18); + usdc.mint(address(sa), 100e6); // 100 usdc; + usdc.mint(address(_btpm), 100e6); // 100 usdc; + console2.log("paymaster balance before ", usdc.balanceOf(address(_btpm))); + (UserOperation memory op, uint256 prefund) = fillUserOp( + sa, keyUser, address(usdc), 0, abi.encodeWithSelector(ERC20.approve.selector, address(_btpm), 10e6) + ); + + IBiconomyTokenPaymaster.ExchangeRateSource priceSource = IBiconomyTokenPaymaster.ExchangeRateSource.ORACLE_BASED; + uint48 validUntil = 3735928559; + uint48 validAfter = 4660; + uint128 exchangeRate = 977100; + uint32 priceMarkup = 2200000; + + bytes32 hash = _btpm.getHash(op, priceSource, validUntil, validAfter, address(usdc), exchangeRate, priceMarkup); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(keyVerifyingSigner, hash.toEthSignedMessageHash()); + bytes memory pmSig = abi.encodePacked(r, s, v); + + op.paymasterAndData = abi.encodePacked( + address(_btpm), priceSource, validUntil, validAfter, address(usdc), exchangeRate, priceMarkup, pmSig + ); + op.signature = signUserOp(op, keyUser); + UserOperation[] memory ops = new UserOperation[](1); + ops[0] = op; + vm.expectRevert( + abi.encodeWithSelector( + IEntryPoint.FailedOp.selector, uint256(0), "AA33 reverted: BTPM: price markup percentage too high" + ) + ); + + entryPoint.handleOps(ops, dan.addr); + } + + // TODO : move to separate PaymasterTestBase and rename to signTokenPaymasterSignature + function signPaymasterSignature(UserOperation memory op, uint256 _key) public returns (bytes memory signature) { + IBiconomyTokenPaymaster.ExchangeRateSource priceSource = IBiconomyTokenPaymaster.ExchangeRateSource.ORACLE_BASED; + uint48 validUntil = 3735928559; + uint48 validAfter = 4660; + uint128 exchangeRate = 977100; + uint32 priceMarkup = 1100000; + + bytes32 hash = _btpm.getHash(op, priceSource, validUntil, validAfter, address(usdc), exchangeRate, priceMarkup); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(_key, hash.toEthSignedMessageHash()); + signature = abi.encodePacked(r, s, v); + } +} diff --git a/test/foundry/token-paymaster/TokenPaymasterMumbai.t.sol b/test/foundry/token-paymaster/TokenPaymasterMumbai.t.sol new file mode 100644 index 0000000..154eabd --- /dev/null +++ b/test/foundry/token-paymaster/TokenPaymasterMumbai.t.sol @@ -0,0 +1,318 @@ +// SPDX-License-Identifier: Unlicense +pragma solidity >=0.8.0; + +import {stdStorage, StdStorage, Test} from "forge-std/Test.sol"; +import {Utilities} from "../../utils/Utilities.sol"; +import {console2} from "forge-std/console2.sol"; +import {Vm} from "forge-std/Vm.sol"; + +import {BiconomyTokenPaymaster} from "../../../contracts/token/BiconomyTokenPaymaster.sol"; +import {IBiconomyTokenPaymaster} from "../../../contracts/interfaces/paymasters/IBiconomyTokenPaymaster.sol"; +import "../../BytesLib.sol"; +import "../../../contracts/test/helpers/TestCounter.sol"; + +import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; +import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import {IEntryPoint} from "@account-abstraction/contracts/interfaces/IEntryPoint.sol"; +import {UserOperation} from "@account-abstraction/contracts/interfaces/UserOperation.sol"; +import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; +import {SmartAccount} from "@biconomy-devx/account-contracts-v2/contracts/smart-account/SmartAccount.sol"; +import {EcdsaOwnershipRegistryModule} from + "@biconomy-devx/account-contracts-v2/contracts/smart-account/modules/EcdsaOwnershipRegistryModule.sol"; +import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol"; + +import {MockToken} from "../../../contracts/test/helpers/MockToken.sol"; +import {MockPriceFeed} from "../../../contracts/test/helpers/MockPriceFeed.sol"; +import {MockOracle} from "../../../contracts/test/helpers/MockOracle.sol"; +import {FeedInterface} from "../../../contracts/token/oracles/FeedInterface.sol"; +import {SATestBase} from "../base/SATestBase.sol"; + +error SetupIncomplete(); + +using ECDSA for bytes32; + +contract TokenPaymasterMumbaiTest is SATestBase { + SmartAccount public sa; + + uint256 internal keyUser; + uint256 internal keyVerifyingSigner; + + BiconomyTokenPaymaster public _btpm; + AggregatorV3Interface public nativeOracle = AggregatorV3Interface(0xd0D5e3DB44DE05E9F294BB0a3bEEaF030DE24Ada); + AggregatorV3Interface public tokenOracle = AggregatorV3Interface(0x572dDec9087154dC5dfBB1546Bb62713147e0Ab0); + IERC20 public usdc = IERC20(0xdA5289fCAAF71d52a80A254da614a192b693e977); + TestCounter counter; + + function setUp() public virtual override { + uint256 forkId = vm.createFork("https://polygon-mumbai.g.alchemy.com/v2/zX14dLXhTQqeK4LG2pNUsk7Gcet8iPXJ"); + vm.selectFork(forkId); + super.setUp(); + + console2.log("current block timestamp ", block.timestamp); + + // Deploy Smart Account with default module + uint256 smartAccountDeploymentIndex = 0; + bytes memory moduleSetupData = getEcdsaOwnershipRegistryModuleSetupData(alice.addr); + sa = getSmartAccountWithModule( + address(ecdsaOwnershipRegistryModule), moduleSetupData, smartAccountDeploymentIndex, "aliceSA" + ); + + keyUser = alice.privateKey; + keyVerifyingSigner = bob.privateKey; + + _btpm = new BiconomyTokenPaymaster(alice.addr, entryPoint, bob.addr); + counter = new TestCounter(); + + // setting price oracle for token + + vm.startPrank(alice.addr); + // could also make a .call using selector and handle success + _btpm.setTokenOracle( + address(usdc), address(tokenOracle), address(nativeOracle), true, 172800 + ); + vm.stopPrank(); + + uint256 priceToLog = _btpm.getTokenValueOfOneNativeToken((address(usdc))); + console2.log(priceToLog); + + vm.startPrank(charlie.addr); + entryPoint.depositTo{value: 2 ether}(address(_btpm)); + vm.stopPrank(); + } + + function testDeploy() external { + BiconomyTokenPaymaster testArtifact = new BiconomyTokenPaymaster(alice.addr, entryPoint, bob.addr); + assertEq(address(testArtifact.owner()), address(alice.addr)); + assertEq(address(testArtifact.entryPoint()), address(entryPoint)); + assertEq(address(testArtifact.verifyingSigner()), address(bob.addr)); + assertEq(address(testArtifact.feeReceiver()), address(testArtifact)); + } + + function testCheckStates() public { + assertEq(_btpm.owner(), alice.addr); + assertEq(_btpm.verifyingSigner(), bob.addr); + assertEq(_btpm.feeReceiver(), address(_btpm)); + } + + function testOwnershipTransfer() external { + vm.startPrank(alice.addr); + assertEq(_btpm.owner(), alice.addr); + _btpm.transferOwnership(dan.addr); + assertEq(_btpm.owner(), dan.addr); + vm.stopPrank(); + } + + function testWithdrawERC20(uint256 _amount) external { + vm.assume(_amount < usdc.totalSupply()); + deal(address(usdc), address(_btpm), _amount); + vm.startPrank(alice.addr); + _btpm.withdrawERC20(usdc, dan.addr, _amount); + assertEq(usdc.balanceOf(address(_btpm)), 0); + assertEq(usdc.balanceOf(dan.addr), _amount); + vm.stopPrank(); + } + + function testWithdrawERC20FailNotOwner(uint256 _amount) external { + vm.assume(_amount < usdc.totalSupply()); + deal(address(usdc), address(_btpm), _amount); + vm.startPrank(dan.addr); + vm.expectRevert("Ownable: caller is not the owner"); + _btpm.withdrawERC20(usdc, dan.addr, _amount); + vm.stopPrank(); + } + + // sanity check for everything works without paymaster + function testCall() external { + vm.deal(address(sa), 1e18); + vm.deal(dan.addr, 1e18); + + bytes memory data = + getSmartAccountExecuteCalldata(address(counter), 0, abi.encodeWithSelector(TestCounter.count.selector)); + + UserOperation memory op = makeEcdsaModuleUserOp(data, sa, 0, alice, bytes("")); + entryPoint.handleOps(arraifyOps(op), dan.addr); + } + + // with token paymaster + function testTokenPaymasterRefund() external { + vm.deal(address(sa), 1e18); + deal(address(usdc), address(sa), 100e6); + deal(address(usdc), address(_btpm), 100e6); + console2.log("paymaster balance before ", usdc.balanceOf(address(_btpm))); + + bytes memory data = getSmartAccountExecuteCalldata( + address(usdc), 0, abi.encodeWithSelector(ERC20.approve.selector, address(_btpm), 10e6) + ); + + UserOperation memory op = makeEcdsaModuleUserOp(data, sa, 0, alice, bytes("")); + + bytes memory pmSig = signPaymasterSignature(op, keyVerifyingSigner); + + IBiconomyTokenPaymaster.ExchangeRateSource priceSource = + IBiconomyTokenPaymaster.ExchangeRateSource.EXTERNAL_EXCHANGE_RATE; + uint48 validUntil = 3735928559; + uint48 validAfter = 4660; + uint128 exchangeRate = 977100; + uint32 priceMarkup = 1100000; + + op.paymasterAndData = abi.encodePacked( + address(_btpm), priceSource, validUntil, validAfter, address(usdc), exchangeRate, priceMarkup, pmSig + ); + + op.signature = signUserOp(op, keyUser); + + entryPoint.handleOps(arraifyOps(op), dan.addr); + + console2.log("paymaster balance after ", usdc.balanceOf(address(_btpm))); + assertNotEq(usdc.balanceOf(address(sa)), 100e6); + } + + function testTokenPaymasterFailInvalidPaymasteDataLength() external { + vm.deal(address(sa), 1e18); + deal(address(usdc), address(sa), 100e6); + deal(address(usdc), address(_btpm), 100e6); + console2.log("paymaster balance before ", usdc.balanceOf(address(_btpm))); + console2.log("SA token balance before ", usdc.balanceOf(address(sa))); + (UserOperation memory op, uint256 prefund) = fillUserOp( + sa, keyUser, address(usdc), 0, abi.encodeWithSelector(ERC20.approve.selector, address(_btpm), 10e6) + ); + + op.paymasterAndData = "0x1234"; + op.signature = signUserOp(op, keyUser); + UserOperation[] memory ops = new UserOperation[](1); + ops[0] = op; + vm.expectRevert("AA93 invalid paymasterAndData"); + entryPoint.handleOps(ops, dan.addr); + } + + function test2TokenPaymasterFailInvalidPaymasteDataLength() external { + vm.deal(address(sa), 1e18); + deal(address(usdc), address(sa), 100e6); + deal(address(usdc), address(_btpm), 100e6); + console2.log("paymaster balance before ", usdc.balanceOf(address(_btpm))); + (UserOperation memory op, uint256 prefund) = fillUserOp( + sa, keyUser, address(usdc), 0, abi.encodeWithSelector(ERC20.approve.selector, address(_btpm), 10e6) + ); + + bytes memory pmSig = "0x1234"; + op.paymasterAndData = abi.encodePacked(address(_btpm), pmSig); + op.signature = signUserOp(op, keyUser); + UserOperation[] memory ops = new UserOperation[](1); + ops[0] = op; + vm.expectRevert( + abi.encodeWithSelector( + IEntryPoint.FailedOp.selector, uint256(0), "AA33 reverted: BTPM: Invalid length for paymasterAndData" + ) + ); + entryPoint.handleOps(ops, dan.addr); + } + + function testTokenPaymasterFailInvalidPMSignature() external { + vm.deal(address(sa), 1e18); + deal(address(usdc), address(sa), 100e6); + deal(address(usdc), address(_btpm), 100e6); + console2.log("paymaster balance before ", usdc.balanceOf(address(_btpm))); + (UserOperation memory op, uint256 prefund) = fillUserOp( + sa, keyUser, address(usdc), 0, abi.encodeWithSelector(ERC20.approve.selector, address(_btpm), 10e6) + ); + bytes memory pmSig = + "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + + IBiconomyTokenPaymaster.ExchangeRateSource priceSource = + IBiconomyTokenPaymaster.ExchangeRateSource.EXTERNAL_EXCHANGE_RATE; + uint48 validUntil = 3735928559; + uint48 validAfter = 4660; + uint128 exchangeRate = 977100; + uint32 priceMarkup = 1100000; + + op.paymasterAndData = abi.encodePacked( + address(_btpm), priceSource, validUntil, validAfter, address(usdc), exchangeRate, priceMarkup, pmSig + ); + op.signature = signUserOp(op, keyUser); + UserOperation[] memory ops = new UserOperation[](1); + ops[0] = op; + vm.expectRevert(); + entryPoint.handleOps(ops, dan.addr); + } + + function testTokenPaymasterFailWrongPMSignature() external { + vm.deal(address(sa), 1e18); + deal(address(usdc), address(sa), 100e6); + deal(address(usdc), address(_btpm), 100e6); + console2.log("paymaster balance before ", usdc.balanceOf(address(_btpm))); + (UserOperation memory op, uint256 prefund) = fillUserOp( + sa, keyUser, address(usdc), 0, abi.encodeWithSelector(ERC20.approve.selector, address(_btpm), 10e6) + ); + + bytes32 hash = keccak256((abi.encodePacked("some message"))); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(keyVerifyingSigner, hash.toEthSignedMessageHash()); + bytes memory pmSig = abi.encodePacked(r, s, v); + + IBiconomyTokenPaymaster.ExchangeRateSource priceSource = + IBiconomyTokenPaymaster.ExchangeRateSource.EXTERNAL_EXCHANGE_RATE; + uint48 validUntil = 3735928559; + uint48 validAfter = 4660; + uint128 exchangeRate = 977100; + uint32 priceMarkup = 1100000; + + op.paymasterAndData = abi.encodePacked( + address(_btpm), priceSource, validUntil, validAfter, address(usdc), exchangeRate, priceMarkup, pmSig + ); + op.signature = signUserOp(op, keyUser); + UserOperation[] memory ops = new UserOperation[](1); + ops[0] = op; + vm.expectRevert(); + // TODO // Review why below doesn't capture while it does in hardhat test and in above tests + // vm.expectRevert("AA34 signature error"); + entryPoint.handleOps(ops, dan.addr); + } + + function testTokenPaymasterFailHighPriceMarkup() external { + vm.deal(address(sa), 1e18); + deal(address(usdc), address(sa), 100e6); + deal(address(usdc), address(_btpm), 100e6); + console2.log("paymaster balance before ", usdc.balanceOf(address(_btpm))); + (UserOperation memory op, uint256 prefund) = fillUserOp( + sa, keyUser, address(usdc), 0, abi.encodeWithSelector(ERC20.approve.selector, address(_btpm), 10e6) + ); + + IBiconomyTokenPaymaster.ExchangeRateSource priceSource = + IBiconomyTokenPaymaster.ExchangeRateSource.EXTERNAL_EXCHANGE_RATE; + uint48 validUntil = 3735928559; + uint48 validAfter = 4660; + uint128 exchangeRate = 977100; + uint32 priceMarkup = 2200000; + + bytes32 hash = _btpm.getHash(op, priceSource, validUntil, validAfter, address(usdc), exchangeRate, priceMarkup); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(keyVerifyingSigner, hash.toEthSignedMessageHash()); + bytes memory pmSig = abi.encodePacked(r, s, v); + + op.paymasterAndData = abi.encodePacked( + address(_btpm), priceSource, validUntil, validAfter, address(usdc), exchangeRate, priceMarkup, pmSig + ); + op.signature = signUserOp(op, keyUser); + UserOperation[] memory ops = new UserOperation[](1); + ops[0] = op; + vm.expectRevert( + abi.encodeWithSelector( + IEntryPoint.FailedOp.selector, uint256(0), "AA33 reverted: BTPM: price markup percentage too high" + ) + ); + + entryPoint.handleOps(ops, dan.addr); + } + + // TODO : move to separate PaymasterTestBase and rename to signTokenPaymasterSignature + function signPaymasterSignature(UserOperation memory op, uint256 _key) public returns (bytes memory signature) { + IBiconomyTokenPaymaster.ExchangeRateSource priceSource = + IBiconomyTokenPaymaster.ExchangeRateSource.EXTERNAL_EXCHANGE_RATE; + uint48 validUntil = 3735928559; + uint48 validAfter = 4660; + uint128 exchangeRate = 977100; + uint32 priceMarkup = 1100000; + + bytes32 hash = _btpm.getHash(op, priceSource, validUntil, validAfter, address(usdc), exchangeRate, priceMarkup); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(_key, hash.toEthSignedMessageHash()); + signature = abi.encodePacked(r, s, v); + } +} diff --git a/test/sponsorship-paymaster/biconomy-sponsorship-paymaster-specs.ts b/test/sponsorship-paymaster/biconomy-sponsorship-paymaster-specs.ts new file mode 100644 index 0000000..bc8cb4f --- /dev/null +++ b/test/sponsorship-paymaster/biconomy-sponsorship-paymaster-specs.ts @@ -0,0 +1,739 @@ +/* eslint-disable node/no-missing-import */ +/* eslint-disable camelcase */ +import { expect } from "chai"; +import { ethers } from "hardhat"; + +import { + BiconomyAccountImplementation, + BiconomyAccountImplementation__factory, + BiconomyAccountFactory, + BiconomyAccountFactory__factory, + SponsorshipPaymaster, + SponsorshipPaymaster__factory, +} from "../../typechain-types"; +import { fillAndSign } from "../utils/userOp"; +import { + EntryPoint, + EntryPoint__factory, +} from "../../lib/account-abstraction/typechain"; +import { + EcdsaOwnershipRegistryModule, + EcdsaOwnershipRegistryModule__factory, +} from "@biconomy-devx/account-contracts-v2/dist/types"; +import { arrayify, hexConcat, parseEther } from "ethers/lib/utils"; +import { BigNumber, Signer } from "ethers"; + +export const AddressZero = ethers.constants.AddressZero; + +const MOCK_VALID_UNTIL = "0x00000000deadbeef"; +const MOCK_VALID_AFTER = "0x0000000000001234"; +const dynamicMarkup = 1100000; // or 0 or 1100000 + +export async function deployEntryPoint( + provider = ethers.provider +): Promise { + return new EntryPoint__factory(provider.getSigner()).deploy(); +} + +describe("EntryPoint with VerifyingPaymaster Singleton", function () { + let entryPoint: EntryPoint; + let depositorSigner: Signer; + let walletOwner: Signer; + let walletAddress: string, paymasterAddress: string; + let ethersSigner; + + let offchainSigner: Signer, deployer: Signer, feeCollector: Signer; + let secondFundingId: Signer, thirdFundingId: Signer; + + let sponsorshipPaymaster: SponsorshipPaymaster; + let smartWalletImp: BiconomyAccountImplementation; + let ecdsaModule: EcdsaOwnershipRegistryModule; + let walletFactory: BiconomyAccountFactory; + const abi = ethers.utils.defaultAbiCoder; + + before(async function () { + ethersSigner = await ethers.getSigners(); + entryPoint = await deployEntryPoint(); + + deployer = ethersSigner[0]; + offchainSigner = ethersSigner[1]; + depositorSigner = ethersSigner[2]; + feeCollector = ethersSigner[3]; + secondFundingId = ethersSigner[4]; + thirdFundingId = ethersSigner[5]; + walletOwner = deployer; // ethersSigner[0]; + + const offchainSignerAddress = await offchainSigner.getAddress(); + const walletOwnerAddress = await walletOwner.getAddress(); + const feeCollectorAddress = await feeCollector.getAddress(); + + ecdsaModule = await new EcdsaOwnershipRegistryModule__factory( + deployer + ).deploy(); + + sponsorshipPaymaster = await new SponsorshipPaymaster__factory( + deployer + ).deploy( + await deployer.getAddress(), + entryPoint.address, + offchainSignerAddress, + feeCollectorAddress + ); + + smartWalletImp = await new BiconomyAccountImplementation__factory( + deployer + ).deploy(entryPoint.address); + + walletFactory = await new BiconomyAccountFactory__factory(deployer).deploy( + smartWalletImp.address, + walletOwnerAddress + ); + + await walletFactory + .connect(deployer) + .addStake(entryPoint.address, 86400, { value: parseEther("2") }); + + const ecdsaOwnershipSetupData = ecdsaModule.interface.encodeFunctionData( + "initForSmartAccount", + [walletOwnerAddress] + ); + + const smartAccountDeploymentIndex = 0; + + await walletFactory.deployCounterFactualAccount( + ecdsaModule.address, + ecdsaOwnershipSetupData, + smartAccountDeploymentIndex + ); + const expected = await walletFactory.getAddressForCounterFactualAccount( + ecdsaModule.address, + ecdsaOwnershipSetupData, + smartAccountDeploymentIndex + ); + + walletAddress = expected; + console.log(" wallet address ", walletAddress); + + paymasterAddress = sponsorshipPaymaster.address; + console.log("Paymaster address is ", paymasterAddress); + + await entryPoint.depositTo(paymasterAddress, { value: parseEther("1") }); + }); + + async function getUserOpWithPaymasterInfo(paymasterId: string) { + const userOp1 = await fillAndSign( + { + sender: walletAddress, + }, + walletOwner, + entryPoint, + "nonce" + ); + + const hash = await sponsorshipPaymaster.getHash( + userOp1, + paymasterId, + MOCK_VALID_UNTIL, + MOCK_VALID_AFTER, + dynamicMarkup + ); + const sig = await offchainSigner.signMessage(arrayify(hash)); + const numVU = ethers.BigNumber.from(MOCK_VALID_UNTIL); + const numVA = ethers.BigNumber.from(MOCK_VALID_AFTER); + const paymasterAndData = hexConcat([ + paymasterAddress, + ethers.utils.hexZeroPad(paymasterId, 20), + ethers.utils.hexZeroPad(ethers.utils.hexlify(numVU.toNumber()), 6), // 6 byte + ethers.utils.hexZeroPad(ethers.utils.hexlify(numVA.toNumber()), 6), // 6 byte + ethers.utils.hexZeroPad(ethers.utils.hexlify(dynamicMarkup), 4), // 4 bytes + sig, + ]); + return await fillAndSign( + { + ...userOp1, + paymasterAndData, + }, + walletOwner, + entryPoint, + "nonce" + ); + } + + describe("Verifying paymaster basic positive tests", () => { + it("Should Fail when there is no deposit for paymaster id", async () => { + // Review + const paymasterId = await depositorSigner.getAddress(); + console.log("paymaster Id ", paymasterId); + const userOp = await getUserOpWithPaymasterInfo(paymasterId); + + // Review: for catching custom errors in better ways + await expect( + entryPoint.callStatic.simulateValidation(userOp) + ).to.be.revertedWithCustomError(entryPoint, "FailedOp"); + }); + + it("succeed with valid signature", async () => { + const fundingId = await offchainSigner.getAddress(); + + // TODO: find accurate value of unaccountedEPGasOverhead based on userOpGasPrice calculation flip (maxFeePerGas vs block.gasprice + priorityFee) + + // already bit high here because of first txn + await sponsorshipPaymaster + .connect(deployer) + .setUnaccountedEPGasOverhead(55500); + + await sponsorshipPaymaster.depositFor(fundingId, { + value: ethers.utils.parseEther("1"), + }); + + const paymasterFundsBefore = await entryPoint.balanceOf(paymasterAddress); + const paymasterIdBalanceBefore = await sponsorshipPaymaster.getBalance( + fundingId + ); + const feeCollectorBalanceBefore = await sponsorshipPaymaster.getBalance( + await feeCollector.getAddress() + ); + console.log("feeCollectorBalanceBefore ", feeCollectorBalanceBefore); + expect(feeCollectorBalanceBefore).to.be.equal(BigNumber.from(0)); + const signer = await sponsorshipPaymaster.verifyingSigner(); + const offchainSignerAddress = await offchainSigner.getAddress(); + expect(signer).to.be.equal(offchainSignerAddress); + + const userOp1 = await fillAndSign( + { + sender: walletAddress, + verificationGasLimit: 200000, + }, + walletOwner, + entryPoint, + "nonce" + ); + + const hash = await sponsorshipPaymaster.getHash( + userOp1, + fundingId, + MOCK_VALID_UNTIL, + MOCK_VALID_AFTER, + dynamicMarkup + ); + const sig = await offchainSigner.signMessage(arrayify(hash)); + const numVU = ethers.BigNumber.from(MOCK_VALID_UNTIL); + const numVA = ethers.BigNumber.from(MOCK_VALID_AFTER); + const userOp = await fillAndSign( + { + ...userOp1, + paymasterAndData: hexConcat([ + paymasterAddress, + ethers.utils.hexZeroPad(fundingId, 20), + ethers.utils.hexZeroPad(ethers.utils.hexlify(numVU.toNumber()), 6), // 6 byte + ethers.utils.hexZeroPad(ethers.utils.hexlify(numVA.toNumber()), 6), // 6 byte + ethers.utils.hexZeroPad(ethers.utils.hexlify(dynamicMarkup), 4), // 4 bytes + sig, + ]), + }, + walletOwner, + entryPoint, + "nonce" + ); + + const signatureWithModuleAddress = ethers.utils.defaultAbiCoder.encode( + ["bytes", "address"], + [userOp.signature, ecdsaModule.address] + ); + userOp.signature = signatureWithModuleAddress; + + const tx = await entryPoint.handleOps( + [userOp], + await offchainSigner.getAddress(), + { + type: 2, + maxFeePerGas: userOp.maxFeePerGas, + maxPriorityFeePerGas: userOp.maxPriorityFeePerGas, + } + ); + const receipt = await tx.wait(); + console.log("effective gas price ", receipt.effectiveGasPrice.toString()); + console.log("gas used VPM V2 ", receipt.gasUsed.toString()); + console.log("gas price ", receipt.effectiveGasPrice.toString()); + + const chargedFromDappIncludingPremium = BigNumber.from( + receipt.logs[1].topics[2] + ); + console.log( + "chargedFromDappIncludingPremium ", + chargedFromDappIncludingPremium.toString() + ); + + const premiumCollected = BigNumber.from( + receipt.logs[2].topics[2] + ).toString(); + console.log("premiumCollected ", premiumCollected); + + const bundlerPaid = receipt.effectiveGasPrice.mul(receipt.gasUsed); + console.log("bundler paid ", bundlerPaid.toString()); + + const paymasterFundsAfter = await entryPoint.balanceOf(paymasterAddress); + const paymasterIdBalanceAfter = await sponsorshipPaymaster.getBalance( + fundingId + ); + + const paymasterIdBalanceDiff = paymasterIdBalanceBefore.sub( + paymasterIdBalanceAfter + ); + console.log("paymasterIdBalanceDiff ", paymasterIdBalanceDiff.toString()); + + const paymasterFundsDiff = paymasterFundsBefore.sub(paymasterFundsAfter); + console.log("paymasterFundsDiff ", paymasterFundsDiff.toString()); + + // paymasterIdBalanceDiffWithoutPremium should be greater than paymaster funds diff (that means unaccounted overhead is right) + expect( + chargedFromDappIncludingPremium + .sub(premiumCollected) + .sub(paymasterFundsDiff) + ).to.be.greaterThan(BigNumber.from(0)); + + await expect( + entryPoint.handleOps([userOp], await offchainSigner.getAddress()) + ).to.be.reverted; + + const feeCollectorBalanceAfter = await sponsorshipPaymaster.getBalance( + await feeCollector.getAddress() + ); + expect(feeCollectorBalanceAfter).to.be.greaterThan(BigNumber.from(0)); + + // 0.1 / 1.1 = actual gas used * 0.1 + expect(feeCollectorBalanceAfter).to.be.equal( + paymasterIdBalanceDiff.mul(BigNumber.from(1)).div(BigNumber.from(11)) + ); + }); + + it("succeed with valid signature - second transaction ", async () => { + const fundingId = await offchainSigner.getAddress(); + + // TODO: find accurate value of unaccountedEPGasOverhead based on userOpGasPrice calculation flip (maxFeePerGas vs block.gasprice + priorityFee) + await sponsorshipPaymaster + .connect(deployer) + .setUnaccountedEPGasOverhead(38500); + + await sponsorshipPaymaster.depositFor(fundingId, { + value: ethers.utils.parseEther("1"), + }); + + const paymasterFundsBefore = await entryPoint.balanceOf(paymasterAddress); + const paymasterIdBalanceBefore = await sponsorshipPaymaster.getBalance( + fundingId + ); + const feeCollectorBalanceBefore = await sponsorshipPaymaster.getBalance( + await feeCollector.getAddress() + ); + console.log("feeCollectorBalanceBefore ", feeCollectorBalanceBefore); + const signer = await sponsorshipPaymaster.verifyingSigner(); + const offchainSignerAddress = await offchainSigner.getAddress(); + expect(signer).to.be.equal(offchainSignerAddress); + + const userOp1 = await fillAndSign( + { + sender: walletAddress, + verificationGasLimit: 200000, + }, + walletOwner, + entryPoint, + "nonce" + ); + + const hash = await sponsorshipPaymaster.getHash( + userOp1, + fundingId, + MOCK_VALID_UNTIL, + MOCK_VALID_AFTER, + dynamicMarkup + ); + const sig = await offchainSigner.signMessage(arrayify(hash)); + const numVU = ethers.BigNumber.from(MOCK_VALID_UNTIL); + const numVA = ethers.BigNumber.from(MOCK_VALID_AFTER); + const userOp = await fillAndSign( + { + ...userOp1, + paymasterAndData: hexConcat([ + paymasterAddress, + ethers.utils.hexZeroPad(fundingId, 20), + ethers.utils.hexZeroPad(ethers.utils.hexlify(numVU.toNumber()), 6), // 6 byte + ethers.utils.hexZeroPad(ethers.utils.hexlify(numVA.toNumber()), 6), // 6 byte + ethers.utils.hexZeroPad(ethers.utils.hexlify(dynamicMarkup), 4), // 4 bytes + sig, + ]), + }, + walletOwner, + entryPoint, + "nonce" + ); + + const signatureWithModuleAddress = ethers.utils.defaultAbiCoder.encode( + ["bytes", "address"], + [userOp.signature, ecdsaModule.address] + ); + userOp.signature = signatureWithModuleAddress; + + const tx = await entryPoint.handleOps( + [userOp], + await offchainSigner.getAddress(), + { + type: 2, + maxFeePerGas: userOp.maxFeePerGas, + maxPriorityFeePerGas: userOp.maxPriorityFeePerGas, + } + ); + const receipt = await tx.wait(); + console.log("effective gas price ", receipt.effectiveGasPrice.toString()); + console.log("gas used VPM V2 ", receipt.gasUsed.toString()); + console.log("gas price ", receipt.effectiveGasPrice.toString()); + + const chargedFromDappIncludingPremium = BigNumber.from( + receipt.logs[1].topics[2] + ); + console.log( + "chargedFromDappIncludingPremium ", + chargedFromDappIncludingPremium.toString() + ); + + const premiumCollected = BigNumber.from( + receipt.logs[2].topics[2] + ).toString(); + console.log("premiumCollected ", premiumCollected); + + const bundlerPaid = receipt.effectiveGasPrice.mul(receipt.gasUsed); + console.log("bundler paid ", bundlerPaid.toString()); + + const paymasterFundsAfter = await entryPoint.balanceOf(paymasterAddress); + const paymasterIdBalanceAfter = await sponsorshipPaymaster.getBalance( + fundingId + ); + + const paymasterIdBalanceDiff = paymasterIdBalanceBefore.sub( + paymasterIdBalanceAfter + ); + console.log("paymasterIdBalanceDiff ", paymasterIdBalanceDiff.toString()); + + const paymasterFundsDiff = paymasterFundsBefore.sub(paymasterFundsAfter); + console.log("paymasterFundsDiff ", paymasterFundsDiff.toString()); + + // paymasterIdBalanceDiffWithoutPremium should be greater than paymaster funds diff (that means unaccounted overhead is right) + expect( + chargedFromDappIncludingPremium + .sub(premiumCollected) + .sub(paymasterFundsDiff) + ).to.be.greaterThan(BigNumber.from(0)); + + await expect( + entryPoint.handleOps([userOp], await offchainSigner.getAddress()) + ).to.be.reverted; + + const feeCollectorBalanceAfter = await sponsorshipPaymaster.getBalance( + await feeCollector.getAddress() + ); + expect(feeCollectorBalanceAfter).to.be.greaterThan(BigNumber.from(0)); + + // 0.1 / 1.1 = actual gas used * 0.1 + expect( + feeCollectorBalanceAfter.sub(feeCollectorBalanceBefore) + ).to.be.equal( + paymasterIdBalanceDiff.mul(BigNumber.from(1)).div(BigNumber.from(11)) + ); + }); + + it("succeed with valid signature - same account - different funding id ", async () => { + const fundingId = await secondFundingId.getAddress(); + + // TODO: find accurate value of unaccountedEPGasOverhead based on userOpGasPrice calculation flip (maxFeePerGas vs block.gasprice + priorityFee) + await sponsorshipPaymaster + .connect(deployer) + .setUnaccountedEPGasOverhead(38500); + + await sponsorshipPaymaster.depositFor(fundingId, { + value: ethers.utils.parseEther("1"), + }); + + const paymasterFundsBefore = await entryPoint.balanceOf(paymasterAddress); + const paymasterIdBalanceBefore = await sponsorshipPaymaster.getBalance( + fundingId + ); + const feeCollectorBalanceBefore = await sponsorshipPaymaster.getBalance( + await feeCollector.getAddress() + ); + console.log("feeCollectorBalanceBefore ", feeCollectorBalanceBefore); + const signer = await sponsorshipPaymaster.verifyingSigner(); + const offchainSignerAddress = await offchainSigner.getAddress(); + expect(signer).to.be.equal(offchainSignerAddress); + + const userOp1 = await fillAndSign( + { + sender: walletAddress, + verificationGasLimit: 200000, + }, + walletOwner, + entryPoint, + "nonce" + ); + + const hash = await sponsorshipPaymaster.getHash( + userOp1, + fundingId, + MOCK_VALID_UNTIL, + MOCK_VALID_AFTER, + dynamicMarkup + ); + const sig = await offchainSigner.signMessage(arrayify(hash)); + const numVU = ethers.BigNumber.from(MOCK_VALID_UNTIL); + const numVA = ethers.BigNumber.from(MOCK_VALID_AFTER); + const userOp = await fillAndSign( + { + ...userOp1, + paymasterAndData: hexConcat([ + paymasterAddress, + ethers.utils.hexZeroPad(fundingId, 20), + ethers.utils.hexZeroPad(ethers.utils.hexlify(numVU.toNumber()), 6), // 6 byte + ethers.utils.hexZeroPad(ethers.utils.hexlify(numVA.toNumber()), 6), // 6 byte + ethers.utils.hexZeroPad(ethers.utils.hexlify(dynamicMarkup), 4), // 4 bytes + sig, + ]), + }, + walletOwner, + entryPoint, + "nonce" + ); + + const signatureWithModuleAddress = ethers.utils.defaultAbiCoder.encode( + ["bytes", "address"], + [userOp.signature, ecdsaModule.address] + ); + userOp.signature = signatureWithModuleAddress; + + const tx = await entryPoint.handleOps( + [userOp], + await offchainSigner.getAddress(), + { + type: 2, + maxFeePerGas: userOp.maxFeePerGas, + maxPriorityFeePerGas: userOp.maxPriorityFeePerGas, + } + ); + const receipt = await tx.wait(); + console.log("effective gas price ", receipt.effectiveGasPrice.toString()); + console.log("gas used VPM V2 ", receipt.gasUsed.toString()); + console.log("gas price ", receipt.effectiveGasPrice.toString()); + + const chargedFromDappIncludingPremium = BigNumber.from( + receipt.logs[1].topics[2] + ); + console.log( + "chargedFromDappIncludingPremium ", + chargedFromDappIncludingPremium.toString() + ); + + const premiumCollected = BigNumber.from( + receipt.logs[2].topics[2] + ).toString(); + console.log("premiumCollected ", premiumCollected); + + const bundlerPaid = receipt.effectiveGasPrice.mul(receipt.gasUsed); + console.log("bundler paid ", bundlerPaid.toString()); + + const paymasterFundsAfter = await entryPoint.balanceOf(paymasterAddress); + const paymasterIdBalanceAfter = await sponsorshipPaymaster.getBalance( + fundingId + ); + + const paymasterIdBalanceDiff = paymasterIdBalanceBefore.sub( + paymasterIdBalanceAfter + ); + console.log("paymasterIdBalanceDiff ", paymasterIdBalanceDiff.toString()); + + const paymasterFundsDiff = paymasterFundsBefore.sub(paymasterFundsAfter); + console.log("paymasterFundsDiff ", paymasterFundsDiff.toString()); + + // paymasterIdBalanceDiffWithoutPremium should be greater than paymaster funds diff (that means unaccounted overhead is right) + expect( + chargedFromDappIncludingPremium + .sub(premiumCollected) + .sub(paymasterFundsDiff) + ).to.be.greaterThan(BigNumber.from(0)); + + await expect( + entryPoint.handleOps([userOp], await offchainSigner.getAddress()) + ).to.be.reverted; + + const feeCollectorBalanceAfter = await sponsorshipPaymaster.getBalance( + await feeCollector.getAddress() + ); + expect(feeCollectorBalanceAfter).to.be.greaterThan(BigNumber.from(0)); + + // 0.1 / 1.1 = actual gas used * 0.1 + expect( + feeCollectorBalanceAfter.sub(feeCollectorBalanceBefore) + ).to.be.equal( + paymasterIdBalanceDiff.mul(BigNumber.from(1)).div(BigNumber.from(11)) + ); + }); + + it("fails for fundingId which does not have enough deposit", async () => { + const fundingId = await thirdFundingId.getAddress(); + + // TODO: find accurate value of unaccountedEPGasOverhead based on userOpGasPrice calculation flip (maxFeePerGas vs block.gasprice + priorityFee) + await sponsorshipPaymaster + .connect(deployer) + .setUnaccountedEPGasOverhead(38500); + + // do not deposit + + const signer = await sponsorshipPaymaster.verifyingSigner(); + const offchainSignerAddress = await offchainSigner.getAddress(); + expect(signer).to.be.equal(offchainSignerAddress); + + const userOp1 = await fillAndSign( + { + sender: walletAddress, + verificationGasLimit: 200000, + }, + walletOwner, + entryPoint, + "nonce" + ); + + const hash = await sponsorshipPaymaster.getHash( + userOp1, + fundingId, + MOCK_VALID_UNTIL, + MOCK_VALID_AFTER, + dynamicMarkup + ); + const sig = await offchainSigner.signMessage(arrayify(hash)); + const numVU = ethers.BigNumber.from(MOCK_VALID_UNTIL); + const numVA = ethers.BigNumber.from(MOCK_VALID_AFTER); + const userOp = await fillAndSign( + { + ...userOp1, + paymasterAndData: hexConcat([ + paymasterAddress, + ethers.utils.hexZeroPad(fundingId, 20), + ethers.utils.hexZeroPad(ethers.utils.hexlify(numVU.toNumber()), 6), // 6 byte + ethers.utils.hexZeroPad(ethers.utils.hexlify(numVA.toNumber()), 6), // 6 byte + ethers.utils.hexZeroPad(ethers.utils.hexlify(dynamicMarkup), 4), // 4 bytes + sig, + ]), + }, + walletOwner, + entryPoint, + "nonce" + ); + + const signatureWithModuleAddress = ethers.utils.defaultAbiCoder.encode( + ["bytes", "address"], + [userOp.signature, ecdsaModule.address] + ); + userOp.signature = signatureWithModuleAddress; + + await expect(entryPoint.callStatic.simulateValidation(userOp)) + .to.be.revertedWithCustomError(entryPoint, "FailedOp") + .withArgs( + 0, + "AA33 reverted: Sponsorship Paymaster: paymasterId does not have enough deposit" + ); + }); + }); + + describe("Sponsorship Paymaster - read methods and state checks", () => { + it("Should parse data properly", async () => { + const numVU = ethers.BigNumber.from(MOCK_VALID_UNTIL); + const numVA = ethers.BigNumber.from(MOCK_VALID_AFTER); + const paymasterAndData = hexConcat([ + paymasterAddress, + ethers.utils.hexZeroPad(await offchainSigner.getAddress(), 20), + ethers.utils.hexZeroPad(ethers.utils.hexlify(numVU.toNumber()), 6), // 6 byte + ethers.utils.hexZeroPad(ethers.utils.hexlify(numVA.toNumber()), 6), // 6 byte + ethers.utils.hexZeroPad(ethers.utils.hexlify(dynamicMarkup), 4), // 4 bytes + "0x" + "00".repeat(65), + ]); + + const res = await sponsorshipPaymaster.parsePaymasterAndData( + paymasterAndData + ); + + expect(res.paymasterId).to.equal(await offchainSigner.getAddress()); + expect(res.validUntil).to.equal(ethers.BigNumber.from(MOCK_VALID_UNTIL)); + expect(res.validAfter).to.equal(ethers.BigNumber.from(MOCK_VALID_AFTER)); + expect(res.priceMarkup).to.equal(dynamicMarkup); + expect(res.signature).to.equal("0x" + "00".repeat(65)); + }); + + it("Invalid paymasterAndData causes revert", async () => { + const paymasterAndData = + "0x9c145aed0000000000000000000000000000000000000000000000"; + + await expect(sponsorshipPaymaster.parsePaymasterAndData(paymasterAndData)) + .to.be.reverted; + }); + + it("should check the correct states set on the paymaster", async () => { + const owner = await sponsorshipPaymaster.owner(); + + const verifyingSigner = await sponsorshipPaymaster.verifyingSigner(); + + const feeReceiver = await sponsorshipPaymaster.feeCollector(); + + expect(owner).to.be.equal(deployer.address); + expect(verifyingSigner).to.be.equal(offchainSigner.address); + expect(feeReceiver).to.be.equal(feeCollector.address); + }); + }); + + describe("Sponsorship Paymaster - deposit and withdraw tests", () => { + it("Deposits into the specified address", async () => { + const paymasterId = await depositorSigner.getAddress(); + + await sponsorshipPaymaster.depositFor(paymasterId, { + value: parseEther("1"), + }); + + const balance = await sponsorshipPaymaster.getBalance(paymasterId); + expect(balance).to.be.equal(parseEther("1")); + }); + + it("Does not allow 0 value deposits", async () => { + const paymasterId = await depositorSigner.getAddress(); + + await expect( + sponsorshipPaymaster.depositFor(paymasterId, { + value: parseEther("0"), + }) + ).to.be.revertedWithCustomError( + sponsorshipPaymaster, + "DepositCanNotBeZero" + ); + }); + + it("Does not allow deposits for 0 address paymasterId", async () => { + const paymasterId = ethers.constants.AddressZero; + + await expect( + sponsorshipPaymaster.depositFor(paymasterId, { + value: parseEther("0.5"), + }) + ).to.be.revertedWithCustomError( + sponsorshipPaymaster, + "PaymasterIdCannotBeZero" + ); + }); + + it("Reverts withdraw when paymasterIdBalance is not enough", async () => { + const paymasterId = await depositorSigner.getAddress(); + + await expect( + sponsorshipPaymaster + .connect(depositorSigner) + .withdrawTo(paymasterId, parseEther("1.1")) + ).to.be.revertedWith( + "Sponsorship Paymaster: Insufficient funds to withdraw from gas tank" + ); + }); + }); +}); diff --git a/test/sponsorship-paymaster/biconomy-verifying-paymaster-specs.ts b/test/sponsorship-paymaster/biconomy-verifying-paymaster-specs.ts deleted file mode 100644 index d187f1b..0000000 --- a/test/sponsorship-paymaster/biconomy-verifying-paymaster-specs.ts +++ /dev/null @@ -1,242 +0,0 @@ -/* eslint-disable node/no-missing-import */ -/* eslint-disable camelcase */ -import { expect } from "chai"; -import { ethers } from "hardhat"; - -import { - BiconomyAccountImplementation, - BiconomyAccountImplementation__factory, - BiconomyAccountFactory, - BiconomyAccountFactory__factory, - VerifyingSingletonPaymaster, - VerifyingSingletonPaymaster__factory, -} from "../../typechain-types"; -// Review: Could import from scw-contracts submodules to be consistent -import { fillAndSign } from "../utils/userOp"; -import { UserOperation } from "../../lib/account-abstraction/test/UserOperation"; -import { - createAccount, - simulationResultCatch, -} from "../../lib/account-abstraction/test/testutils"; -import { - EntryPoint, - EntryPoint__factory, - SimpleAccount, - TestToken, - TestToken__factory, -} from "../../lib/account-abstraction/typechain"; -import { - EcdsaOwnershipRegistryModule, - EcdsaOwnershipRegistryModule__factory, -} from "@biconomy-devx/account-contracts-v2/dist/types"; -import { arrayify, hexConcat, parseEther } from "ethers/lib/utils"; -import { BigNumber, BigNumberish, Contract, Signer } from "ethers"; - -export const AddressZero = ethers.constants.AddressZero; - -const MOCK_VALID_UNTIL = "0x00000000deadbeef"; -const MOCK_VALID_AFTER = "0x0000000000001234"; - -export async function deployEntryPoint( - provider = ethers.provider -): Promise { - const epf = await (await ethers.getContractFactory("EntryPoint")).deploy(); - return EntryPoint__factory.connect(epf.address, provider.getSigner()); -} - -describe("EntryPoint with VerifyingPaymaster Singleton", function () { - let entryPoint: EntryPoint; - let entryPointStatic: EntryPoint; - let depositorSigner: Signer; - let walletOwner: Signer; - let proxyPaymaster: Contract; - let walletAddress: string, paymasterAddress: string; - let ethersSigner; - - let offchainSigner: Signer, deployer: Signer; - - let verifyingSingletonPaymaster: VerifyingSingletonPaymaster; - // Could also use published package or added submodule (for Account Implementation and Factory) - let smartWalletImp: BiconomyAccountImplementation; - let ecdsaModule: EcdsaOwnershipRegistryModule; - let walletFactory: BiconomyAccountFactory; - const abi = ethers.utils.defaultAbiCoder; - - beforeEach(async function () { - ethersSigner = await ethers.getSigners(); - entryPoint = await deployEntryPoint(); - entryPointStatic = entryPoint.connect(AddressZero); - - deployer = ethersSigner[0]; - offchainSigner = ethersSigner[1]; - depositorSigner = ethersSigner[2]; - walletOwner = deployer; // ethersSigner[3]; - - const offchainSignerAddress = await offchainSigner.getAddress(); - const walletOwnerAddress = await walletOwner.getAddress(); - - ecdsaModule = await new EcdsaOwnershipRegistryModule__factory( - deployer - ).deploy(); - - verifyingSingletonPaymaster = - await new VerifyingSingletonPaymaster__factory(deployer).deploy( - await deployer.getAddress(), - entryPoint.address, - offchainSignerAddress - ); - - smartWalletImp = await new BiconomyAccountImplementation__factory( - deployer - ).deploy(entryPoint.address); - - walletFactory = await new BiconomyAccountFactory__factory(deployer).deploy( - smartWalletImp.address, - walletOwnerAddress - ); - - await walletFactory - .connect(deployer) - .addStake(entryPoint.address, 86400, { value: parseEther("2") }); - - const ecdsaOwnershipSetupData = ecdsaModule.interface.encodeFunctionData( - "initForSmartAccount", - [walletOwnerAddress] - ); - - const smartAccountDeploymentIndex = 0; - - await walletFactory.deployCounterFactualAccount( - ecdsaModule.address, - ecdsaOwnershipSetupData, - smartAccountDeploymentIndex - ); - const expected = await walletFactory.getAddressForCounterFactualAccount( - ecdsaModule.address, - ecdsaOwnershipSetupData, - smartAccountDeploymentIndex - ); - - walletAddress = expected; - - paymasterAddress = verifyingSingletonPaymaster.address; - - await verifyingSingletonPaymaster - .connect(deployer) - .addStake(86400, { value: parseEther("2") }); - - await entryPoint.depositTo(paymasterAddress, { value: parseEther("1") }); - }); - - async function getUserOpWithPaymasterInfo(paymasterId: string) { - const userOp1 = await fillAndSign( - { - sender: walletAddress, - }, - walletOwner, - entryPoint, - "nonce" - ); - - const hash = await verifyingSingletonPaymaster.getHash( - userOp1, - paymasterId, - MOCK_VALID_UNTIL, - MOCK_VALID_AFTER - ); - const sig = await offchainSigner.signMessage(arrayify(hash)); - const paymasterData = abi.encode( - ["address", "uint48", "uint48", "bytes"], - [paymasterId, MOCK_VALID_UNTIL, MOCK_VALID_AFTER, sig] - ); - const paymasterAndData = hexConcat([paymasterAddress, paymasterData]); - return await fillAndSign( - { - ...userOp1, - paymasterAndData, - }, - walletOwner, - entryPoint, - "nonce" - ); - } - - describe("#validatePaymasterUserOp", () => { - it("Should Fail when there is no deposit for paymaster id", async () => { - const paymasterId = await depositorSigner.getAddress(); - const userOp = await getUserOpWithPaymasterInfo(paymasterId); - - const signatureWithModuleAddress = ethers.utils.defaultAbiCoder.encode( - ["bytes", "address"], - [userOp.signature, ecdsaModule.address] - ); - - userOp.signature = signatureWithModuleAddress; - - await expect( - entryPoint.callStatic.simulateValidation(userOp) - // ).to.be.revertedWith("FailedOp"); - ).to.be.reverted; - }); - - it("succeed with valid signature", async () => { - const signer = await verifyingSingletonPaymaster.verifyingSigner(); - const offchainSignerAddress = await offchainSigner.getAddress(); - expect(signer).to.be.equal(offchainSignerAddress); - - await verifyingSingletonPaymaster.depositFor( - await offchainSigner.getAddress(), - { value: ethers.utils.parseEther("1") } - ); - const userOp1 = await fillAndSign( - { - sender: walletAddress, - verificationGasLimit: 200000, - }, - walletOwner, - entryPoint, - "nonce" - ); - - const hash = await verifyingSingletonPaymaster.getHash( - userOp1, - await offchainSigner.getAddress(), - MOCK_VALID_UNTIL, - MOCK_VALID_AFTER - ); - const sig = await offchainSigner.signMessage(arrayify(hash)); - const userOp = await fillAndSign( - { - ...userOp1, - paymasterAndData: hexConcat([ - paymasterAddress, - ethers.utils.defaultAbiCoder.encode( - ["address", "uint48", "uint48", "bytes"], - [ - await offchainSigner.getAddress(), - MOCK_VALID_UNTIL, - MOCK_VALID_AFTER, - sig, - ] - ), - ]), - }, - walletOwner, - entryPoint, - "nonce" - ); - - const signatureWithModuleAddress = ethers.utils.defaultAbiCoder.encode( - ["bytes", "address"], - [userOp.signature, ecdsaModule.address] - ); - - userOp.signature = signatureWithModuleAddress; - - await entryPoint.handleOps([userOp], await offchainSigner.getAddress()); - await expect( - entryPoint.handleOps([userOp], await offchainSigner.getAddress()) - ).to.be.reverted; - }); - }); -}); diff --git a/test/token-paymaster/biconomy-token-paymaster-specs.ts b/test/token-paymaster/biconomy-token-paymaster-specs.ts index bbef1c5..21580df 100644 --- a/test/token-paymaster/biconomy-token-paymaster-specs.ts +++ b/test/token-paymaster/biconomy-token-paymaster-specs.ts @@ -12,26 +12,19 @@ import { BiconomyAccountFactory__factory, BiconomyTokenPaymaster, BiconomyTokenPaymaster__factory, - ChainlinkOracleAggregator, - ChainlinkOracleAggregator__factory, MockPriceFeed, MockPriceFeed__factory, MockToken, + MockOracle__factory, } from "../../typechain-types"; // Review: Could import from scw-contracts submodules to be consistent and without copying files import { fillAndSign } from "../utils/userOp"; -import { UserOperation } from "../../lib/account-abstraction/test/UserOperation"; -import { - createAccount, - simulationResultCatch, -} from "../../lib/account-abstraction/test/testutils"; +import { simulationResultCatch } from "../../lib/account-abstraction/test/testutils"; import { EntryPoint, EntryPoint__factory, - SimpleAccount, TestToken, - TestToken__factory, } from "../../lib/account-abstraction/typechain"; import { EcdsaOwnershipRegistryModule, @@ -40,6 +33,7 @@ import { import { arrayify, hexConcat, parseEther } from "ethers/lib/utils"; import { BigNumber, BigNumberish, Contract, Signer } from "ethers"; import { SignerWithAddress } from "hardhat-deploy-ethers/signers"; +import { getUserOpEvent, parseEvent } from "../utils/testUtils"; export const AddressZero = ethers.constants.AddressZero; @@ -51,38 +45,25 @@ const DEFAULT_FEE_MARKUP = 1100000; const MOCK_FX: BigNumberish = "977100"; // matic to usdc approx +const UserOperationEventTopic = + "0x49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f"; + export async function deployEntryPoint( provider = ethers.provider ): Promise { return new EntryPoint__factory(provider.getSigner()).deploy(); } -export const encodePaymasterData = ( - feeToken = ethers.constants.AddressZero, - oracleAggregator = ethers.constants.AddressZero, - exchangeRate: BigNumberish = ethers.constants.Zero, - priceMarkup: BigNumberish = ethers.constants.Zero -) => { - return ethers.utils.defaultAbiCoder.encode( - ["uint48", "uint48", "address", "address", "uint256", "uint32"], - [ - MOCK_VALID_UNTIL, - MOCK_VALID_AFTER, - feeToken, - oracleAggregator, - exchangeRate, - priceMarkup, - ] - ); -}; - -export async function getUserOpEvent(ep: EntryPoint) { - const [log] = await ep.queryFilter( - ep.filters.UserOperationEvent(), - await ethers.provider.getBlockNumber() - ); - return log; -} +// export const encodePaymasterData = ( +// feeToken = ethers.constants.AddressZero, +// exchangeRate: BigNumberish = ethers.constants.Zero, +// priceMarkup: BigNumberish = ethers.constants.Zero +// ) => { +// return ethers.utils.defaultAbiCoder.encode( +// ["uint48", "uint48", "address", "uint256", "uint32"], +// [MOCK_VALID_UNTIL, MOCK_VALID_AFTER, feeToken, exchangeRate, priceMarkup] +// ); +// }; export const encodeERC20Approval = ( account: BiconomyAccountImplementation, @@ -110,8 +91,6 @@ describe("Biconomy Token Paymaster", function () { let offchainSigner: Signer, deployer: Signer; let sampleTokenPaymaster: BiconomyTokenPaymaster; - let mockPriceFeed: MockPriceFeed; - let oracleAggregator: ChainlinkOracleAggregator; // Note: Could also use published package or added submodule (for Account Implementation and Factory) let smartWalletImp: BiconomyAccountImplementation; @@ -127,15 +106,11 @@ describe("Biconomy Token Paymaster", function () { deployer = ethersSigner[0]; offchainSigner = ethersSigner[1]; depositorSigner = ethersSigner[2]; - walletOwner = deployer; // ethersSigner[3]; + walletOwner = deployer; // ethersSigner[0]; // const offchainSignerAddress = await deployer.getAddress(); const walletOwnerAddress = await walletOwner.getAddress(); - oracleAggregator = await new ChainlinkOracleAggregator__factory( - deployer - ).deploy(walletOwnerAddress); - ecdsaModule = await new EcdsaOwnershipRegistryModule__factory( deployer ).deploy(); @@ -144,7 +119,6 @@ describe("Biconomy Token Paymaster", function () { token = await MockToken.deploy(); await token.deployed(); - const usdcMaticPriceFeedMock = await new MockPriceFeed__factory( deployer ).deploy(); @@ -154,19 +128,13 @@ describe("Biconomy Token Paymaster", function () { usdcMaticPriceFeedMock.address ); - const priceFeedTxUsdc: any = - await priceFeedUsdc.populateTransaction.getThePrice(); - - await oracleAggregator.setTokenOracle( - token.address, - usdcMaticPriceFeedMock.address, - 18, - priceFeedTxUsdc.data, - true + const nativeOracle = await new MockOracle__factory(deployer).deploy( + 82843594, + "MATIC/USD" ); - - const priceResult = await oracleAggregator.getTokenValueOfOneNativeToken( - token.address + const tokenOracle = await new MockOracle__factory(deployer).deploy( + 100000000, + "USDC/USD" ); sampleTokenPaymaster = await new BiconomyTokenPaymaster__factory( @@ -177,6 +145,17 @@ describe("Biconomy Token Paymaster", function () { await offchainSigner.getAddress() ); + await sampleTokenPaymaster.setTokenOracle( + token.address, + tokenOracle.address, + nativeOracle.address, + true, + 172800 // 2 days + ); + + const priceResult = + await sampleTokenPaymaster.getTokenValueOfOneNativeToken(token.address); + smartWalletImp = await new BiconomyAccountImplementation__factory( deployer ).deploy(entryPoint.address); @@ -214,7 +193,6 @@ describe("Biconomy Token Paymaster", function () { walletAddress = expected; paymasterAddress = sampleTokenPaymaster.address; - await sampleTokenPaymaster .connect(deployer) @@ -225,15 +203,18 @@ describe("Biconomy Token Paymaster", function () { describe("Token Payamster read methods and state checks", () => { it("Should parse data properly", async () => { + const numVU = ethers.BigNumber.from(MOCK_VALID_UNTIL); + const numVA = ethers.BigNumber.from(MOCK_VALID_AFTER); + const numER = ethers.BigNumber.from(MOCK_FX); + const paymasterAndData = ethers.utils.hexConcat([ paymasterAddress, ethers.utils.hexlify(1).slice(0, 4), - encodePaymasterData( - token.address, - oracleAggregator.address, - MOCK_FX, - DEFAULT_FEE_MARKUP - ), + ethers.utils.hexZeroPad(ethers.utils.hexlify(numVU.toNumber()), 6), // 6 byte + ethers.utils.hexZeroPad(ethers.utils.hexlify(numVA.toNumber()), 6), // 6 byte + ethers.utils.hexZeroPad(token.address, 20), // 20 byte + ethers.utils.hexZeroPad(ethers.utils.hexlify(numER.toNumber()), 16), // 16 byte + ethers.utils.hexZeroPad(ethers.utils.hexlify(DEFAULT_FEE_MARKUP), 4), // 4 byte "0x" + "00".repeat(65), ]); @@ -242,12 +223,18 @@ describe("Biconomy Token Paymaster", function () { ); expect(res.priceSource).to.equal(1); + + console.log(res.validUntil); + expect(res.priceMarkup).to.equal(DEFAULT_FEE_MARKUP); - expect(res.validUntil).to.equal(ethers.BigNumber.from(MOCK_VALID_UNTIL)); - expect(res.validAfter).to.equal(ethers.BigNumber.from(MOCK_VALID_AFTER)); + expect(res.validUntil).to.equal( + ethers.BigNumber.from(MOCK_VALID_UNTIL).toNumber() + ); + expect(res.validAfter).to.equal( + ethers.BigNumber.from(MOCK_VALID_AFTER).toNumber() + ); expect(res.feeToken).to.equal(token.address); - expect(res.oracleAggregator).to.equal(oracleAggregator.address); - expect(res.exchangeRate).to.equal(MOCK_FX); + expect(res.exchangeRate).to.equal(BigNumber.from(MOCK_FX).toNumber()); expect(res.signature).to.equal("0x" + "00".repeat(65)); }); @@ -320,23 +307,29 @@ describe("Biconomy Token Paymaster", function () { MOCK_VALID_UNTIL, MOCK_VALID_AFTER, token.address, - oracleAggregator.address, MOCK_FX, DEFAULT_FEE_MARKUP ); const sig = await offchainSigner.signMessage(arrayify(hash)); + + const numVU = ethers.BigNumber.from(MOCK_VALID_UNTIL); + const numVA = ethers.BigNumber.from(MOCK_VALID_AFTER); + const numER = ethers.BigNumber.from(MOCK_FX); + const userOp = await fillAndSign( { ...userOp1, paymasterAndData: ethers.utils.hexConcat([ paymasterAddress, ethers.utils.hexlify(1).slice(0, 4), - encodePaymasterData( - token.address, - oracleAggregator.address, - MOCK_FX, - DEFAULT_FEE_MARKUP - ), + ethers.utils.hexZeroPad(ethers.utils.hexlify(numVU.toNumber()), 6), // 6 byte + ethers.utils.hexZeroPad(ethers.utils.hexlify(numVA.toNumber()), 6), // 6 byte + ethers.utils.hexZeroPad(token.address, 20), // 20 byte + ethers.utils.hexZeroPad(ethers.utils.hexlify(numER.toNumber()), 16), // 16 byte + ethers.utils.hexZeroPad( + ethers.utils.hexlify(DEFAULT_FEE_MARKUP), + 4 + ), // 4 byte sig, ]), }, @@ -357,7 +350,6 @@ describe("Biconomy Token Paymaster", function () { .add(userOp.preVerificationGas) .mul(userOp.maxFeePerGas); - const preTokenBalanceForAccount = await token.balanceOf(walletAddress); const tx = await entryPoint.handleOps( [userOp], @@ -365,13 +357,28 @@ describe("Biconomy Token Paymaster", function () { ); const receipt = await tx.wait(); + console.log("paymaster and data length", userOp.paymasterAndData.length); + const gasUsed = receipt.gasUsed.toNumber(); + console.log("gas used token paymaster", gasUsed); + console.log( + "fees paid in native ", + receipt.effectiveGasPrice.mul(receipt.gasUsed).toString() + ); const postBalance = await token.balanceOf(paymasterAddress); const postTokenBalanceForAccount = await token.balanceOf(walletAddress); + expect(postTokenBalanceForAccount).to.be.lt(preTokenBalanceForAccount); + + const event = parseEvent(receipt, UserOperationEventTopic); + + const eventLogsUserop = entryPoint.interface.decodeEventLog( + "UserOperationEvent", + event[0].data + ); - const ev = await getUserOpEvent(entryPoint); - expect(ev.args.success).to.be.true; + // eslint-disable-next-line no-unused-expressions + expect(eventLogsUserop.success).to.be.true; await expect( entryPoint.handleOps([userOp], await offchainSigner.getAddress()) @@ -386,6 +393,10 @@ describe("Biconomy Token Paymaster", function () { deployer ); + const numVU = ethers.BigNumber.from(MOCK_VALID_UNTIL); + const numVA = ethers.BigNumber.from(MOCK_VALID_AFTER); + const numER = ethers.BigNumber.from(MOCK_FX); + const userOp = await fillAndSign( { sender: walletAddress, @@ -401,11 +412,15 @@ describe("Biconomy Token Paymaster", function () { paymasterAndData: ethers.utils.hexConcat([ paymasterAddress, ethers.utils.hexlify(1).slice(0, 4), - encodePaymasterData( - token.address, - oracleAggregator.address, - MOCK_FX - ), + ethers.utils.hexZeroPad(ethers.utils.hexlify(numVU.toNumber()), 6), // 6 byte + ethers.utils.hexZeroPad(ethers.utils.hexlify(numVA.toNumber()), 6), // 6 byte + ethers.utils.hexZeroPad(token.address, 20), // 20 byte + ethers.utils.hexZeroPad(ethers.utils.hexlify(numER.toNumber()), 16), // 16 byte + ethers.utils.hexZeroPad( + ethers.utils.hexlify(DEFAULT_FEE_MARKUP), + 4 + ), // 4 byte + "0x1234", ]), }, @@ -423,10 +438,7 @@ describe("Biconomy Token Paymaster", function () { await expect(entryPoint.callStatic.simulateValidation(userOp)) .to.be.revertedWithCustomError(entryPoint, "FailedOp") - .withArgs( - 0, - "AA33 reverted: BTPM: invalid signature length in paymasterAndData" - ); + .withArgs(0, "AA33 reverted: ECDSA: invalid signature length"); }); it("should revert (from EntryPoint) on invalid paymaster and data length", async () => { @@ -515,6 +527,10 @@ describe("Biconomy Token Paymaster", function () { deployer ); + const numVU = ethers.BigNumber.from(MOCK_VALID_UNTIL); + const numVA = ethers.BigNumber.from(MOCK_VALID_AFTER); + const numER = ethers.BigNumber.from(MOCK_FX); + const userOp = await fillAndSign( { sender: walletAddress, @@ -530,11 +546,14 @@ describe("Biconomy Token Paymaster", function () { paymasterAndData: ethers.utils.hexConcat([ paymasterAddress, ethers.utils.hexlify(1).slice(0, 4), - encodePaymasterData( - token.address, - oracleAggregator.address, - MOCK_FX - ), + ethers.utils.hexZeroPad(ethers.utils.hexlify(numVU.toNumber()), 6), // 6 byte + ethers.utils.hexZeroPad(ethers.utils.hexlify(numVA.toNumber()), 6), // 6 byte + ethers.utils.hexZeroPad(token.address, 20), // 20 byte + ethers.utils.hexZeroPad(ethers.utils.hexlify(numER.toNumber()), 16), // 16 byte + ethers.utils.hexZeroPad( + ethers.utils.hexlify(DEFAULT_FEE_MARKUP), + 4 + ), // 4 byte "0x" + "00".repeat(65), ]), }, @@ -565,6 +584,10 @@ describe("Biconomy Token Paymaster", function () { ethers.utils.arrayify("0xdead") ); + const numVU = ethers.BigNumber.from(MOCK_VALID_UNTIL); + const numVA = ethers.BigNumber.from(MOCK_VALID_AFTER); + const numER = ethers.BigNumber.from(MOCK_FX); + const wrongUserOp = await fillAndSign( { sender: walletAddress, @@ -580,11 +603,14 @@ describe("Biconomy Token Paymaster", function () { paymasterAndData: ethers.utils.hexConcat([ paymasterAddress, ethers.utils.hexlify(1).slice(0, 4), - encodePaymasterData( - token.address, - oracleAggregator.address, - MOCK_FX - ), + ethers.utils.hexZeroPad(ethers.utils.hexlify(numVU.toNumber()), 6), // 6 byte + ethers.utils.hexZeroPad(ethers.utils.hexlify(numVA.toNumber()), 6), // 6 byte + ethers.utils.hexZeroPad(token.address, 20), // 20 byte + ethers.utils.hexZeroPad(ethers.utils.hexlify(numER.toNumber()), 16), // 16 byte + ethers.utils.hexZeroPad( + ethers.utils.hexlify(DEFAULT_FEE_MARKUP), + 4 + ), // 4 byte sig, ]), }, @@ -616,8 +642,8 @@ describe("Biconomy Token Paymaster", function () { }); }); - describe("Negative scenarios: approvals and transfers gone wrong", () => { - it("should revert if ERC20 token withdrawal fails", async () => { + describe("Grief scneario: not enough allowance for postOp", async () => { + it("should revert in second postOp", async () => { const userSCW: any = BiconomyAccountImplementation__factory.connect( walletAddress, deployer @@ -627,7 +653,27 @@ describe("Biconomy Token Paymaster", function () { .connect(deployer) .transfer(walletAddress, ethers.utils.parseEther("100")); - // We make transferFrom impossible by setting allowance to zero + const owner = await walletOwner.getAddress(); + const AccountFactory = await ethers.getContractFactory( + "SmartAccountFactory" + ); + + const ecdsaOwnershipSetupData = ecdsaModule.interface.encodeFunctionData( + "initForSmartAccount", + [owner] + ); + + const smartAccountDeploymentIndex = 0; + + const deploymentData = AccountFactory.interface.encodeFunctionData( + "deployCounterFactualAccount", + [ + ecdsaModule.address, + ecdsaOwnershipSetupData, + smartAccountDeploymentIndex, + ] + ); + const userOp1 = await fillAndSign( { sender: walletAddress, @@ -638,7 +684,7 @@ describe("Biconomy Token Paymaster", function () { userSCW, token, paymasterAddress, - ethers.constants.Zero + ethers.constants.Zero // Making allowance 0 in execution ), }, walletOwner, @@ -652,23 +698,29 @@ describe("Biconomy Token Paymaster", function () { MOCK_VALID_UNTIL, MOCK_VALID_AFTER, token.address, - oracleAggregator.address, MOCK_FX, DEFAULT_FEE_MARKUP ); const sig = await offchainSigner.signMessage(arrayify(hash)); + + const numVU = ethers.BigNumber.from(MOCK_VALID_UNTIL); + const numVA = ethers.BigNumber.from(MOCK_VALID_AFTER); + const numER = ethers.BigNumber.from(MOCK_FX); + const userOp = await fillAndSign( { ...userOp1, paymasterAndData: ethers.utils.hexConcat([ paymasterAddress, ethers.utils.hexlify(1).slice(0, 4), - encodePaymasterData( - token.address, - oracleAggregator.address, - MOCK_FX, - DEFAULT_FEE_MARKUP - ), + ethers.utils.hexZeroPad(ethers.utils.hexlify(numVU.toNumber()), 6), // 6 byte + ethers.utils.hexZeroPad(ethers.utils.hexlify(numVA.toNumber()), 6), // 6 byte + ethers.utils.hexZeroPad(token.address, 20), // 20 byte + ethers.utils.hexZeroPad(ethers.utils.hexlify(numER.toNumber()), 16), // 16 byte + ethers.utils.hexZeroPad( + ethers.utils.hexlify(DEFAULT_FEE_MARKUP), + 4 + ), // 4 byte sig, ]), }, @@ -684,19 +736,18 @@ describe("Biconomy Token Paymaster", function () { userOp.signature = signatureWithModuleAddress; - await entryPoint.handleOps([userOp], await offchainSigner.getAddress()); - - const postBalance = await token.balanceOf(paymasterAddress); - - const ev = await getUserOpEvent(entryPoint); - // Review this because despite explicit revert bundler still pays gas - expect(ev.args.success).to.be.false; - await expect( entryPoint.handleOps([userOp], await offchainSigner.getAddress()) - ).to.be.reverted; + ) + .to.be.revertedWithCustomError(entryPoint, "FailedOp") + .withArgs( + 0, + "AA50 postOp reverted: BTPM PostOpReverted: Failed to charge tokens" + ); }); + }); + describe("Negative scenarios", () => { it("should revert if price markup charged is too darn high", async () => { const userSCW: any = BiconomyAccountImplementation__factory.connect( walletAddress, @@ -732,10 +783,12 @@ describe("Biconomy Token Paymaster", function () { MOCK_VALID_UNTIL, MOCK_VALID_AFTER, token.address, - oracleAggregator.address, MOCK_FX, 2200000 // > 2x! ); + const numVU = ethers.BigNumber.from(MOCK_VALID_UNTIL); + const numVA = ethers.BigNumber.from(MOCK_VALID_AFTER); + const numER = ethers.BigNumber.from(MOCK_FX); const sig = await offchainSigner.signMessage(arrayify(hash)); const userOp = await fillAndSign( { @@ -743,12 +796,11 @@ describe("Biconomy Token Paymaster", function () { paymasterAndData: ethers.utils.hexConcat([ paymasterAddress, ethers.utils.hexlify(1).slice(0, 4), - encodePaymasterData( - token.address, - oracleAggregator.address, - MOCK_FX, - 2200000 - ), + ethers.utils.hexZeroPad(ethers.utils.hexlify(numVU.toNumber()), 6), // 6 byte + ethers.utils.hexZeroPad(ethers.utils.hexlify(numVA.toNumber()), 6), // 6 byte + ethers.utils.hexZeroPad(token.address, 20), // 20 byte + ethers.utils.hexZeroPad(ethers.utils.hexlify(numER.toNumber()), 16), // 16 byte + ethers.utils.hexZeroPad(ethers.utils.hexlify(2200000), 4), // 4 byte sig, ]), }, @@ -788,7 +840,8 @@ describe("Biconomy Token Paymaster", function () { let feeReceiver = await sampleTokenPaymaster.feeReceiver(); - let unaccountedCost = await sampleTokenPaymaster.UNACCOUNTED_COST(); + let unaccountedCost = + await sampleTokenPaymaster.unaccountedEPGasOverhead(); let owner = await sampleTokenPaymaster.owner(); @@ -809,7 +862,7 @@ describe("Biconomy Token Paymaster", function () { feeReceiver = await sampleTokenPaymaster.feeReceiver(); - unaccountedCost = await sampleTokenPaymaster.UNACCOUNTED_COST(); + unaccountedCost = await sampleTokenPaymaster.unaccountedEPGasOverhead(); owner = await sampleTokenPaymaster.owner(); diff --git a/test/token-paymaster/btpm-coverage-specs.ts b/test/token-paymaster/btpm-coverage-specs.ts index 7282cf8..bf52a9f 100644 --- a/test/token-paymaster/btpm-coverage-specs.ts +++ b/test/token-paymaster/btpm-coverage-specs.ts @@ -12,11 +12,10 @@ import { BiconomyAccountFactory__factory, BiconomyTokenPaymaster, BiconomyTokenPaymaster__factory, - ChainlinkOracleAggregator, - ChainlinkOracleAggregator__factory, MockPriceFeed, MockPriceFeed__factory, MockToken, + MockOracle__factory, } from "../../typechain-types"; import { fillAndSign } from "../../lib/account-abstraction/test/UserOp"; @@ -60,32 +59,16 @@ function delay(ms: number) { }); } -export const encodePaymasterData = ( - feeToken = ethers.constants.AddressZero, - oracleAggregator = ethers.constants.AddressZero, - exchangeRate: BigNumberish = ethers.constants.Zero, - priceMarkup: BigNumberish = ethers.constants.Zero -) => { - return ethers.utils.defaultAbiCoder.encode( - ["uint48", "uint48", "address", "address", "uint256", "uint32"], - [ - MOCK_VALID_UNTIL, - MOCK_VALID_AFTER, - feeToken, - oracleAggregator, - exchangeRate, - priceMarkup, - ] - ); -}; - -export async function getUserOpEvent(ep: EntryPoint) { - const [log] = await ep.queryFilter( - ep.filters.UserOperationEvent(), - await ethers.provider.getBlockNumber() - ); - return log; -} +// export const encodePaymasterData = ( +// feeToken = ethers.constants.AddressZero, +// exchangeRate: BigNumberish = ethers.constants.Zero, +// priceMarkup: BigNumberish = ethers.constants.Zero +// ) => { +// return ethers.utils.defaultAbiCoder.encode( +// ["uint48", "uint48", "address", "address", "uint256", "uint32"], +// [MOCK_VALID_UNTIL, MOCK_VALID_AFTER, feeToken, exchangeRate, priceMarkup] +// ); +// }; export const encodeERC20Approval = ( account: BiconomyAccountImplementation, @@ -114,7 +97,6 @@ describe("Biconomy Token Paymaster", function () { let sampleTokenPaymaster: BiconomyTokenPaymaster; let mockPriceFeed: MockPriceFeed; - let oracleAggregator: ChainlinkOracleAggregator; // Could also use published package or added submodule (for Account Implementation and Factory) let smartWalletImp: BiconomyAccountImplementation; @@ -130,15 +112,11 @@ describe("Biconomy Token Paymaster", function () { deployer = ethersSigner[0]; offchainSigner = ethersSigner[1]; depositorSigner = ethersSigner[2]; - walletOwner = deployer; // ethersSigner[3]; + walletOwner = deployer; // ethersSigner[0]; // const offchainSignerAddress = await deployer.getAddress(); const walletOwnerAddress = await walletOwner.getAddress(); - oracleAggregator = await new ChainlinkOracleAggregator__factory( - deployer - ).deploy(walletOwnerAddress); - ecdsaModule = await new EcdsaOwnershipRegistryModule__factory( deployer ).deploy(); @@ -151,24 +129,13 @@ describe("Biconomy Token Paymaster", function () { deployer ).deploy(); - const priceFeedUsdc = await ethers.getContractAt( - "FeedInterface", - usdcMaticPriceFeedMock.address + const nativeOracle = await new MockOracle__factory(deployer).deploy( + 82843594, + "MATIC/USD" ); - - const priceFeedTxUsdc: any = - await priceFeedUsdc.populateTransaction.getThePrice(); - - await oracleAggregator.setTokenOracle( - token.address, - usdcMaticPriceFeedMock.address, - 18, - priceFeedTxUsdc.data, - true - ); - - const priceResult = await oracleAggregator.getTokenValueOfOneNativeToken( - token.address + const tokenOracle = await new MockOracle__factory(deployer).deploy( + 100000000, + "USDC/USD" ); sampleTokenPaymaster = await new BiconomyTokenPaymaster__factory( @@ -179,6 +146,17 @@ describe("Biconomy Token Paymaster", function () { await offchainSigner.getAddress() ); + await sampleTokenPaymaster.setTokenOracle( + token.address, + tokenOracle.address, + nativeOracle.address, + true, + 172800 // 2 days + ); + + const priceResult = + await sampleTokenPaymaster.getTokenValueOfOneNativeToken(token.address); + smartWalletImp = await new BiconomyAccountImplementation__factory( deployer ).deploy(entryPoint.address); diff --git a/test/token-paymaster/btpm-undeployed-wallet.ts b/test/token-paymaster/btpm-undeployed-wallet.ts index 0d4cc6f..076fa6e 100644 --- a/test/token-paymaster/btpm-undeployed-wallet.ts +++ b/test/token-paymaster/btpm-undeployed-wallet.ts @@ -12,11 +12,10 @@ import { BiconomyAccountFactory__factory, BiconomyTokenPaymaster, BiconomyTokenPaymaster__factory, - ChainlinkOracleAggregator, - ChainlinkOracleAggregator__factory, MockPriceFeed, MockPriceFeed__factory, MockToken, + MockOracle__factory, } from "../../typechain-types"; // Review: Could import from scw-contracts submodules to be consistent @@ -39,6 +38,7 @@ import { EcdsaOwnershipRegistryModule, EcdsaOwnershipRegistryModule__factory, } from "@biconomy-devx/account-contracts-v2/dist/types"; +import { getUserOpEvent, parseEvent } from "../utils/testUtils"; export const AddressZero = ethers.constants.AddressZero; const NATIVE_ADDRESS = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"; @@ -51,38 +51,25 @@ const DEFAULT_FEE_MARKUP = 1100000; const MOCK_FX: BigNumberish = "977100"; // matic to usdc approx +const UserOperationEventTopic = + "0x49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f"; + export async function deployEntryPoint( provider = ethers.provider ): Promise { return new EntryPoint__factory(provider.getSigner()).deploy(); } -export const encodePaymasterData = ( - feeToken = ethers.constants.AddressZero, - oracleAggregator = ethers.constants.AddressZero, - exchangeRate: BigNumberish = ethers.constants.Zero, - priceMarkup: BigNumberish = ethers.constants.Zero -) => { - return ethers.utils.defaultAbiCoder.encode( - ["uint48", "uint48", "address", "address", "uint256", "uint32"], - [ - MOCK_VALID_UNTIL, - MOCK_VALID_AFTER, - feeToken, - oracleAggregator, - exchangeRate, - priceMarkup, - ] - ); -}; - -export async function getUserOpEvent(ep: EntryPoint) { - const [log] = await ep.queryFilter( - ep.filters.UserOperationEvent(), - await ethers.provider.getBlockNumber() - ); - return log; -} +// export const encodePaymasterData = ( +// feeToken = ethers.constants.AddressZero, +// exchangeRate: BigNumberish = ethers.constants.Zero, +// priceMarkup: BigNumberish = ethers.constants.Zero +// ) => { +// return ethers.utils.defaultAbiCoder.encode( +// ["uint48", "uint48", "address", "uint256", "uint32"], +// [MOCK_VALID_UNTIL, MOCK_VALID_AFTER, feeToken, exchangeRate, priceMarkup] +// ); +// }; export const encodeERC20Approval = ( account: BiconomyAccountImplementation, @@ -111,7 +98,6 @@ describe("Biconomy Token Paymaster", function () { let sampleTokenPaymaster: BiconomyTokenPaymaster; let mockPriceFeed: MockPriceFeed; - let oracleAggregator: ChainlinkOracleAggregator; // Could also use published package or added submodule (for Account Implementation and Factory) let smartWalletImp: BiconomyAccountImplementation; @@ -127,15 +113,11 @@ describe("Biconomy Token Paymaster", function () { deployer = ethersSigner[0]; offchainSigner = ethersSigner[1]; depositorSigner = ethersSigner[2]; - walletOwner = deployer; // ethersSigner[3]; + walletOwner = deployer; // ethersSigner[0]; // const offchainSignerAddress = await deployer.getAddress(); const walletOwnerAddress = await walletOwner.getAddress(); - oracleAggregator = await new ChainlinkOracleAggregator__factory( - deployer - ).deploy(walletOwnerAddress); - ecdsaModule = await new EcdsaOwnershipRegistryModule__factory( deployer ).deploy(); @@ -156,12 +138,13 @@ describe("Biconomy Token Paymaster", function () { const priceFeedTxUsdc: any = await priceFeedUsdc.populateTransaction.getThePrice(); - await oracleAggregator.setTokenOracle( - token.address, - usdcMaticPriceFeedMock.address, - 18, - priceFeedTxUsdc.data, - true + const nativeOracle = await new MockOracle__factory(deployer).deploy( + 82843594, + "MATIC/USD" + ); + const tokenOracle = await new MockOracle__factory(deployer).deploy( + 100000000, + "USDC/USD" ); sampleTokenPaymaster = await new BiconomyTokenPaymaster__factory( @@ -172,6 +155,17 @@ describe("Biconomy Token Paymaster", function () { await offchainSigner.getAddress() ); + await sampleTokenPaymaster.setTokenOracle( + token.address, + tokenOracle.address, + nativeOracle.address, + true, + 172800 // 2 days + ); + + const priceResult = + await sampleTokenPaymaster.getTokenValueOfOneNativeToken(token.address); + smartWalletImp = await new BiconomyAccountImplementation__factory( deployer ).deploy(entryPoint.address); @@ -209,15 +203,17 @@ describe("Biconomy Token Paymaster", function () { describe("Token Payamster read methods and state checks", () => { it("Should parse data properly", async () => { + const numVU = ethers.BigNumber.from(MOCK_VALID_UNTIL); + const numVA = ethers.BigNumber.from(MOCK_VALID_AFTER); + const numER = ethers.BigNumber.from(MOCK_FX); const paymasterAndData = ethers.utils.hexConcat([ paymasterAddress, ethers.utils.hexlify(1).slice(0, 4), - encodePaymasterData( - token.address, - oracleAggregator.address, - MOCK_FX, - DEFAULT_FEE_MARKUP - ), + ethers.utils.hexZeroPad(ethers.utils.hexlify(numVU.toNumber()), 6), // 6 byte + ethers.utils.hexZeroPad(ethers.utils.hexlify(numVA.toNumber()), 6), // 6 byte + ethers.utils.hexZeroPad(token.address, 20), // 20 byte + ethers.utils.hexZeroPad(ethers.utils.hexlify(numER.toNumber()), 16), // 16 byte + ethers.utils.hexZeroPad(ethers.utils.hexlify(DEFAULT_FEE_MARKUP), 4), // 4 byte "0x" + "00".repeat(65), ]); @@ -230,7 +226,6 @@ describe("Biconomy Token Paymaster", function () { expect(res.validUntil).to.equal(ethers.BigNumber.from(MOCK_VALID_UNTIL)); expect(res.validAfter).to.equal(ethers.BigNumber.from(MOCK_VALID_AFTER)); expect(res.feeToken).to.equal(token.address); - expect(res.oracleAggregator).to.equal(oracleAggregator.address); expect(res.exchangeRate).to.equal(MOCK_FX); expect(res.signature).to.equal("0x" + "00".repeat(65)); }); @@ -304,23 +299,27 @@ describe("Biconomy Token Paymaster", function () { MOCK_VALID_UNTIL, MOCK_VALID_AFTER, token.address, - oracleAggregator.address, MOCK_FX, DEFAULT_FEE_MARKUP ); const sig = await offchainSigner.signMessage(arrayify(hash)); + const numVU = ethers.BigNumber.from(MOCK_VALID_UNTIL); + const numVA = ethers.BigNumber.from(MOCK_VALID_AFTER); + const numER = ethers.BigNumber.from(MOCK_FX); const userOp = await fillAndSign( { ...userOp1, paymasterAndData: ethers.utils.hexConcat([ paymasterAddress, ethers.utils.hexlify(1).slice(0, 4), - encodePaymasterData( - token.address, - oracleAggregator.address, - MOCK_FX, - DEFAULT_FEE_MARKUP - ), + ethers.utils.hexZeroPad(ethers.utils.hexlify(numVU.toNumber()), 6), // 6 byte + ethers.utils.hexZeroPad(ethers.utils.hexlify(numVA.toNumber()), 6), // 6 byte + ethers.utils.hexZeroPad(token.address, 20), // 20 byte + ethers.utils.hexZeroPad(ethers.utils.hexlify(numER.toNumber()), 16), // 16 byte + ethers.utils.hexZeroPad( + ethers.utils.hexlify(DEFAULT_FEE_MARKUP), + 4 + ), // 4 byte sig, ]), }, @@ -341,16 +340,22 @@ describe("Biconomy Token Paymaster", function () { .add(userOp.preVerificationGas) .mul(userOp.maxFeePerGas); - const tx = await entryPoint.handleOps( [userOp], await offchainSigner.getAddress() ); - - await tx.wait(); - const ev = await getUserOpEvent(entryPoint); - expect(ev.args.success).to.be.true; + const receipt = await tx.wait(); + + const event = parseEvent(receipt, UserOperationEventTopic); + + const eventLogsUserop = entryPoint.interface.decodeEventLog( + "UserOperationEvent", + event[0].data + ); + + // eslint-disable-next-line no-unused-expressions + expect(eventLogsUserop.success).to.be.true; await expect( entryPoint.handleOps([userOp], await offchainSigner.getAddress()) diff --git a/test/token-paymaster/oracle-aggregator-specs.ts b/test/token-paymaster/oracle-aggregator-specs.ts index 1ec4923..5af9f20 100644 --- a/test/token-paymaster/oracle-aggregator-specs.ts +++ b/test/token-paymaster/oracle-aggregator-specs.ts @@ -12,15 +12,14 @@ import { BiconomyAccountFactory__factory, BiconomyTokenPaymaster, BiconomyTokenPaymaster__factory, - ChainlinkOracleAggregator, - ChainlinkOracleAggregator__factory, - MockChainlinkOracleAggregator__factory, MockPriceFeed, MockStalePriceFeed__factory, MockStalePriceFeed, MockPriceFeed__factory, MockToken, - MockChainlinkOracleAggregator, + MockOracle__factory, + MockStaleOracle__factory, + MockStaleOracle, } from "../../typechain-types"; // Review: Could import from scw-contracts submodules to be consistent @@ -36,6 +35,7 @@ import { } from "@biconomy-devx/account-contracts-v2/dist/types"; import { arrayify, parseEther } from "ethers/lib/utils"; import { BigNumber, BigNumberish, Contract, Signer } from "ethers"; +import { getUserOpEvent, parseEvent } from "../utils/testUtils"; export const AddressZero = ethers.constants.AddressZero; @@ -45,38 +45,25 @@ const DEFAULT_FEE_MARKUP = 1100000; const MOCK_FX: BigNumberish = "977100"; // matic to usdc approx +const UserOperationEventTopic = + "0x49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f"; + export async function deployEntryPoint( provider = ethers.provider ): Promise { return new EntryPoint__factory(provider.getSigner()).deploy(); } -export const encodePaymasterData = ( - feeToken = ethers.constants.AddressZero, - oracleAggregator = ethers.constants.AddressZero, - exchangeRate: BigNumberish = ethers.constants.Zero, - priceMarkup: BigNumberish = ethers.constants.Zero -) => { - return ethers.utils.defaultAbiCoder.encode( - ["uint48", "uint48", "address", "address", "uint256", "uint32"], - [ - MOCK_VALID_UNTIL, - MOCK_VALID_AFTER, - feeToken, - oracleAggregator, - exchangeRate, - priceMarkup, - ] - ); -}; - -export async function getUserOpEvent(ep: EntryPoint) { - const [log] = await ep.queryFilter( - ep.filters.UserOperationEvent(), - await ethers.provider.getBlockNumber() - ); - return log; -} +// export const encodePaymasterData = ( +// feeToken = ethers.constants.AddressZero, +// exchangeRate: BigNumberish = ethers.constants.Zero, +// priceMarkup: BigNumberish = ethers.constants.Zero +// ) => { +// return ethers.utils.defaultAbiCoder.encode( +// ["uint48", "uint48", "address", "uint256", "uint32"], +// [MOCK_VALID_UNTIL, MOCK_VALID_AFTER, feeToken, exchangeRate, priceMarkup] +// ); +// }; export const encodeERC20Approval = ( account: BiconomyAccountImplementation, @@ -105,11 +92,11 @@ describe("Biconomy Token Paymaster", function () { let sampleTokenPaymaster: BiconomyTokenPaymaster; let mockPriceFeed: MockPriceFeed; - let oracleAggregator: ChainlinkOracleAggregator; - let staleOracleAggregator: MockChainlinkOracleAggregator; let staleMockPriceFeed: MockStalePriceFeed; let ecdsaModule: EcdsaOwnershipRegistryModule; let smartWalletImp: BiconomyAccountImplementation; + let staleFeed: MockStaleOracle; + let nativeOracle: MockOracle; let walletFactory: BiconomyAccountFactory; const abi = ethers.utils.defaultAbiCoder; @@ -122,64 +109,32 @@ describe("Biconomy Token Paymaster", function () { deployer = ethersSigner[0]; offchainSigner = ethersSigner[1]; depositorSigner = ethersSigner[2]; - walletOwner = deployer; // ethersSigner[3]; + walletOwner = deployer; // ethersSigner[0]; // const offchainSignerAddress = await deployer.getAddress(); const walletOwnerAddress = await walletOwner.getAddress(); - oracleAggregator = await new ChainlinkOracleAggregator__factory( - deployer - ).deploy(walletOwnerAddress); ecdsaModule = await new EcdsaOwnershipRegistryModule__factory( deployer ).deploy(); - staleOracleAggregator = await new MockChainlinkOracleAggregator__factory( - deployer - ).deploy(walletOwnerAddress); const MockToken = await ethers.getContractFactory("MockToken"); token = await MockToken.deploy(); - - await token.deployed(); - - const usdcMaticPriceFeedMock = await new MockPriceFeed__factory( - deployer - ).deploy(); - const priceFeedUsdc = await ethers.getContractAt( - "FeedInterface", - usdcMaticPriceFeedMock.address - ); - - const priceFeedTxUsdc: any = - await priceFeedUsdc.populateTransaction.getThePrice(); + await token.deployed(); - await oracleAggregator.setTokenOracle( - token.address, - usdcMaticPriceFeedMock.address, - 18, - priceFeedTxUsdc.data, - true + nativeOracle = await new MockOracle__factory(deployer).deploy( + 82843594, + "MATIC/USD" ); - - const stalePriceFeedMock = await new MockStalePriceFeed__factory( - deployer - ).deploy(); - - const priceFeedStale = await ethers.getContractAt( - "FeedInterface", - stalePriceFeedMock.address + const tokenOracle = await new MockOracle__factory(deployer).deploy( + 100000000, + "USDC/USD" ); - const priceFeedTxStale: any = - await priceFeedStale.populateTransaction.getThePrice(); - - await staleOracleAggregator.setTokenOracle( - token.address, - stalePriceFeedMock.address, - 18, - priceFeedTxStale.data, - true + staleFeed = await new MockStaleOracle__factory(deployer).deploy( + 100000000, + "USDC/USD" ); sampleTokenPaymaster = await new BiconomyTokenPaymaster__factory( @@ -190,6 +145,19 @@ describe("Biconomy Token Paymaster", function () { await offchainSigner.getAddress() ); + await sampleTokenPaymaster.setTokenOracle( + token.address, + tokenOracle.address, + nativeOracle.address, + true, + 172800 // 2 days + ); + + const priceResult = + await sampleTokenPaymaster.getTokenValueOfOneNativeToken(token.address); + + console.log("priceResult ", priceResult.toString()); + smartWalletImp = await new BiconomyAccountImplementation__factory( deployer ).deploy(entryPoint.address); @@ -235,136 +203,14 @@ describe("Biconomy Token Paymaster", function () { await entryPoint.depositTo(paymasterAddress, { value: parseEther("2") }); }); - describe("Oracle Aggregator returning unexpected values / using stale feed", () => { - it("Query price form good and bad aggregator", async () => { - const rate1 = await oracleAggregator.getTokenValueOfOneNativeToken( - token.address - ); - - await expect( - staleOracleAggregator.getTokenValueOfOneNativeToken(token.address) - ).to.be.reverted; - }); - }); - - describe("Token Payamster with good and bad oracle aggregator", () => { - it("succeed with fallback exchange rate in case price feed reverts", async () => { - const userSCW: any = BiconomyAccountImplementation__factory.connect( - walletAddress, - deployer - ); - - await token - .connect(deployer) - .transfer(walletAddress, ethers.utils.parseEther("100")); - - const owner = await walletOwner.getAddress(); - const AccountFactory = await ethers.getContractFactory( - "SmartAccountFactory" - ); - const ecdsaOwnershipSetupData = ecdsaModule.interface.encodeFunctionData( - "initForSmartAccount", - [owner] - ); - - const smartAccountDeploymentIndex = 0; - - const deploymentData = AccountFactory.interface.encodeFunctionData( - "deployCounterFactualAccount", - [ - ecdsaModule.address, - ecdsaOwnershipSetupData, - smartAccountDeploymentIndex, - ] - ); - - const userOp1 = await fillAndSign( - { - sender: walletAddress, - verificationGasLimit: 200000, - callData: encodeERC20Approval( - userSCW, - token, - paymasterAddress, - ethers.constants.MaxUint256 - ), - }, - walletOwner, - entryPoint, - "nonce" - ); - - const hash = await sampleTokenPaymaster.getHash( - userOp1, - ethers.utils.hexlify(1).slice(2, 4), - MOCK_VALID_UNTIL, - MOCK_VALID_AFTER, - token.address, - staleOracleAggregator.address, - MOCK_FX, - DEFAULT_FEE_MARKUP - ); - const sig = await offchainSigner.signMessage(arrayify(hash)); - const userOp = await fillAndSign( - { - ...userOp1, - paymasterAndData: ethers.utils.hexConcat([ - paymasterAddress, - ethers.utils.hexlify(1).slice(0, 4), - encodePaymasterData( - token.address, - staleOracleAggregator.address, - MOCK_FX, - DEFAULT_FEE_MARKUP - ), - sig, - ]), - }, - walletOwner, - entryPoint, - "nonce" - ); - - const signatureWithModuleAddress = ethers.utils.defaultAbiCoder.encode( - ["bytes", "address"], - [userOp.signature, ecdsaModule.address] - ); - - userOp.signature = signatureWithModuleAddress; - - const tx = await entryPoint.handleOps( - [userOp], - await offchainSigner.getAddress() - ); - const receipt = await tx.wait(); - - const ev = await getUserOpEvent(entryPoint); - expect(ev.args.success).to.be.true; - - const BiconomyTokenPaymaster = await ethers.getContractFactory( - "BiconomyTokenPaymaster" - ); - - const eventLogs = BiconomyTokenPaymaster.interface.decodeEventLog( - "TokenPaymasterOperation", - receipt.logs[3].data - ); - - // Confirming that it's using backup (external) exchange rate in case oracle aggregator / price feed is stale / anything goes wrong - expect(eventLogs.exchangeRate.toString()).to.be.equal(MOCK_FX); - - await expect( - entryPoint.handleOps([userOp], await offchainSigner.getAddress()) - ).to.be.reverted; - }); - + describe("Token Payamster with good and bad price feed", () => { it("succeed with exchange rate based on price feed in case everything goes well", async () => { const userSCW: any = BiconomyAccountImplementation__factory.connect( walletAddress, deployer ); - const rate1 = await oracleAggregator.getTokenValueOfOneNativeToken( + const rate1 = await sampleTokenPaymaster.getTokenValueOfOneNativeToken( token.address ); @@ -414,23 +260,27 @@ describe("Biconomy Token Paymaster", function () { MOCK_VALID_UNTIL, MOCK_VALID_AFTER, token.address, - oracleAggregator.address, MOCK_FX, DEFAULT_FEE_MARKUP ); const sig = await offchainSigner.signMessage(arrayify(hash)); + const numVU = ethers.BigNumber.from(MOCK_VALID_UNTIL); + const numVA = ethers.BigNumber.from(MOCK_VALID_AFTER); + const numER = ethers.BigNumber.from(MOCK_FX); const userOp = await fillAndSign( { ...userOp1, paymasterAndData: ethers.utils.hexConcat([ paymasterAddress, ethers.utils.hexlify(1).slice(0, 4), - encodePaymasterData( - token.address, - oracleAggregator.address, - MOCK_FX, - DEFAULT_FEE_MARKUP - ), + ethers.utils.hexZeroPad(ethers.utils.hexlify(numVU.toNumber()), 6), // 6 byte + ethers.utils.hexZeroPad(ethers.utils.hexlify(numVA.toNumber()), 6), // 6 byte + ethers.utils.hexZeroPad(token.address, 20), // 20 byte + ethers.utils.hexZeroPad(ethers.utils.hexlify(numER.toNumber()), 16), // 16 byte + ethers.utils.hexZeroPad( + ethers.utils.hexlify(DEFAULT_FEE_MARKUP), + 4 + ), // 4 byte sig, ]), }, @@ -452,8 +302,15 @@ describe("Biconomy Token Paymaster", function () { ); const receipt = await tx.wait(); - const ev = await getUserOpEvent(entryPoint); - expect(ev.args.success).to.be.true; + const event = parseEvent(receipt, UserOperationEventTopic); + + const eventLogsUserop = entryPoint.interface.decodeEventLog( + "UserOperationEvent", + event[0].data + ); + + // eslint-disable-next-line no-unused-expressions + expect(eventLogsUserop.success).to.be.true; const BiconomyTokenPaymaster = await ethers.getContractFactory( "BiconomyTokenPaymaster" @@ -472,40 +329,33 @@ describe("Biconomy Token Paymaster", function () { ).to.be.reverted; }); - it("succeed with fallback exchange rate in case oracle aggregator is 0 address", async () => { + it("succeed with fallback exchange rate in case price feed reverts", async () => { const userSCW: any = BiconomyAccountImplementation__factory.connect( walletAddress, deployer ); - await token - .connect(deployer) - .transfer(walletAddress, ethers.utils.parseEther("100")); - - const owner = await walletOwner.getAddress(); - const AccountFactory = await ethers.getContractFactory( - "SmartAccountFactory" - ); - const ecdsaOwnershipSetupData = ecdsaModule.interface.encodeFunctionData( - "initForSmartAccount", - [owner] + await sampleTokenPaymaster.setTokenOracle( + token.address, + staleFeed.address, + nativeOracle.address, + true, + 172800 // 2 days ); - const smartAccountDeploymentIndex = 0; + // this is not expected to revert + const feedResult = + await sampleTokenPaymaster.getTokenValueOfOneNativeToken(token.address); + expect(feedResult).to.be.equal(ethers.constants.Zero); - const deploymentData = AccountFactory.interface.encodeFunctionData( - "deployCounterFactualAccount", - [ - ecdsaModule.address, - ecdsaOwnershipSetupData, - smartAccountDeploymentIndex, - ] - ); + await token + .connect(deployer) + .transfer(walletAddress, ethers.utils.parseEther("100")); const userOp1 = await fillAndSign( { sender: walletAddress, - verificationGasLimit: 200000, + verificationGasLimit: 400000, callData: encodeERC20Approval( userSCW, token, @@ -524,23 +374,27 @@ describe("Biconomy Token Paymaster", function () { MOCK_VALID_UNTIL, MOCK_VALID_AFTER, token.address, - ethers.constants.AddressZero, MOCK_FX, DEFAULT_FEE_MARKUP ); const sig = await offchainSigner.signMessage(arrayify(hash)); + const numVU = ethers.BigNumber.from(MOCK_VALID_UNTIL); + const numVA = ethers.BigNumber.from(MOCK_VALID_AFTER); + const numER = ethers.BigNumber.from(MOCK_FX); const userOp = await fillAndSign( { ...userOp1, paymasterAndData: ethers.utils.hexConcat([ paymasterAddress, ethers.utils.hexlify(1).slice(0, 4), - encodePaymasterData( - token.address, - ethers.constants.AddressZero, - MOCK_FX, - DEFAULT_FEE_MARKUP - ), + ethers.utils.hexZeroPad(ethers.utils.hexlify(numVU.toNumber()), 6), // 6 byte + ethers.utils.hexZeroPad(ethers.utils.hexlify(numVA.toNumber()), 6), // 6 byte + ethers.utils.hexZeroPad(token.address, 20), // 20 byte + ethers.utils.hexZeroPad(ethers.utils.hexlify(numER.toNumber()), 16), // 16 byte + ethers.utils.hexZeroPad( + ethers.utils.hexlify(DEFAULT_FEE_MARKUP), + 4 + ), // 4 byte sig, ]), }, @@ -556,14 +410,23 @@ describe("Biconomy Token Paymaster", function () { userOp.signature = signatureWithModuleAddress; + console.log("userOp second case ", userOp); + const tx = await entryPoint.handleOps( [userOp], await offchainSigner.getAddress() ); const receipt = await tx.wait(); - const ev = await getUserOpEvent(entryPoint); - expect(ev.args.success).to.be.true; + const event = parseEvent(receipt, UserOperationEventTopic); + + const eventLogsUserop = entryPoint.interface.decodeEventLog( + "UserOperationEvent", + event[0].data + ); + + // eslint-disable-next-line no-unused-expressions + expect(eventLogsUserop.success).to.be.true; const BiconomyTokenPaymaster = await ethers.getContractFactory( "BiconomyTokenPaymaster" diff --git a/test/utils/testUtils.ts b/test/utils/testUtils.ts index 76b443d..ac6a700 100644 --- a/test/utils/testUtils.ts +++ b/test/utils/testUtils.ts @@ -6,6 +6,7 @@ import { parseEther, // solidityKeccak256, } from "ethers/lib/utils"; +import { TransactionReceipt } from "@ethersproject/providers"; import { BigNumber, // BigNumberish, @@ -23,6 +24,7 @@ import { // import { expect } from "chai"; // import { debugTransaction } from "./debugTx"; import { keccak256 } from "ethereumjs-util"; +import { EntryPoint } from "../../lib/account-abstraction/typechain"; export const AddressZero = ethers.constants.AddressZero; export const HashZero = ethers.constants.HashZero; @@ -60,6 +62,20 @@ export async function getBalance(address: string): Promise { return parseInt(balance.toString()); } +export async function getUserOpEvent(ep: EntryPoint) { + const [log] = await ep.queryFilter( + ep.filters.UserOperationEvent(), + await ethers.provider.getBlockNumber() + ); + return log; +} + +export function parseEvent(receipt: TransactionReceipt, topicName: string) { + return receipt.logs + .map((log) => log) + .filter((log) => log.topics[0] === topicName); +} + export function rethrow(): (e: Error) => void { const callerStack = new Error().stack ?.replace(/Error.*\n.*at.*\n/, "") diff --git a/test/utils/userOp.ts b/test/utils/userOp.ts index 0ebd833..4212802 100644 --- a/test/utils/userOp.ts +++ b/test/utils/userOp.ts @@ -18,6 +18,7 @@ import { EntryPoint } from "../../typechain-types"; import { UserOperation } from "./userOperation"; import { Create2Factory } from "../../src/Create2Factory"; import { SignerWithAddress } from "@nomiclabs/hardhat-ethers/signers"; +import { userInfo } from "os"; export function packUserOp(op: UserOperation, forSignature = true): string { if (forSignature) { @@ -317,6 +318,12 @@ export async function fillAndSign( op2.preVerificationGas = Number(op2.preVerificationGas) + extraPreVerificationGas; + // console.log("user op max fee per gas ", op2.maxFeePerGas.toString()); + // console.log( + // "user op max priority fee per gas ", + // op2.maxPriorityFeePerGas.toString() + // ); + const chainId = await provider!.getNetwork().then((net) => net.chainId); const message = arrayify(getUserOpHash(op2, entryPoint!.address, chainId)); diff --git a/yarn.lock b/yarn.lock index cfe90ff..9394f2a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7,147 +7,37 @@ resolved "https://registry.yarnpkg.com/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz#bd9154aec9983f77b3a034ecaa015c2e4201f6cf" integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA== -"@account-abstraction/contracts@^0.5.0": - version "0.5.0" - resolved "https://registry.yarnpkg.com/@account-abstraction/contracts/-/contracts-0.5.0.tgz#a089aee7b4c446251fbbce7df315bbf8f659e37f" - integrity sha512-CKyS9Zh5rcYUM+4B6TlaB9+THHzJ+6TY3tWF5QofqvFpqGNvIhF8ddy6wyCmqZw6TB74/yYv7cYD/RarVudfDg== - -"@account-abstraction/contracts@^0.6.0": +"@account-abstraction/contracts@0.6.0", "@account-abstraction/contracts@^0.6.0": version "0.6.0" resolved "https://registry.yarnpkg.com/@account-abstraction/contracts/-/contracts-0.6.0.tgz#7188a01839999226e6b2796328af338329543b76" integrity sha512-8ooRJuR7XzohMDM4MV34I12Ci2bmxfE9+cixakRL7lA4BAwJKQ3ahvd8FbJa9kiwkUPCUNtj+/zxDQWYYalLMQ== -"@account-abstraction/sdk@^0.5.0": - version "0.5.0" - resolved "https://registry.yarnpkg.com/@account-abstraction/sdk/-/sdk-0.5.0.tgz#fb306ecb1dba82e10a0277ab716890acf1d2d1ed" - integrity sha512-KuEG9UVl2kEhamevFmPJfqY5AQH4fRLnFhfWAdoqwxIZIuSyA8wfyzM9WKnDPSCaiApLvSzckjRwbs4dVoOp2Q== - dependencies: - "@account-abstraction/contracts" "^0.5.0" - "@account-abstraction/utils" "^0.5.0" - "@ethersproject/abstract-provider" "^5.7.0" - "@ethersproject/abstract-signer" "^5.7.0" - "@ethersproject/networks" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/providers" "^5.7.0" - "@types/debug" "^4.1.7" - debug "^4.3.4" - ethers "^5.7.0" - -"@account-abstraction/utils@^0.5.0": - version "0.5.0" - resolved "https://registry.yarnpkg.com/@account-abstraction/utils/-/utils-0.5.0.tgz#aa7925741048b1657a71d7f98ccaf3c187f99b4a" - integrity sha512-dgXguTn5WgFMmr3wQMdLGEoIMDcIJgzAv74YlHeb2D3Nyy1pByPArSb3eLOOcgxCJSJeqTscpO9P57uhNkkC4A== - dependencies: - "@account-abstraction/contracts" "^0.5.0" - "@ethersproject/abi" "^5.7.0" - "@ethersproject/providers" "^5.7.0" - "@openzeppelin/contracts" "^4.7.3" - debug "^4.3.4" - ethers "^5.7.0" - "@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== + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.23.5.tgz#9009b69a8c602293476ad598ff53e4562e15c244" + integrity sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA== dependencies: - "@babel/highlight" "^7.22.13" + "@babel/highlight" "^7.23.4" chalk "^2.4.2" -"@babel/compat-data@^7.22.6", "@babel/compat-data@^7.22.9": - version "7.23.2" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.23.2.tgz#6a12ced93455827037bfb5ed8492820d60fc32cc" - integrity sha512-0S9TQMmDHlqAZ2ITT95irXKfxN9bncq8ZCoJhun3nHL/lLUxd2NKBJYoNGWH7S0hz6fRQwWlAWn/ILM0C70KZQ== - -"@babel/helper-compilation-targets@^7.22.6": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz#0698fc44551a26cf29f18d4662d5bf545a6cfc52" - integrity sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw== - dependencies: - "@babel/compat-data" "^7.22.9" - "@babel/helper-validator-option" "^7.22.15" - browserslist "^4.21.9" - lru-cache "^5.1.1" - semver "^6.3.1" - -"@babel/helper-define-polyfill-provider@^0.4.3": - version "0.4.3" - resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.3.tgz#a71c10f7146d809f4a256c373f462d9bba8cf6ba" - integrity sha512-WBrLmuPP47n7PNwsZ57pqam6G/RGo1vw/87b0Blc53tZNGZ4x7YvZ6HgQe2vo1W/FR20OgjeZuGXzudPiXHFug== - dependencies: - "@babel/helper-compilation-targets" "^7.22.6" - "@babel/helper-plugin-utils" "^7.22.5" - debug "^4.1.1" - lodash.debounce "^4.0.8" - resolve "^1.14.2" - -"@babel/helper-module-imports@^7.22.15": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz#16146307acdc40cc00c3b2c647713076464bdbf0" - integrity sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w== - dependencies: - "@babel/types" "^7.22.15" - -"@babel/helper-plugin-utils@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz#dd7ee3735e8a313b9f7b05a773d892e88e6d7295" - integrity sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg== - -"@babel/helper-string-parser@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz#533f36457a25814cf1df6488523ad547d784a99f" - integrity sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw== - "@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/helper-validator-option@^7.22.15": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.22.15.tgz#694c30dfa1d09a6534cdfcafbe56789d36aba040" - integrity sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA== - -"@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== +"@babel/highlight@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.23.4.tgz#edaadf4d8232e1a961432db785091207ead0621b" + integrity sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A== dependencies: "@babel/helper-validator-identifier" "^7.22.20" chalk "^2.4.2" js-tokens "^4.0.0" -"@babel/plugin-transform-runtime@^7.5.5": - version "7.23.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.23.2.tgz#c956a3f8d1aa50816ff6c30c6288d66635c12990" - integrity sha512-XOntj6icgzMS58jPVtQpiuF6ZFWxQiJavISGx5KGjRj+3gqZr8+N6Kx+N9BApWzgS+DOjIZfXXj0ZesenOWDyA== - dependencies: - "@babel/helper-module-imports" "^7.22.15" - "@babel/helper-plugin-utils" "^7.22.5" - babel-plugin-polyfill-corejs2 "^0.4.6" - babel-plugin-polyfill-corejs3 "^0.8.5" - babel-plugin-polyfill-regenerator "^0.5.3" - semver "^6.3.1" - -"@babel/runtime@^7.5.5": - 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" - -"@babel/types@^7.22.15": - version "7.23.0" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.23.0.tgz#8c1f020c9df0e737e4e247c0619f58c68458aaeb" - integrity sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg== - dependencies: - "@babel/helper-string-parser" "^7.22.5" - "@babel/helper-validator-identifier" "^7.22.20" - to-fast-properties "^2.0.0" - -"@biconomy-devx/account-contracts-v2@^2.0.2": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@biconomy-devx/account-contracts-v2/-/account-contracts-v2-2.0.2.tgz#306ef4de9259fb70e6a556186184a3a3b2561205" - integrity sha512-sBXIFWbsxzRTgjFKJ0sBDssHiFxThU1efKolEn6nvHkN5dvXpzwKWgD15ltgKh1XN7S0NRWLhn/myWMy6kGPGw== +"@biconomy-devx/account-contracts-v2@^2.0.3": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@biconomy-devx/account-contracts-v2/-/account-contracts-v2-2.0.3.tgz#df8ee507b3c9fa4db3a8f6d729fe2dc97057be06" + integrity sha512-tv5KfzkyEwfuV+Hcl25/KjR2mXupPDRt55hTPMTGUagaAXjO9XNmQm5Ac1D0GMDN8ZHshAd6ytSRADLYhKZsLA== dependencies: "@account-abstraction/contracts" "^0.6.0" "@ethersproject/abstract-signer" "^5.6.2" @@ -156,44 +46,6 @@ dotenv "^16.0.3" ethereumjs-util "^7.1.0" -"@biconomy/account-contracts@^2.0.0": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@biconomy/account-contracts/-/account-contracts-2.0.1.tgz#5e5d6ccbc7f4d43da50c17e09ae0387a95f9aa04" - integrity sha512-GuSTy0zeDq5Jhe7d2PttltVu8fc6EpLtd/RWkWXRYF9Gjsn3ztr0I7a2eK0w0I7LgB67/wmWiMcGZfrMwq0m1A== - dependencies: - "@account-abstraction/contracts" "^0.6.0" - "@account-abstraction/sdk" "^0.5.0" - "@chainlink/contracts" "^0.4.1" - "@ethersproject/abstract-signer" "^5.6.2" - "@ethersproject/constants" "^5.6.1" - "@openzeppelin/contracts" "4.8.1" - "@openzeppelin/contracts-upgradeable" "4.8.1" - "@typechain/hardhat" "^2.3.0" - "@types/mocha" "^9.0.0" - chai-as-promised "^7.1.1" - chai-string "^1.5.0" - eth-gas-reporter "^0.2.24" - ethereumjs-util "^7.1.0" - ethereumjs-wallet "^1.0.1" - ethers "^5.6.8" - ganache "^7.1.0" - ganache-cli "^6.12.2" - hardhat "^2.9.5" - hardhat-deploy "^0.9.3" - hardhat-deploy-ethers "^0.3.0-beta.11" - hardhat-gas-reporter "^1.0.7" - solc "^0.8.15" - solidity-bytes-utils "^0.8.0" - source-map-support "^0.5.19" - typescript "^4.3.5" - -"@chainlink/contracts@^0.4.1": - version "0.4.2" - resolved "https://registry.yarnpkg.com/@chainlink/contracts/-/contracts-0.4.2.tgz#2928a35e8da94664b8ffeb8f5a54b1a3f14d5b3f" - integrity sha512-wVI/KZ9nIH0iqoebVxYrZfNVWO23vwds1UrHdbF+S0JwyixtT+54xYGlot723jCrAeBeQHsDRQXnEhhbUEHpgQ== - dependencies: - "@eth-optimism/contracts" "^0.5.21" - "@chainlink/contracts@^0.6.0": version "0.6.1" resolved "https://registry.yarnpkg.com/@chainlink/contracts/-/contracts-0.6.1.tgz#8842b57e755793cbdbcbc45277fb5d179c993e19" @@ -259,10 +111,10 @@ resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.10.0.tgz#548f6de556857c8bb73bbee70c35dc82a2e74d63" integrity sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA== -"@eslint/eslintrc@^2.1.3": - version "2.1.3" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.1.3.tgz#797470a75fe0fbd5a53350ee715e85e87baff22d" - integrity sha512-yZzuIG+jnVu6hNSzFEN07e8BxF3uAzYtQb6uDkaYZLo6oYZDCq454c5kB8zxnzfCYyP4MIuyBn10L0DqwujTmA== +"@eslint/eslintrc@^2.1.4": + version "2.1.4" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.1.4.tgz#388a269f0f25c1b6adc317b5a2c55714894c70ad" + integrity sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ== dependencies: ajv "^6.12.4" debug "^4.3.2" @@ -274,10 +126,10 @@ minimatch "^3.1.2" strip-json-comments "^3.1.1" -"@eslint/js@8.53.0": - version "8.53.0" - resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.53.0.tgz#bea56f2ed2b5baea164348ff4d5a879f6f81f20d" - integrity sha512-Kn7K8dx/5U6+cT1yEhpX1w4PCSg0M+XyRILPgvwcEBjerFWCwQj5sbr3/VmxqV0JGHCBCzyd6LxypEuehypY1w== +"@eslint/js@8.56.0": + version "8.56.0" + resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.56.0.tgz#ef20350fec605a7f7035a01764731b2de0f3782b" + integrity sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A== "@eth-optimism/contracts@^0.5.21": version "0.5.40" @@ -376,14 +228,6 @@ 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" @@ -392,7 +236,7 @@ crc-32 "^1.2.0" ethereumjs-util "^7.1.3" -"@ethereumjs/common@^2.4.0", "@ethereumjs/common@^2.5.0", "@ethereumjs/common@^2.6.0", "@ethereumjs/common@^2.6.4", "@ethereumjs/common@^2.6.5": +"@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== @@ -416,14 +260,6 @@ 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" @@ -432,7 +268,7 @@ "@ethereumjs/common" "^2.6.0" ethereumjs-util "^7.1.3" -"@ethereumjs/tx@^3.3.0", "@ethereumjs/tx@^3.4.0", "@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== @@ -467,7 +303,7 @@ merkle-patricia-tree "^4.2.2" rustbn.js "~0.2.0" -"@ethersproject/abi@5.7.0", "@ethersproject/abi@^5.0.9", "@ethersproject/abi@^5.1.2", "@ethersproject/abi@^5.4.0", "@ethersproject/abi@^5.6.3", "@ethersproject/abi@^5.7.0": +"@ethersproject/abi@5.7.0", "@ethersproject/abi@^5.0.9", "@ethersproject/abi@^5.1.2", "@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== @@ -495,7 +331,7 @@ "@ethersproject/transactions" "^5.7.0" "@ethersproject/web" "^5.7.0" -"@ethersproject/abstract-signer@5.7.0", "@ethersproject/abstract-signer@^5.4.1", "@ethersproject/abstract-signer@^5.6.2", "@ethersproject/abstract-signer@^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== @@ -506,7 +342,7 @@ "@ethersproject/logger" "^5.7.0" "@ethersproject/properties" "^5.7.0" -"@ethersproject/address@5.7.0", "@ethersproject/address@^5.0.2", "@ethersproject/address@^5.4.0", "@ethersproject/address@^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== @@ -532,7 +368,7 @@ "@ethersproject/bytes" "^5.7.0" "@ethersproject/properties" "^5.7.0" -"@ethersproject/bignumber@5.7.0", "@ethersproject/bignumber@^5.4.1", "@ethersproject/bignumber@^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== @@ -541,21 +377,21 @@ "@ethersproject/logger" "^5.7.0" bn.js "^5.2.1" -"@ethersproject/bytes@5.7.0", "@ethersproject/bytes@^5.4.0", "@ethersproject/bytes@^5.7.0": +"@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.4.0", "@ethersproject/constants@^5.6.1", "@ethersproject/constants@^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.4.1", "@ethersproject/contracts@^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== @@ -658,7 +494,7 @@ dependencies: "@ethersproject/logger" "^5.7.0" -"@ethersproject/providers@5.7.2", "@ethersproject/providers@^5.4.4", "@ethersproject/providers@^5.7.0", "@ethersproject/providers@^5.7.1", "@ethersproject/providers@^5.7.2": +"@ethersproject/providers@5.7.2", "@ethersproject/providers@^5.7.0", "@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== @@ -721,7 +557,7 @@ elliptic "6.5.4" hash.js "1.1.7" -"@ethersproject/solidity@5.7.0", "@ethersproject/solidity@^5.4.0", "@ethersproject/solidity@^5.7.0": +"@ethersproject/solidity@5.7.0", "@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== @@ -742,7 +578,7 @@ "@ethersproject/constants" "^5.7.0" "@ethersproject/logger" "^5.7.0" -"@ethersproject/transactions@5.7.0", "@ethersproject/transactions@^5.4.0", "@ethersproject/transactions@^5.6.2", "@ethersproject/transactions@^5.7.0": +"@ethersproject/transactions@5.7.0", "@ethersproject/transactions@^5.7.0": version "5.7.0" resolved "https://registry.yarnpkg.com/@ethersproject/transactions/-/transactions-5.7.0.tgz#91318fc24063e057885a6af13fdb703e1f993d3b" integrity sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ== @@ -766,7 +602,7 @@ "@ethersproject/constants" "^5.7.0" "@ethersproject/logger" "^5.7.0" -"@ethersproject/wallet@5.7.0", "@ethersproject/wallet@^5.4.0", "@ethersproject/wallet@^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== @@ -810,9 +646,9 @@ "@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== + version "2.1.0" + resolved "https://registry.yarnpkg.com/@fastify/busboy/-/busboy-2.1.0.tgz#0709e9f4cb252351c609c6e6d8d6779a8d25edff" + integrity sha512-+KpH+QxZU7O4675t3mnkQKcZZg56u+K/Ct2K+N2AZYNVK8kyeo/bI18tI8aPm3tvNNRyTWfj6s5tnGNlcbQRsA== "@ganache/ethereum-address@0.1.4": version "0.1.4" @@ -877,12 +713,12 @@ "@trufflesuite/bigint-buffer" "1.1.9" "@humanwhocodes/config-array@^0.11.13": - version "0.11.13" - resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.13.tgz#075dc9684f40a531d9b26b0822153c1e832ee297" - integrity sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ== + version "0.11.14" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.14.tgz#d78e481a039f7566ecc9660b4ea7fe6b1fec442b" + integrity sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg== dependencies: - "@humanwhocodes/object-schema" "^2.0.1" - debug "^4.1.1" + "@humanwhocodes/object-schema" "^2.0.2" + debug "^4.3.1" minimatch "^3.0.5" "@humanwhocodes/module-importer@^1.0.1": @@ -890,10 +726,10 @@ resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== -"@humanwhocodes/object-schema@^2.0.1": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz#e5211452df060fa8522b55c7b3c0c4d1981cb044" - integrity sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw== +"@humanwhocodes/object-schema@^2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz#d9fae00a2d5cb40f92cfe64b47ad749fbc38f917" + integrity sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw== "@jridgewell/resolve-uri@^3.0.3": version "3.1.1" @@ -913,25 +749,7 @@ "@jridgewell/resolve-uri" "^3.0.3" "@jridgewell/sourcemap-codec" "^1.4.10" -"@mean-finance/deterministic-factory@1.4.3": - version "1.4.3" - resolved "https://registry.yarnpkg.com/@mean-finance/deterministic-factory/-/deterministic-factory-1.4.3.tgz#4e2c2f02ec336ff4cdf18e85bd575280d817f2a7" - integrity sha512-nnYJm27IyubCrEpeyuRW7fTL5sJ6wqFyhM78xw0fEuFegYK6Dqs3qkE66lXl25QZyby5VD6q4M6viyEnYSNumQ== - dependencies: - "@openzeppelin/contracts" "4.6.0" - "@rari-capital/solmate" "6.2.0" - -"@mean-finance/uniswap-v3-oracle@^1.0.3": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@mean-finance/uniswap-v3-oracle/-/uniswap-v3-oracle-1.0.3.tgz#f67ddc84827e50311b0e340947c885da12b99149" - integrity sha512-kAGXfl3Sv0jSzmCkkQ6TcUf7scEp/qorhKyOrDgOLwWiAmMEZgdDile/zJ05UQcvpSG7pSTVus6ZAnhiFOfw8w== - dependencies: - "@mean-finance/deterministic-factory" "1.4.3" - "@openzeppelin/contracts" "3.4.0" - "@uniswap/v3-core" "1.0.1" - "@uniswap/v3-periphery" "1.4.1" - -"@metamask/eth-sig-util@4.0.1", "@metamask/eth-sig-util@^4.0.0": +"@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== @@ -942,47 +760,22 @@ tweetnacl "^1.0.3" tweetnacl-util "^0.15.1" -"@metamask/safe-event-emitter@^2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@metamask/safe-event-emitter/-/safe-event-emitter-2.0.0.tgz#af577b477c683fad17c619a78208cede06f9605c" - integrity sha512-/kSXhY692qiV1MXu6EeOZvg5nECLclxNXcKCxJ3cXQgYuRymRHpdx/t7JXfsK+JLjwA1e1c1/SBrlQYpusC29Q== - -"@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== +"@noble/curves@1.3.0", "@noble/curves@~1.3.0": + version "1.3.0" + resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.3.0.tgz#01be46da4fd195822dab821e72f71bf4aeec635e" + integrity sha512-t01iSXPuN+Eqzb4eBX0S5oubSqXbK/xXa1Ne18Hj8f9pStxztHCE2gfboSp/dZRLSqfuLpRK2nDXDK+W9puocA== dependencies: - "@noble/hashes" "1.3.1" - -"@noble/hashes@1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.1.2.tgz#e9e035b9b166ca0af657a7848eb2718f0f22f183" - integrity sha512-KYRCASVTv6aeUi1tsF8/vpyR7zpfs3FUzy2Jqm+MU+LmUKhQ0y2FpfwqkCcxSg2ua4GALJd8k2R76WxwZGbQpA== + "@noble/hashes" "1.3.3" "@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.1.1": - version "1.1.5" - resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.1.5.tgz#1a0377f3b9020efe2fae03290bd2a12140c95c11" - integrity sha512-LTMZiiLc+V4v1Yi16TD6aX2gmtKszNye0pQgbaLqkvhIqP7nVsSaJsWloGQjJfJ8offaoP5GtX3yY5swbcJxxQ== - -"@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.6.3", "@noble/secp256k1@~1.6.0": - version "1.6.3" - resolved "https://registry.yarnpkg.com/@noble/secp256k1/-/secp256k1-1.6.3.tgz#7eed12d9f4404b416999d0c87686836c4c5c9b94" - integrity sha512-T04e4iTurVy7I8Sw4+c5OSN9/RkPlo1uKxAomtxQNLq8j1uPAqnsqG1bqvY3Jv7c13gyr6dui0zmh/I3+f/JaQ== +"@noble/hashes@1.3.3", "@noble/hashes@~1.3.2": + version "1.3.3" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.3.tgz#39908da56a4adc270147bb07968bf3b16cfe1699" + integrity sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA== "@noble/secp256k1@1.7.1", "@noble/secp256k1@~1.7.0": version "1.7.1" @@ -1155,7 +948,7 @@ deep-eql "^4.0.1" ordinal "^1.0.3" -"@nomicfoundation/hardhat-foundry@^1.0.0": +"@nomicfoundation/hardhat-foundry@^1.1.1": version "1.1.1" resolved "https://registry.yarnpkg.com/@nomicfoundation/hardhat-foundry/-/hardhat-foundry-1.1.1.tgz#db72b1f33f9cfaecc27e67f69ad436f8710162d6" integrity sha512-cXGCBHAiXas9Pg9MhMOpBVQCkWRYoRFG7GJJAph+sdQsfd22iRs5U5Vs9XmpGEQd1yEvYISQZMeE68Nxj65iUQ== @@ -1163,9 +956,9 @@ chalk "^2.4.2" "@nomicfoundation/hardhat-network-helpers@^1.0.8": - version "1.0.9" - resolved "https://registry.yarnpkg.com/@nomicfoundation/hardhat-network-helpers/-/hardhat-network-helpers-1.0.9.tgz#767449e8a2acda79306ac84626117583d95d25aa" - integrity sha512-OXWCv0cHpwLUO2u7bFxBna6dQtCC2Gg/aN/KtJLO7gmuuA28vgmVKYFRCDUqrbjujzgfwQ2aKyZ9Y3vSmDqS7Q== + version "1.0.10" + resolved "https://registry.yarnpkg.com/@nomicfoundation/hardhat-network-helpers/-/hardhat-network-helpers-1.0.10.tgz#c61042ceb104fdd6c10017859fdef6529c1d6585" + integrity sha512-R35/BMBlx7tWN5V6d/8/19QCwEmIdbnA4ZrsuXgvs8i2qFx5i7h6mH5pBS4Pwi4WigLH+upl6faYusrNPuzMrQ== dependencies: ethereumjs-util "^7.1.4" @@ -1246,9 +1039,9 @@ integrity sha512-YhzPdzb612X591FOe68q+qXVXGG2ANZRvDo0RRUtimev85rCrAlv/TLMEZw5c+kq9AbzocLTVX/h2jVIFPL9Xg== "@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== + version "3.1.8" + resolved "https://registry.yarnpkg.com/@nomiclabs/hardhat-etherscan/-/hardhat-etherscan-3.1.8.tgz#3c12ee90b3733e0775e05111146ef9418d4f5a38" + integrity sha512-v5F6IzQhrsjHh6kQz4uNrym49brK9K5bYCq2zQZ729RYRaifI9hHbtmK+KkIVevfhut7huQFEQ77JLRMAzWYjQ== dependencies: "@ethersproject/abi" "^5.1.2" "@ethersproject/address" "^5.0.2" @@ -1266,47 +1059,17 @@ resolved "https://registry.yarnpkg.com/@nomiclabs/hardhat-waffle/-/hardhat-waffle-2.0.6.tgz#d11cb063a5f61a77806053e54009c40ddee49a54" integrity sha512-+Wz0hwmJGSI17B+BhU/qFRZ1l6/xMW82QGXE/Gi+WTmwgJrQefuBs1lIf7hzQ1hLk6hpkvb/zwcNkpVKRYTQYg== -"@openzeppelin/contracts-upgradeable@4.8.1": - version "4.8.1" - resolved "https://registry.yarnpkg.com/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-4.8.1.tgz#363f7dd08f25f8f77e16d374350c3d6b43340a7a" - integrity sha512-1wTv+20lNiC0R07jyIAbHU7TNHKRwGiTGRfiNnA8jOWjKT98g5OgLpYWOi40Vgpk8SPLA9EvfJAbAeIyVn+7Bw== - "@openzeppelin/contracts-upgradeable@^4.7.3": - version "4.9.3" - resolved "https://registry.yarnpkg.com/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-4.9.3.tgz#ff17a80fb945f5102571f8efecb5ce5915cc4811" - integrity sha512-jjaHAVRMrE4UuZNfDwjlLGDxTHWIOwTJS2ldnc278a0gevfXfPr8hxKEVBGFBE96kl2G3VHDZhUimw/+G3TG2A== + version "4.9.5" + resolved "https://registry.yarnpkg.com/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-4.9.5.tgz#572b5da102fc9be1d73f34968e0ca56765969812" + integrity sha512-f7L1//4sLlflAN7fVzJLoRedrf5Na3Oal5PZfIq55NFcVZ90EpV1q5xOvL4lFvg3MNICSDr2hH0JUBxwlxcoPg== "@openzeppelin/contracts-v0.7@npm:@openzeppelin/contracts@v3.4.2": version "3.4.2" resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-3.4.2.tgz#d81f786fda2871d1eb8a8c5a73e455753ba53527" integrity sha512-z0zMCjyhhp4y7XKAcDAi3Vgms4T2PstwBdahiO0+9NaGICQKjynK3wduSRplTgk4LXmoO1yfDGO5RbjKYxtuxA== -"@openzeppelin/contracts@3.4.0": - version "3.4.0" - resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-3.4.0.tgz#9a1669ad5f9fdfb6e273bb5a4fed10cb4cc35eb0" - integrity sha512-qh+EiHWzfY/9CORr+eRUkeEUP1WiFUcq3974bLHwyYzLBUtK6HPaMkIUHi74S1rDTZ0sNz42DwPc5A4IJvN3rg== - -"@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.6.0": - version "4.6.0" - resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.6.0.tgz#c91cf64bc27f573836dba4122758b4743418c1b3" - integrity sha512-8vi4d50NNya/bQqCmaVzvHNmwHvS0OBKb7HNtuNwEE3scXWrP31fKQoGxNMT+KbzmrNZzatE3QK5p2gFONI/hg== - -"@openzeppelin/contracts@4.7.0": - version "4.7.0" - resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.7.0.tgz#3092d70ea60e3d1835466266b1d68ad47035a2d5" - integrity sha512-52Qb+A1DdOss8QvJrijYYPSf32GUg2pGaG/yCxtaA3cu4jduouTdg4XZSMLW9op54m1jH7J8hoajhHKOPsoJFw== - -"@openzeppelin/contracts@4.8.1": - version "4.8.1" - resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.8.1.tgz#709cfc4bbb3ca9f4460d60101f15dac6b7a2d5e4" - integrity sha512-xQ6eUZl+RDyb/FiZe1h+U7qr/f4p/SrTSQcTPH2bjur3C5DbuW/zFgCU/b1P/xcIaEqJep+9ju4xDRi3rmChdQ== - -"@openzeppelin/contracts@^4.7.3", "@openzeppelin/contracts@^4.8.2": +"@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== @@ -1316,25 +1079,6 @@ resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.3.3.tgz#ff6ee919fc2a1abaf72b22814bfb72ed129ec137" integrity sha512-tDBopO1c98Yk7Cv/PZlHqrvtVjlgK5R4J6jxLwoO7qxK4xqOiZG+zSkIvGFpPZ0ikc3QOED3plgdqjgNTnBc7g== -"@pimlico/erc20-paymaster@^0.0.1": - version "0.0.1" - resolved "https://registry.yarnpkg.com/@pimlico/erc20-paymaster/-/erc20-paymaster-0.0.1.tgz#d9c827f3f6c2c553870597a5dc3e1398967d7790" - integrity sha512-L7xJce76sxUK88lFqKI0J1BiQRa9cgj233Qke3rEOCzncG8Gl4Lx+/89/jWiqNbdyfHtjD4Dn2PKLyBj27ypxg== - dependencies: - "@account-abstraction/contracts" "^0.6.0" - "@account-abstraction/utils" "^0.5.0" - "@ethersproject/abstract-provider" "^5.7.0" - "@ethersproject/providers" "^5.7.2" - "@openzeppelin/contracts" "^4.8.2" - ethers "^5.7.2" - hardhat "^2.13.0" - solady "^0.0.90" - -"@rari-capital/solmate@6.2.0": - version "6.2.0" - resolved "https://registry.yarnpkg.com/@rari-capital/solmate/-/solmate-6.2.0.tgz#4f70dc236606c27ec2cb1b4261dd830235d01fe4" - integrity sha512-g94F+Ra9ixyJyNgvnOIufNjUz488uEG0nxIEEtJ7+g+tA1XGUupRB2kB5b+VO7WYO26RNOVD2fW6xE4e14iWpg== - "@resolver-engine/core@^0.3.3": version "0.3.3" resolved "https://registry.yarnpkg.com/@resolver-engine/core/-/core-0.3.3.tgz#590f77d85d45bc7ecc4e06c654f41345db6ca967" @@ -1372,19 +1116,10 @@ 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.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.1.0.tgz#dea45875e7fbc720c2b4560325f1cf5d2246d95b" - integrity sha512-ftTW3kKX54YXLCxH6BB7oEEoJfoE2pIgw7MINKAs5PsS6nqKPuKk1haTF/EuHmYqG330t5GSrdmtRuHaY1a62Q== - dependencies: - "@noble/hashes" "~1.1.1" - "@noble/secp256k1" "~1.6.0" - "@scure/base" "~1.1.0" +"@scure/base@~1.1.0", "@scure/base@~1.1.4": + version "1.1.5" + resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.5.tgz#1d85d17269fe97694b9c592552dd9e5e33552157" + integrity sha512-Brj9FiG2W1MRQSTB212YVPRrcbjkv48FoZi/u4l/zds/ieRrqsh7aUf6CLwkAq61oKXr/ZlTzlY66gLIj3TFTQ== "@scure/bip32@1.1.5": version "1.1.5" @@ -1395,22 +1130,14 @@ "@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.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.1.0.tgz#92f11d095bae025f166bef3defcc5bf4945d419a" - integrity sha512-pwrPOS16VeTKg98dYXQyIjJEcWfz7/1YJIwxUEPFfQPtc86Ym/1sVgQ2RLoD43AazMk2l/unK4ITySSpW2+82w== +"@scure/bip32@1.3.3": + version "1.3.3" + resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.3.3.tgz#a9624991dc8767087c57999a5d79488f48eae6c8" + integrity sha512-LJaN3HwRbfQK0X1xFSi0Q9amqOgzQnnDngIt+ZlsBC3Bm7/nE7K0kwshZHyaru79yIVRv/e1mQAjZyuZG6jOFQ== dependencies: - "@noble/hashes" "~1.1.1" - "@scure/base" "~1.1.0" + "@noble/curves" "~1.3.0" + "@noble/hashes" "~1.3.2" + "@scure/base" "~1.1.4" "@scure/bip39@1.1.1": version "1.1.1" @@ -1420,13 +1147,13 @@ "@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== +"@scure/bip39@1.2.2": + version "1.2.2" + resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.2.2.tgz#f3426813f4ced11a47489cbcf7294aa963966527" + integrity sha512-HYf9TUXG80beW+hGAt3TRM8wU6pQoYur9iNypTROm42dorCGmLnFe3eWjz3gOq6G62H2WRh0FCzAR1PI+29zIA== dependencies: - "@noble/hashes" "~1.3.0" - "@scure/base" "~1.1.0" + "@noble/hashes" "~1.3.2" + "@scure/base" "~1.1.4" "@sentry/core@5.30.0": version "5.30.0" @@ -1496,11 +1223,6 @@ "@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" @@ -1509,52 +1231,21 @@ 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== + version "0.16.2" + resolved "https://registry.yarnpkg.com/@solidity-parser/parser/-/parser-0.16.2.tgz#42cb1e3d88b3e8029b0c9befff00b634cd92d2fa" + integrity sha512-PI9NfoA3P8XK2VBkK5oIfRgKDsicwDZfkVq9ZTBCQYGOP1N2owgY2dyLGyU5/J/hQs8KRk55kdmvTLjy3Mu3vg== 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/hdwallet-provider@latest": - version "2.1.15" - resolved "https://registry.yarnpkg.com/@truffle/hdwallet-provider/-/hdwallet-provider-2.1.15.tgz#fbf8e19d112db81b109ebc06ac6d9d42124b512c" - integrity sha512-I5cSS+5LygA3WFzru9aC5+yDXVowEEbLCx0ckl/RqJ2/SCiYXkzYlR5/DjjDJuCtYhivhrn2RP9AheeFlRF+qw== - dependencies: - "@ethereumjs/common" "^2.4.0" - "@ethereumjs/tx" "^3.3.0" - "@metamask/eth-sig-util" "4.0.1" - "@truffle/hdwallet" "^0.1.4" - "@types/ethereum-protocol" "^1.0.0" - "@types/web3" "1.0.20" - "@types/web3-provider-engine" "^14.0.0" - ethereum-cryptography "1.1.2" - ethereum-protocol "^1.0.1" - ethereumjs-util "^7.1.5" - web3 "1.10.0" - web3-provider-engine "16.0.3" +"@solidity-parser/parser@^0.17.0": + version "0.17.0" + resolved "https://registry.yarnpkg.com/@solidity-parser/parser/-/parser-0.17.0.tgz#52a2fcc97ff609f72011014e4c5b485ec52243ef" + integrity sha512-Nko8R0/kUo391jsEHHxrGM07QFdnPGvlmox4rmH0kNiNAashItAilhy4Mv4pK5gQmW5f4sXAF58fwJbmlkGcVw== -"@truffle/hdwallet@^0.1.4": - version "0.1.4" - resolved "https://registry.yarnpkg.com/@truffle/hdwallet/-/hdwallet-0.1.4.tgz#eeb21163d9e295692a0ba2fa848cc7b5a29b0ded" - integrity sha512-D3SN0iw3sMWUXjWAedP6RJtopo9qQXYi80inzbtcsoso4VhxFxCwFvCErCl4b27AEJ9pkAtgnxEFRaSKdMmi1Q== - dependencies: - ethereum-cryptography "1.1.2" - keccak "3.0.2" - secp256k1 "4.0.3" +"@solidity-parser/parser@^0.18.0": + version "0.18.0" + resolved "https://registry.yarnpkg.com/@solidity-parser/parser/-/parser-0.18.0.tgz#8e77a02a09ecce957255a2f48c9a7178ec191908" + integrity sha512-yfORGUIPgLck41qyN7nbwJRAx17/jAIXCTanHOJZhB6PJ1iAk/84b/xlsVKFSyNyLXIj0dhppoE0+CRws7wlzA== "@trufflesuite/bigint-buffer@1.1.10": version "1.1.10" @@ -1608,13 +1299,6 @@ lodash "^4.17.15" ts-essentials "^7.0.1" -"@typechain/hardhat@^2.3.0": - 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" - "@typechain/hardhat@^6.1.5": version "6.1.6" resolved "https://registry.yarnpkg.com/@typechain/hardhat/-/hardhat-6.1.6.tgz#1a749eb35e5054c80df531cf440819cb347c62ea" @@ -1627,13 +1311,6 @@ resolved "https://registry.yarnpkg.com/@types/abstract-leveldown/-/abstract-leveldown-7.2.5.tgz#db2cf364c159fb1f12be6cd3549f56387eaf8d73" integrity sha512-/2B0nQF4UdupuxeKTJA2+Rj1D+uDemo6P4kMwKCpbfpnzeVaWSELTsAw4Lxn3VJD6APtRrZOCuYo+4nHUQfTfg== -"@types/bn.js@*", "@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/bn.js@^4.11.3": version "4.11.6" resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-4.11.6.tgz#c306c70d9358aaea33cd4eda092a742b9505967c" @@ -1641,15 +1318,12 @@ 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== +"@types/bn.js@^5.1.0": + 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/http-cache-semantics" "*" - "@types/keyv" "^3.1.4" "@types/node" "*" - "@types/responselike" "^1.0.0" "@types/chai-as-promised@^7.1.3": version "7.1.8" @@ -1659,9 +1333,9 @@ "@types/chai" "*" "@types/chai@*", "@types/chai@^4.3.4": - version "4.3.10" - resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.3.10.tgz#2ad2959d1767edee5b0e4efb1a0cd2b500747317" - integrity sha512-of+ICnbqjmFCiixUnqRulbylyXQrPqIGf/B3Jax1wIF3DvSheysQxAWvqHhZiW3IQrycvokcLcFQlveGp+vyNg== + version "4.3.11" + resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.3.11.tgz#e95050bf79a932cb7305dd130254ccdf9bde671c" + integrity sha512-qQR1dr2rGIHYlJulmr8Ioq3De0Le9E4MJ5AiaeAETJJpndT1uUNHsGFK3L/UIu+rbkQSdj8J/w2bCsBZc/Y5fQ== "@types/concat-stream@^1.6.0": version "1.6.1" @@ -1670,20 +1344,6 @@ dependencies: "@types/node" "*" -"@types/debug@^4.1.7": - version "4.1.11" - resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.11.tgz#b20d24098288f19e48fdf776c5d9ccd024629e4e" - integrity sha512-R2qflTjHDs4CL6D/6TkqBeIHr54WzZfIxN729xvCNlYIVp2LknlnCro5Yo3frNaX2E5gO9pZ3/QAPVdGmu+q9w== - dependencies: - "@types/ms" "*" - -"@types/ethereum-protocol@*", "@types/ethereum-protocol@^1.0.0": - version "1.0.5" - resolved "https://registry.yarnpkg.com/@types/ethereum-protocol/-/ethereum-protocol-1.0.5.tgz#6ad4c2c722d440d1f59e0d7e44a0fbb5fad2c41b" - integrity sha512-4wr+t2rYbwMmDrT447SGzE/43Z0EN++zyHCBoruIx32fzXQDxVa1rnQbYwPO8sLP2OugE/L8KaAIJC5kieUuBg== - dependencies: - bignumber.js "7.2.1" - "@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" @@ -1699,11 +1359,6 @@ "@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.12": version "7.0.15" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" @@ -1714,13 +1369,6 @@ 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" @@ -1753,32 +1401,22 @@ "@types/node" "*" "@types/mocha@^10.0.1": - version "10.0.4" - resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-10.0.4.tgz#b5331955ebca216604691fd4fcd2dbdc2bd559a4" - integrity sha512-xKU7bUjiFTIttpWaIZ9qvgg+22O1nmbA+HRxdlR+u6TWsGfmFdXrheJoK4fFxrHNVIOBDvDNKZG+LYBpMHpX3w== - -"@types/mocha@^9.0.0": - version "9.1.1" - resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-9.1.1.tgz#e7c4f1001eefa4b8afbd1eee27a237fee3bf29c4" - integrity sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw== - -"@types/ms@*": - version "0.7.34" - resolved "https://registry.yarnpkg.com/@types/ms/-/ms-0.7.34.tgz#10964ba0dee6ac4cd462e2795b6bebd407303433" - integrity sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g== + version "10.0.6" + resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-10.0.6.tgz#818551d39113081048bdddbef96701b4e8bb9d1b" + integrity sha512-dJvrYWxP/UcXm36Qn36fxhUKu8A/xMRXVT2cliFF1Z7UA9liG5Psj3ezNSZw+5puH2czDXRLcXQxf8JbJt0ejg== "@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== + version "2.6.11" + resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.6.11.tgz#9b39b78665dae0e82a08f02f4967d62c66f95d24" + integrity sha512-24xFj9R5+rfQJLRyM56qh+wnVSYhyXC2tkoBndtY0U+vubqNsYXGjufB2nn8Q6gt0LrARwL6UBtMCSVCwl4B1g== dependencies: "@types/node" "*" form-data "^4.0.0" "@types/node@*": - version "20.9.0" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.9.0.tgz#bfcdc230583aeb891cf51e73cfdaacdd8deae298" - integrity sha512-nekiGu2NDb1BcVofVcEKMIwzlx4NjHlcjhoxxKBNLtz15Y1z7MYf549DFvkHSId02Ax6kGwWntIBPC3l/JZcmw== + version "20.11.10" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.11.10.tgz#6c3de8974d65c362f82ee29db6b5adf4205462f9" + integrity sha512-rZEfe/hJSGYmdfX9tvcPMYeYPW2sNl50nsw4jZmRcaG0HIAb0WYEpsB05GOb53vjqpyE9GUhlDQ4jLSoB5q9kg== dependencies: undici-types "~5.26.4" @@ -1792,15 +1430,10 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.60.tgz#35f3d6213daed95da7f0f73e75bcc6980e90597b" integrity sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw== -"@types/node@^12.12.6": - version "12.20.55" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.55.tgz#c329cbd434c42164f846b909bd6f85b5537f6240" - integrity sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ== - "@types/node@^18.15.11": - version "18.18.9" - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.18.9.tgz#5527ea1832db3bba8eb8023ce8497b7d3f299592" - integrity sha512-0f5klcuImLnG4Qreu9hPj/rEfFq6YRc5n2mAjSsH+ec/mJL+3voBH0+8T7o8RpFjH7ovc+TRsL/c7OYIQsPTfQ== + version "18.19.10" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.19.10.tgz#4de314ab66faf6bc8ba691021a091ddcdf13a158" + integrity sha512-IZD8kAM02AW1HRDTPOlz3npFava678pr8Ie9Vp8uRhBROXAv8MXT2pCnGZZAKYdromsNQLHQcfWQ6EOatVLtqA== dependencies: undici-types "~5.26.4" @@ -1822,9 +1455,9 @@ 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== + version "6.9.11" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.11.tgz#208d8a30bc507bd82e03ada29e4732ea46a6bbda" + integrity sha512-oGk0gmhnEJK4Yyk+oI7EfXsLayXatCWPHary1MtcmbAifkobT9cM9yutG/hZKIseOU0MqbIwQ/u2nn/Gb+ltuQ== "@types/readable-stream@^2.3.13": version "2.3.15" @@ -1834,13 +1467,6 @@ "@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" @@ -1854,40 +1480,20 @@ integrity sha512-giB9gzDeiCeloIXDgzFBCgjj1k4WxcDrZtGl6h1IqmUPlxF+Nx8Ve+96QCyDZ/HseB/uvDsKbpib9hU5cU53pw== "@types/semver@^7.5.0": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.5.tgz#deed5ab7019756c9c90ea86139106b0346223f35" - integrity sha512-+d+WYC1BxJ6yVOgUgzK8gWvp5qF8ssV5r4nsDcZWKRWcDQLQ619tvWAxJQYGgBrO1MnLJC7a5GtiYsAoQ47dJg== - -"@types/underscore@*": - version "1.11.13" - resolved "https://registry.yarnpkg.com/@types/underscore/-/underscore-1.11.13.tgz#a7bc9dd049621399a492cf4691e1d2ba01b8c1e0" - integrity sha512-x/KVdl2MXWKrQmcGktLLZfT6LVDIgSZhWWWrKgoEXSv2BSUkqJOoELJMphnnZBbrpZ62U8z+9eyusxyIP8lxFw== - -"@types/web3-provider-engine@^14.0.0": - version "14.0.4" - resolved "https://registry.yarnpkg.com/@types/web3-provider-engine/-/web3-provider-engine-14.0.4.tgz#78b76bd177fca9678dbb998afa837a0beb15efca" - integrity sha512-59wFvtceRmWXfQFoH8qtFIQZf6B7PqBwgBBmZLu4SjRK6pycnjV8K+jihbaGOFwHjTPcPFm15m+CS6I0BBm4lw== - dependencies: - "@types/ethereum-protocol" "*" - -"@types/web3@1.0.20": - version "1.0.20" - resolved "https://registry.yarnpkg.com/@types/web3/-/web3-1.0.20.tgz#234dd1f976702c0daaff147c80f24a5582e09d0e" - integrity sha512-KTDlFuYjzCUlBDGt35Ir5QRtyV9klF84MMKUsEJK10sTWga/71V+8VYLT7yysjuBjaOx2uFYtIWNGoz3yrNDlg== - dependencies: - "@types/bn.js" "*" - "@types/underscore" "*" + version "7.5.6" + resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.6.tgz#c65b2bfce1bec346582c07724e3f8c1017a20339" + integrity sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A== "@typescript-eslint/eslint-plugin@^6.10.0": - version "6.10.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.10.0.tgz#cfe2bd34e26d2289212946b96ab19dcad64b661a" - integrity sha512-uoLj4g2OTL8rfUQVx2AFO1hp/zja1wABJq77P6IclQs6I/m9GLrm7jCdgzZkvWdDCQf1uEvoa8s8CupsgWQgVg== + version "6.20.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.20.0.tgz#9cf31546d2d5e884602626d89b0e0d2168ac25ed" + integrity sha512-fTwGQUnjhoYHeSF6m5pWNkzmDDdsKELYrOBxhjMrofPqCkoC2k3B2wvGHFxa1CTIqkEn88nlW1HVMztjo2K8Hg== dependencies: "@eslint-community/regexpp" "^4.5.1" - "@typescript-eslint/scope-manager" "6.10.0" - "@typescript-eslint/type-utils" "6.10.0" - "@typescript-eslint/utils" "6.10.0" - "@typescript-eslint/visitor-keys" "6.10.0" + "@typescript-eslint/scope-manager" "6.20.0" + "@typescript-eslint/type-utils" "6.20.0" + "@typescript-eslint/utils" "6.20.0" + "@typescript-eslint/visitor-keys" "6.20.0" debug "^4.3.4" graphemer "^1.4.0" ignore "^5.2.4" @@ -1896,71 +1502,72 @@ ts-api-utils "^1.0.1" "@typescript-eslint/parser@^6.10.0": - version "6.10.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-6.10.0.tgz#578af79ae7273193b0b6b61a742a2bc8e02f875a" - integrity sha512-+sZwIj+s+io9ozSxIWbNB5873OSdfeBEH/FR0re14WLI6BaKuSOnnwCJ2foUiu8uXf4dRp1UqHP0vrZ1zXGrog== - dependencies: - "@typescript-eslint/scope-manager" "6.10.0" - "@typescript-eslint/types" "6.10.0" - "@typescript-eslint/typescript-estree" "6.10.0" - "@typescript-eslint/visitor-keys" "6.10.0" + version "6.20.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-6.20.0.tgz#17e314177304bdf498527e3c4b112e41287b7416" + integrity sha512-bYerPDF/H5v6V76MdMYhjwmwgMA+jlPVqjSDq2cRqMi8bP5sR3Z+RLOiOMad3nsnmDVmn2gAFCyNgh/dIrfP/w== + dependencies: + "@typescript-eslint/scope-manager" "6.20.0" + "@typescript-eslint/types" "6.20.0" + "@typescript-eslint/typescript-estree" "6.20.0" + "@typescript-eslint/visitor-keys" "6.20.0" debug "^4.3.4" -"@typescript-eslint/scope-manager@6.10.0": - version "6.10.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-6.10.0.tgz#b0276118b13d16f72809e3cecc86a72c93708540" - integrity sha512-TN/plV7dzqqC2iPNf1KrxozDgZs53Gfgg5ZHyw8erd6jd5Ta/JIEcdCheXFt9b1NYb93a1wmIIVW/2gLkombDg== +"@typescript-eslint/scope-manager@6.20.0": + version "6.20.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-6.20.0.tgz#8a926e60f6c47feb5bab878246dc2ae465730151" + integrity sha512-p4rvHQRDTI1tGGMDFQm+GtxP1ZHyAh64WANVoyEcNMpaTFn3ox/3CcgtIlELnRfKzSs/DwYlDccJEtr3O6qBvA== dependencies: - "@typescript-eslint/types" "6.10.0" - "@typescript-eslint/visitor-keys" "6.10.0" + "@typescript-eslint/types" "6.20.0" + "@typescript-eslint/visitor-keys" "6.20.0" -"@typescript-eslint/type-utils@6.10.0": - version "6.10.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-6.10.0.tgz#1007faede067c78bdbcef2e8abb31437e163e2e1" - integrity sha512-wYpPs3hgTFblMYwbYWPT3eZtaDOjbLyIYuqpwuLBBqhLiuvJ+9sEp2gNRJEtR5N/c9G1uTtQQL5AhV0fEPJYcg== +"@typescript-eslint/type-utils@6.20.0": + version "6.20.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-6.20.0.tgz#d395475cd0f3610dd80c7d8716fa0db767da3831" + integrity sha512-qnSobiJQb1F5JjN0YDRPHruQTrX7ICsmltXhkV536mp4idGAYrIyr47zF/JmkJtEcAVnIz4gUYJ7gOZa6SmN4g== dependencies: - "@typescript-eslint/typescript-estree" "6.10.0" - "@typescript-eslint/utils" "6.10.0" + "@typescript-eslint/typescript-estree" "6.20.0" + "@typescript-eslint/utils" "6.20.0" debug "^4.3.4" ts-api-utils "^1.0.1" -"@typescript-eslint/types@6.10.0": - version "6.10.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-6.10.0.tgz#f4f0a84aeb2ac546f21a66c6e0da92420e921367" - integrity sha512-36Fq1PWh9dusgo3vH7qmQAj5/AZqARky1Wi6WpINxB6SkQdY5vQoT2/7rW7uBIsPDcvvGCLi4r10p0OJ7ITAeg== +"@typescript-eslint/types@6.20.0": + version "6.20.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-6.20.0.tgz#5ccd74c29011ae7714ae6973e4ec0c634708b448" + integrity sha512-MM9mfZMAhiN4cOEcUOEx+0HmuaW3WBfukBZPCfwSqFnQy0grXYtngKCqpQN339X3RrwtzspWJrpbrupKYUSBXQ== -"@typescript-eslint/typescript-estree@6.10.0": - version "6.10.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-6.10.0.tgz#667381eed6f723a1a8ad7590a31f312e31e07697" - integrity sha512-ek0Eyuy6P15LJVeghbWhSrBCj/vJpPXXR+EpaRZqou7achUWL8IdYnMSC5WHAeTWswYQuP2hAZgij/bC9fanBg== +"@typescript-eslint/typescript-estree@6.20.0": + version "6.20.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-6.20.0.tgz#5b2d0975949e6bdd8d45ee1471461ef5fadc5542" + integrity sha512-RnRya9q5m6YYSpBN7IzKu9FmLcYtErkDkc8/dKv81I9QiLLtVBHrjz+Ev/crAqgMNW2FCsoZF4g2QUylMnJz+g== dependencies: - "@typescript-eslint/types" "6.10.0" - "@typescript-eslint/visitor-keys" "6.10.0" + "@typescript-eslint/types" "6.20.0" + "@typescript-eslint/visitor-keys" "6.20.0" debug "^4.3.4" globby "^11.1.0" is-glob "^4.0.3" + minimatch "9.0.3" semver "^7.5.4" ts-api-utils "^1.0.1" -"@typescript-eslint/utils@6.10.0": - version "6.10.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-6.10.0.tgz#4d76062d94413c30e402c9b0df8c14aef8d77336" - integrity sha512-v+pJ1/RcVyRc0o4wAGux9x42RHmAjIGzPRo538Z8M1tVx6HOnoQBCX/NoadHQlZeC+QO2yr4nNSFWOoraZCAyg== +"@typescript-eslint/utils@6.20.0": + version "6.20.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-6.20.0.tgz#0e52afcfaa51af5656490ba4b7437cc3aa28633d" + integrity sha512-/EKuw+kRu2vAqCoDwDCBtDRU6CTKbUmwwI7SH7AashZ+W+7o8eiyy6V2cdOqN49KsTcASWsC5QeghYuRDTyOOg== dependencies: "@eslint-community/eslint-utils" "^4.4.0" "@types/json-schema" "^7.0.12" "@types/semver" "^7.5.0" - "@typescript-eslint/scope-manager" "6.10.0" - "@typescript-eslint/types" "6.10.0" - "@typescript-eslint/typescript-estree" "6.10.0" + "@typescript-eslint/scope-manager" "6.20.0" + "@typescript-eslint/types" "6.20.0" + "@typescript-eslint/typescript-estree" "6.20.0" semver "^7.5.4" -"@typescript-eslint/visitor-keys@6.10.0": - version "6.10.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-6.10.0.tgz#b9eaf855a1ac7e95633ae1073af43d451e8f84e3" - integrity sha512-xMGluxQIEtOM7bqFCo+rCMh5fqI+ZxV5RUUOa29iVPz1OgCZrtc7rFnz5cLUazlkPKYqX+75iuDq7m0HQ48nCg== +"@typescript-eslint/visitor-keys@6.20.0": + version "6.20.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-6.20.0.tgz#f7ada27f2803de89df0edd9fd7be22c05ce6a498" + integrity sha512-E8Cp98kRe4gKHjJD4NExXKz/zOJ1A2hhZc+IMVD6i7w4yjIvh6VyuRI0gRtxAsXtoC35uGMaQ9rjI2zJaXDEAw== dependencies: - "@typescript-eslint/types" "6.10.0" + "@typescript-eslint/types" "6.20.0" eslint-visitor-keys "^3.4.1" "@ungap/structured-clone@^1.2.0": @@ -1968,70 +1575,6 @@ resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.2.0.tgz#756641adb587851b5ccb3e095daf27ae581c8406" integrity sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ== -"@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@^3.2.2": - version "3.2.6" - resolved "https://registry.yarnpkg.com/@uniswap/sdk-core/-/sdk-core-3.2.6.tgz#1a652516fab0c6bc1420c2226648da967a10f52a" - integrity sha512-MvH/3G0W0sM2g7XjaUy9qU7IabxL/KQp/ucU0AQGpVxiTaAhmVRtsjkkv9UDyzpIXVrmevl4kRgV7KKE29UuXA== - 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/universal-router@^1.4.1": - version "1.5.1" - resolved "https://registry.yarnpkg.com/@uniswap/universal-router/-/universal-router-1.5.1.tgz#2ce832485eb85093b0cb94a53be20661e1aece70" - integrity sha512-+htTC/nHQXKfY/c+9C1XHMRs7Jz0bX9LQfYn9Hb7WZKZ/YHWhOsCZQylYhksieLYTRam5sQheow747hOZ+QpZQ== - dependencies: - "@openzeppelin/contracts" "4.7.0" - "@uniswap/v2-core" "1.0.1" - "@uniswap/v3-core" "1.0.0" - -"@uniswap/v2-core@1.0.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.1", "@uniswap/v3-core@^1.0.0": - 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.4.1": - version "1.4.1" - resolved "https://registry.yarnpkg.com/@uniswap/v3-periphery/-/v3-periphery-1.4.1.tgz#b90f08b7386163c0abfd7258831caef6339c7862" - integrity sha512-Ab0ZCKOQrQMKIcpBTezTsEhWfQjItd0TtkCG8mPhoQu+wC67nPaf4hYUhM6wGHeFUmDiYY5MpEQuokB0ENvoTg== - 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" - hardhat-watcher "^2.1.1" - -"@uniswap/v3-periphery@^1.4.3": - 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" - abbrev@1: version "1.1.1" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" @@ -2042,12 +1585,7 @@ abbrev@1.0.x: resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.0.9.tgz#91b4792588a7738c25f35dd6f63752a2f8776135" integrity sha512-LEyx4aLEC3x6T0UguF6YILf+ntvmOaWsVfENmIW0E9H09vKlLDGelMjjSm0jkDHALj8A8quZ/HapKNigzwge+Q== -abortcontroller-polyfill@^1.7.3: - 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.3, abstract-level@^1.0.0, abstract-level@^1.0.2, abstract-level@^1.0.3: +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== @@ -2060,6 +1598,19 @@ abstract-level@1.0.3, abstract-level@^1.0.0, abstract-level@^1.0.2, abstract-lev module-error "^1.0.1" queue-microtask "^1.2.3" +abstract-level@^1.0.0, abstract-level@^1.0.2, abstract-level@^1.0.3, abstract-level@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/abstract-level/-/abstract-level-1.0.4.tgz#3ad8d684c51cc9cbc9cf9612a7100b716c414b57" + integrity sha512-eUP/6pbXBkMbXFdx4IH2fVgvB7M0JvR7/lIL33zcs0IBcwjdzSSl31TOJsaCzmKSSDF9h8QYSOJux4Nd4YJqFg== + 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@7.2.0, abstract-leveldown@^7.2.0: version "7.2.0" resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-7.2.0.tgz#08d19d4e26fb5be426f7a57004851b39e1795a2e" @@ -2083,20 +1634,6 @@ abstract-leveldown@^6.2.1: level-supports "~1.0.0" xtend "~4.0.0" -abstract-leveldown@~2.6.0: - version "2.6.3" - resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-2.6.3.tgz#1c5e8c6a5ef965ae8c35dfb3a8770c476b82c4b8" - integrity sha512-2++wDf/DYqkPR3o5tbfdhF96EfMApo1GpPfzOsR/ZYXdkSmELlvOOEAl9iKkRsktMPHdGjO4rtkBpf2I7TiTeA== - dependencies: - xtend "~4.0.0" - -abstract-leveldown@~2.7.1: - version "2.7.2" - resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-2.7.2.tgz#87a44d7ebebc341d59665204834c8b7e0932cc93" - integrity sha512-+OVvxH2rHVEhWLdbudP6p0+dNMXu8JA1CbhP19T8paTYAcX7oJ4OVjT+ZUVpv7mITxXHqDMej+GdqXBmXkw09w== - dependencies: - xtend "~4.0.0" - abstract-leveldown@~6.2.1: version "6.2.3" resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-6.2.3.tgz#036543d87e3710f2528e47040bc3261b77a9a8eb" @@ -2108,28 +1645,20 @@ abstract-leveldown@~6.2.1: 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.2: version "5.3.2" resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== acorn-walk@^8.1.1: - version "8.3.0" - resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.3.0.tgz#2097665af50fd0cf7a2dfccd2b9368964e66540f" - integrity sha512-FS7hV565M5l1R08MXqo8odwMTB02C2UqzB17RVgu9EyuYFBqJZ3/ZY97sQD5FewVu1UyDFc1yztUDrAwT0EypA== + version "8.3.2" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.3.2.tgz#7703af9415f1b6db9315d6895503862e231d34aa" + integrity sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A== acorn@^8.4.1, acorn@^8.9.0: - version "8.11.2" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.2.tgz#ca0d78b51895be5390a5903c5b3bdcdaf78ae40b" - integrity sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w== + version "8.11.3" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.3.tgz#71e0b14e13a4ec160724b38fb7b0f233b1b81d7a" + integrity sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg== address@^1.0.1: version "1.2.2" @@ -2146,11 +1675,6 @@ aes-js@3.0.0: resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-3.0.0.tgz#e21df10ad6c2053295bcbb8dab40b09dbea87e4d" integrity sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw== -aes-js@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-3.1.2.tgz#db9aabde85d5caabbfc0d4f2a4446960f627146a" - integrity sha512-e5pEa2kBnBOgR4Y/p20pskXI74UEz7de8ZGVo58asOtvSVG5YAbJeELPZxOmt+Bnz3rX753YKhfIn4X4l1PPRQ== - agent-base@6: version "6.0.2" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" @@ -2290,11 +1814,6 @@ array-buffer-byte-length@^1.0.0: 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" @@ -2392,31 +1911,19 @@ astral-regex@^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, async-eventemitter@^0.2.2, async-eventemitter@^0.2.4: +async-eventemitter@0.2.4, 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-mutex@^0.2.6: - version "0.2.6" - resolved "https://registry.yarnpkg.com/async-mutex/-/async-mutex-0.2.6.tgz#0d7a3deb978bc2b984d5908a2038e1ae2e54ff40" - integrity sha512-Hs4R+4SPgamu6rSGW8C7cV9gaWUKEHykfzCCvIRuaVv636Ju10ZdeUbvb4TBEW0INuq2DHZqXbK4Nd3yG4RaRw== - dependencies: - tslib "^2.0.0" - -async@1.x, async@^1.4.2: +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.0.1, async@^2.1.2, async@^2.4.0, async@^2.5.0: +async@^2.4.0: version "2.6.4" resolved "https://registry.yarnpkg.com/async/-/async-2.6.4.tgz#706b7ff6084664cd7eae713f6f965433b5504221" integrity sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA== @@ -2456,51 +1963,20 @@ axios@^0.21.1: follow-redirects "^1.14.0" axios@^1.4.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== + version "1.6.7" + resolved "https://registry.yarnpkg.com/axios/-/axios-1.6.7.tgz#7b48c2e27c96f9c68a2f8f31e2ab19f59b06b0a7" + integrity sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA== dependencies: - follow-redirects "^1.15.0" + follow-redirects "^1.15.4" form-data "^4.0.0" proxy-from-env "^1.1.0" -babel-plugin-polyfill-corejs2@^0.4.6: - version "0.4.6" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.6.tgz#b2df0251d8e99f229a8e60fc4efa9a68b41c8313" - integrity sha512-jhHiWVZIlnPbEUKSSNb9YoWcQGdlTLq7z1GHL4AjFxaoOUMuuEVJ+Y4pAaQUGOGk93YsVCKPbqbfw3m0SM6H8Q== - dependencies: - "@babel/compat-data" "^7.22.6" - "@babel/helper-define-polyfill-provider" "^0.4.3" - semver "^6.3.1" - -babel-plugin-polyfill-corejs3@^0.8.5: - version "0.8.6" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.6.tgz#25c2d20002da91fe328ff89095c85a391d6856cf" - integrity sha512-leDIc4l4tUgU7str5BWLS2h8q2N4Nf6lGZP6UrNDxdtfF2g69eJ5L0H7S8A5Ln/arfFAfHor5InAdZuIOwZdgQ== - dependencies: - "@babel/helper-define-polyfill-provider" "^0.4.3" - core-js-compat "^3.33.1" - -babel-plugin-polyfill-regenerator@^0.5.3: - version "0.5.3" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.3.tgz#d4c49e4b44614607c13fb769bcd85c72bb26a4a5" - integrity sha512-8sHeDOmXC8csczMrYEOf0UTNa4yE2SxV5JGeT/LP1n0OYVDUUFPxG9vdk2AlDlIit4t+Kf0xCtpgXPBwnn/9pw== - dependencies: - "@babel/helper-define-polyfill-provider" "^0.4.3" - -backoff@^2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/backoff/-/backoff-2.5.0.tgz#f616eda9d3e4b66b8ca7fca79f695722c5f8e26f" - integrity sha512-wC5ihrnUXmR2douXmXLCe5O3zg3GKIyvRi/hi58a/XyRxVI+3/yM0PYueQOZXPXQ9pxBislYkw+sF9b7C/RuMA== - dependencies: - precond "0.2" - balanced-match@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== -base-x@^3.0.2, base-x@^3.0.8: +base-x@^3.0.2: 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== @@ -2512,11 +1988,6 @@ base64-js@^1.3.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" @@ -2529,21 +2000,11 @@ bech32@1.1.4: resolved "https://registry.yarnpkg.com/bech32/-/bech32-1.1.4.tgz#e38c9f37bf179b8eb16ae3a772b40c356d4832e9" integrity sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ== -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== - 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@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== - bignumber.js@^9.0.0, bignumber.js@^9.0.1: version "9.1.2" resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.1.2.tgz#b7c4242259c008903b13707983b5f4bbd31eda0c" @@ -2569,17 +2030,12 @@ blakejs@^1.1.0: resolved "https://registry.yarnpkg.com/blakejs/-/blakejs-1.2.1.tgz#5057e4206eadb4a97f7c0b6e197a505042fc3814" integrity sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ== -bluebird@^3.5.0: - 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: +bn.js@^4.0.0, bn.js@^4.11.0, bn.js@^4.11.1, 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== @@ -2589,42 +2045,6 @@ bn.js@^5.1.2, bn.js@^5.2.0, bn.js@^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" - brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" @@ -2679,16 +2099,6 @@ browserify-aes@^1.2.0: inherits "^2.0.1" safe-buffer "^5.0.1" -browserslist@^4.21.9, browserslist@^4.22.1: - version "4.22.1" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.22.1.tgz#ba91958d1a59b87dab6fed8dfbcb3da5e2e9c619" - integrity sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ== - dependencies: - caniuse-lite "^1.0.30001541" - electron-to-chromium "^1.4.535" - node-releases "^2.0.13" - update-browserslist-db "^1.0.13" - bs58@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a" @@ -2705,11 +2115,6 @@ bs58check@^2.1.2: create-hash "^1.1.0" safe-buffer "^5.1.2" -btoa@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/btoa/-/btoa-1.2.1.tgz#01a9909f8b2c93f6bf680ba26131eb30f7fa3d73" - integrity sha512-SB4/MIGlsiVkMcHmT+pSmIPoNDoHg+7cMzmt3Uxt628MTz2487DKSqK/fuhFBrkuqrYv5UCEnACpF4dTFNKc/g== - buffer-from@^1.0.0: version "1.1.2" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" @@ -2720,11 +2125,6 @@ buffer-reverse@^1.0.1: resolved "https://registry.yarnpkg.com/buffer-reverse/-/buffer-reverse-1.0.1.tgz#49283c8efa6f901bc01fa3304d06027971ae2f60" integrity sha512-M87YIUBsZ6N924W57vDwT/aOu8hw7ZgdByz6ijksLjmHJELBASmYTTlNHRgjE+pTsT9oJXGaDSgqqwfdHotDUg== -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" @@ -2737,7 +2137,7 @@ buffer-xor@^2.0.1: dependencies: safe-buffer "^5.1.1" -buffer@^5.0.5, buffer@^5.5.0, buffer@^5.6.0: +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== @@ -2767,18 +2167,16 @@ bufferutil@4.0.7: 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" - bufio@^1.0.7: version "1.2.1" resolved "https://registry.yarnpkg.com/bufio/-/bufio-1.2.1.tgz#8d4ab3ddfcd5faa90f996f922f9397d41cbaf2de" integrity sha512-9oR3zNdupcg/Ge2sSHQF3GX+kmvL/fTPvD0nd5AGLq8SjUYnTz+SlFjK/GXidndbZtIj+pVKXiWeR9w6e9wKCA== +builtin-modules@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-3.3.0.tgz#cae62812b89801e9656336e46223e030386be7b6" + integrity sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw== + builtins@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/builtins/-/builtins-5.0.1.tgz#87f6db9ab0458be728564fa81d876d8d74552fa9" @@ -2791,29 +2189,6 @@ bytes@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" @@ -2838,11 +2213,6 @@ camelcase@^6.0.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== -caniuse-lite@^1.0.30001541: - version "1.0.30001561" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001561.tgz#752f21f56f96f1b1a52e97aae98c57c562d5d9da" - integrity sha512-NTt0DNoKe958Q0BE0j0c1V9jbUzhBxHIEJy7asmGrpE0yG63KTV7PLHPnK2E1O9RsQrQ081I3NLuXGS6zht3cw== - case@^1.6.3: version "1.6.3" resolved "https://registry.yarnpkg.com/case/-/case-1.6.3.tgz#0a4386e3e9825351ca2e6216c60467ff5f1ea1c9" @@ -2878,9 +2248,9 @@ chai-string@^1.5.0: integrity sha512-sydDC3S3pNAQMYwJrs6dQX0oBQ6KfIPuOZ78n7rocW0eJJlsHPh2t3kwW7xfwYA/1Bf6/arGtSUo16rxR2JFlw== chai@^4.3.4, chai@^4.3.7: - version "4.3.10" - resolved "https://registry.yarnpkg.com/chai/-/chai-4.3.10.tgz#d784cec635e3b7e2ffb66446a63b4e33bd390384" - integrity sha512-0UXG04VuVbruMUYbJ6JctvH0YnC/4q3/AkT18q4NaITo91CUm0liMS9VqzT9vZhVQ/1eqPanMWjBM+Juhfb/9g== + version "4.4.1" + resolved "https://registry.yarnpkg.com/chai/-/chai-4.4.1.tgz#3603fa6eba35425b0f2ac91a009fe924106e50d1" + integrity sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g== dependencies: assertion-error "^1.1.0" check-error "^1.0.3" @@ -2919,14 +2289,7 @@ check-error@^1.0.2, check-error@^1.0.3: dependencies: get-func-name "^2.0.2" -checkpoint-store@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/checkpoint-store/-/checkpoint-store-1.1.0.tgz#04e4cb516b91433893581e6d4601a78e9552ea06" - integrity sha512-J/NdY2WvIx654cc6LWSq/IYFFCUf75fFTgwzFnmbqyORH4MwgiQCgswLLKBGzmsyTI5V7i5bp/So6sMbDWhedg== - dependencies: - functional-red-black-tree "^1.0.1" - -chokidar@3.5.3, chokidar@^3.4.0, chokidar@^3.5.2, chokidar@^3.5.3: +chokidar@3.5.3, chokidar@^3.4.0, chokidar@^3.5.2: version "3.5.3" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== @@ -2941,27 +2304,11 @@ chokidar@3.5.3, chokidar@^3.4.0, chokidar@^3.5.2, chokidar@^3.5.3: 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" @@ -2970,15 +2317,10 @@ cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: 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== + version "1.4.1" + resolved "https://registry.yarnpkg.com/classic-level/-/classic-level-1.4.1.tgz#169ecf9f9c6200ad42a98c8576af449c1badbaee" + integrity sha512-qGx/KJl3bvtOHrGau2WklEZuXhS3zme+jf+fsu6Ej7W7IP/C49v7KNlWIsT1jZu0YnfzSIYDGcEWpCa1wKGWXQ== dependencies: abstract-level "^1.0.2" catering "^2.1.0" @@ -3019,18 +2361,6 @@ cliui@^7.0.2: 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" - -clone@^2.0.0, clone@^2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f" - integrity sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w== - color-convert@^1.9.0: version "1.9.3" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" @@ -3122,53 +2452,15 @@ concat-stream@^1.6.0, concat-stream@^1.6.2: readable-stream "^2.2.2" typedarray "^0.0.6" -content-disposition@0.5.4: - version "0.5.4" - resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" - integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== - dependencies: - safe-buffer "5.2.1" - -content-hash@^2.5.2: - version "2.5.2" - resolved "https://registry.yarnpkg.com/content-hash/-/content-hash-2.5.2.tgz#bbc2655e7c21f14fd3bfc7b7d4bfe6e454c9e211" - integrity sha512-FvIQKy0S1JaWV10sMsA7TRx8bpU+pqPkhbsfvOJAdjRXvYxEckAwQWGwtRjiaJfh+E0DvcWUGqcdjwMGFjsSdw== - dependencies: - cids "^0.7.1" - multicodec "^0.5.5" - multihashes "^0.4.15" - -content-type@~1.0.4, 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-compat@^3.33.1: - version "3.33.2" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.33.2.tgz#3ea4563bfd015ad4e4b52442865b02c62aba5085" - integrity sha512-axfo+wxFVxnqf8RvxTzoAlzW4gRoacrHeoFlc9n0x50+7BEyZL/Rt3hicaED1/CEd7I6tPCPVUYcJwCMO5XUYw== - dependencies: - browserslist "^4.22.1" - 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== + version "3.35.1" + resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.35.1.tgz#f33ad7fdf9dddae260339a30e5f8363f5c49a3bc" + integrity sha512-zcIdi/CL3MWbBJYo5YCeVAAx+Sy9yJE9I3/u9LkFABwbeaPhTMRWraM8mYFp9jW5Z50hOy7FVzCc8dCrpZqtIQ== core-util-is@1.0.2: version "1.0.2" @@ -3180,14 +2472,6 @@ core-util-is@~1.0.0: 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" @@ -3231,21 +2515,6 @@ create-require@^1.1.0: resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== -cross-fetch@^2.1.0: - version "2.2.6" - resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-2.2.6.tgz#2ef0bb39a24ac034787965c457368a28730e220a" - integrity sha512-9JZz+vXCmfKUZ68zAptS7k4Nu8e2qcibe7WVZYps7sAgk5R8GYTc+T1WR0v1rlP9HxgARmOX1UTIJZFytajpNA== - dependencies: - node-fetch "^2.6.7" - whatwg-fetch "^2.0.4" - -cross-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-spawn@^6.0.0: version "6.0.5" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" @@ -3276,14 +2545,6 @@ crypto-js@^4.2.0: resolved "https://registry.yarnpkg.com/crypto-js/-/crypto-js-4.2.0.tgz#4d931639ecdfd12ff80e8186dba6af2c2e856631" integrity sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q== -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" @@ -3296,13 +2557,6 @@ death@^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.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" @@ -3310,6 +2564,13 @@ debug@4, debug@4.3.4, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.3, de dependencies: ms "2.1.2" +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@^3.1.0, debug@^3.2.7: version "3.2.7" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" @@ -3327,30 +2588,6 @@ decamelize@^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.0.1, deep-eql@^4.1.3: version "4.1.3" resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-4.1.3.tgz#7c7775513092f7df98d8df9996dd085eb668cc6d" @@ -3368,18 +2605,6 @@ deep-is@^0.1.3, deep-is@~0.1.3: 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@~1.2.1: - version "1.2.2" - resolved "https://registry.yarnpkg.com/deferred-leveldown/-/deferred-leveldown-1.2.2.tgz#3acd2e0b75d1669924bc0a4b642851131173e1eb" - integrity sha512-uukrWD2bguRtXilKt6cAWKyoXrTSMo5m7crUdLfWQmu8kIm88w3QZoUL+6nhpfKVmhHANER6Re3sKoNoZ3IKMA== - dependencies: - abstract-leveldown "~2.6.0" - deferred-leveldown@~5.3.0: version "5.3.0" resolved "https://registry.yarnpkg.com/deferred-leveldown/-/deferred-leveldown-5.3.0.tgz#27a997ad95408b61161aa69bd489b86c71b78058" @@ -3397,7 +2622,7 @@ define-data-property@^1.0.1, define-data-property@^1.1.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: +define-properties@^1.1.3, define-properties@^1.2.0, define-properties@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.1.tgz#10781cc616eb951a80a034bafcaa7377f6af2b6c" integrity sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg== @@ -3416,11 +2641,6 @@ depd@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-port@^1.3.0: version "1.5.1" resolved "https://registry.yarnpkg.com/detect-port/-/detect-port-1.5.1.tgz#451ca9b6eaf20451acb0799b8ab40dff7718727b" @@ -3467,15 +2687,14 @@ doctrine@^3.0.0: dependencies: esutils "^2.0.2" -dom-walk@^0.1.0: - version "0.1.2" - resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.2.tgz#0c548bef048f4d1f2a97249002236060daa3fd84" - integrity sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w== - dotenv@^16.0.3: - version "16.3.1" - resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.3.1.tgz#369034de7d7e5b120972693352a3bf112172cc3e" - integrity sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ== + version "16.4.1" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.4.1.tgz#1d9931f1d3e5d2959350d1250efab299561f7f11" + integrity sha512-CjA3y+Dr3FyFDOAMnxZEGtnW9KBR2M0JvvUtXNW+dYJL5ROWxP9DUHCwgFqpMk0OXCc0ljhaNTr2w/kutYIcHQ== + +"ds-test@github:dapphub/ds-test": + version "1.0.0" + resolved "https://codeload.github.com/dapphub/ds-test/tar.gz/e282159d5170298eb2455a6c05280ab5a73a4ef0" ecc-jsbn@~0.1.1: version "0.1.2" @@ -3485,17 +2704,7 @@ ecc-jsbn@~0.1.1: 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== - -electron-to-chromium@^1.4.535: - version "1.4.578" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.578.tgz#7a3510f333bcd55e87882799ebeb7518d6ab4d95" - integrity sha512-V0ZhSu1BQZKfG0yNEL6Dadzik8E1vAzfpVOapdSiT9F6yapEJ3Bk+4tZ4SMPdWiUchCgnM/ByYtBzp5ntzDMIA== - -elliptic@6.5.4, elliptic@^6.4.0, elliptic@^6.5.2, elliptic@^6.5.4: +elliptic@6.5.4, 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== @@ -3528,11 +2737,6 @@ encode-utf8@^1.0.2: 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" @@ -3647,47 +2851,11 @@ es-to-primitive@^1.2.1: 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" @@ -3710,6 +2878,11 @@ escodegen@1.8.x: optionalDependencies: source-map "~0.2.0" +eslint-compat-utils@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/eslint-compat-utils/-/eslint-compat-utils-0.1.2.tgz#f45e3b5ced4c746c127cf724fb074cd4e730d653" + integrity sha512-Jia4JDldWnFNIru1Ehx1H5s9/yxiRHY/TimCuUc0jNexew3cF1gI6CYZil1ociakfWO3rRqFjl1mskBblB3RYg== + eslint-config-prettier@^8.5.0: version "8.10.0" resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.10.0.tgz#3a06a662130807e2502fc3ff8b4143d8a0658e11" @@ -3736,13 +2909,14 @@ eslint-module-utils@^2.8.0: dependencies: debug "^3.2.7" -eslint-plugin-es-x@^7.1.0: - version "7.3.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-es-x/-/eslint-plugin-es-x-7.3.0.tgz#c699280ad35cd315720c3cccf0fe503092c08788" - integrity sha512-W9zIs+k00I/I13+Bdkl/zG1MEO07G97XjUSQuH117w620SJ6bHtLUmoMvkGA2oYnI/gNdr+G7BONLyYnFaLLEQ== +eslint-plugin-es-x@^7.5.0: + version "7.5.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-es-x/-/eslint-plugin-es-x-7.5.0.tgz#d08d9cd155383e35156c48f736eb06561d07ba92" + integrity sha512-ODswlDSO0HJDzXU0XvgZ3lF3lS3XAZEossh15Q2UHjwrJggWeBoKqqEsLTZLXl+dh5eOAozG0zRcYtuE35oTuQ== dependencies: "@eslint-community/eslint-utils" "^4.1.2" "@eslint-community/regexpp" "^4.6.0" + eslint-compat-utils "^0.1.2" eslint-plugin-es@^3.0.0: version "3.0.1" @@ -3753,9 +2927,9 @@ eslint-plugin-es@^3.0.0: regexpp "^3.0.0" eslint-plugin-import@^2.29.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== + version "2.29.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz#d45b37b5ef5901d639c15270d74d46d161150643" + integrity sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw== dependencies: array-includes "^3.1.7" array.prototype.findlastindex "^1.2.3" @@ -3773,18 +2947,20 @@ eslint-plugin-import@^2.29.0: object.groupby "^1.0.1" object.values "^1.1.7" semver "^6.3.1" - tsconfig-paths "^3.14.2" + tsconfig-paths "^3.15.0" eslint-plugin-n@^16.3.0: - version "16.3.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-n/-/eslint-plugin-n-16.3.0.tgz#8ad04e0c52b311d58bd9b6b59532e26a19d3911b" - integrity sha512-/XZLH5CUXGK3laz3xYFNza8ZxLCq8ZNW6MsVw5z3d5hc2AwZzi0fPiySFZHQTdVDOHGs2cGv91aqzWmgBdq2gQ== + version "16.6.2" + resolved "https://registry.yarnpkg.com/eslint-plugin-n/-/eslint-plugin-n-16.6.2.tgz#6a60a1a376870064c906742272074d5d0b412b0b" + integrity sha512-6TyDmZ1HXoFQXnhCTUjVFULReoBPOAjpuiKELMkeP40yffI/1ZRO+d9ug/VC6fqISo2WkuIBk3cvuRPALaWlOQ== dependencies: "@eslint-community/eslint-utils" "^4.4.0" builtins "^5.0.1" - eslint-plugin-es-x "^7.1.0" + eslint-plugin-es-x "^7.5.0" get-tsconfig "^4.7.0" + globals "^13.24.0" ignore "^5.2.4" + is-builtin-module "^3.2.1" is-core-module "^2.12.1" minimatch "^3.1.2" resolve "^1.22.2" @@ -3847,14 +3023,14 @@ eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4 integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== eslint@^8.53.0: - version "8.53.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.53.0.tgz#14f2c8244298fcae1f46945459577413ba2697ce" - integrity sha512-N4VuiPjXDUa4xVeV/GC/RV3hQW9Nw+Y463lkWaKKXKYMvmRiRDAtfpuPFLN+E1/6ZhyR8J2ig+eVREnYgUsiag== + version "8.56.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.56.0.tgz#4957ce8da409dc0809f99ab07a1b94832ab74b15" + integrity sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ== dependencies: "@eslint-community/eslint-utils" "^4.2.0" "@eslint-community/regexpp" "^4.6.1" - "@eslint/eslintrc" "^2.1.3" - "@eslint/js" "8.53.0" + "@eslint/eslintrc" "^2.1.4" + "@eslint/js" "8.56.0" "@humanwhocodes/config-array" "^0.11.13" "@humanwhocodes/module-importer" "^1.0.1" "@nodelib/fs.walk" "^1.2.8" @@ -3938,31 +3114,6 @@ esutils@^2.0.2: 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-block-tracker@^4.4.2: - version "4.4.3" - resolved "https://registry.yarnpkg.com/eth-block-tracker/-/eth-block-tracker-4.4.3.tgz#766a0a0eb4a52c867a28328e9ae21353812cf626" - integrity sha512-A8tG4Z4iNg4mw5tP1Vung9N9IjgMNqpiMoJ/FouSFwNCGHv2X0mmOYwtQOJzki6XN7r7Tyo01S29p7b224I4jw== - dependencies: - "@babel/plugin-transform-runtime" "^7.5.5" - "@babel/runtime" "^7.5.5" - eth-query "^2.1.0" - json-rpc-random-id "^1.0.1" - pify "^3.0.0" - safe-event-emitter "^1.0.1" - -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.24, 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" @@ -3982,96 +3133,6 @@ eth-gas-reporter@^0.2.24, eth-gas-reporter@^0.2.25: sha1 "^1.1.1" sync-request "^6.0.0" -eth-json-rpc-filters@^4.2.1: - version "4.2.2" - resolved "https://registry.yarnpkg.com/eth-json-rpc-filters/-/eth-json-rpc-filters-4.2.2.tgz#eb35e1dfe9357ace8a8908e7daee80b2cd60a10d" - integrity sha512-DGtqpLU7bBg63wPMWg1sCpkKCf57dJ+hj/k3zF26anXMzkmtSBDExL8IhUu7LUd34f0Zsce3PYNO2vV2GaTzaw== - dependencies: - "@metamask/safe-event-emitter" "^2.0.0" - async-mutex "^0.2.6" - eth-json-rpc-middleware "^6.0.0" - eth-query "^2.1.2" - json-rpc-engine "^6.1.0" - pify "^5.0.0" - -eth-json-rpc-infura@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/eth-json-rpc-infura/-/eth-json-rpc-infura-5.1.0.tgz#e6da7dc47402ce64c54e7018170d89433c4e8fb6" - integrity sha512-THzLye3PHUSGn1EXMhg6WTLW9uim7LQZKeKaeYsS9+wOBcamRiCQVGHa6D2/4P0oS0vSaxsBnU/J6qvn0MPdow== - dependencies: - eth-json-rpc-middleware "^6.0.0" - eth-rpc-errors "^3.0.0" - json-rpc-engine "^5.3.0" - node-fetch "^2.6.0" - -eth-json-rpc-middleware@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/eth-json-rpc-middleware/-/eth-json-rpc-middleware-6.0.0.tgz#4fe16928b34231a2537856f08a5ebbc3d0c31175" - integrity sha512-qqBfLU2Uq1Ou15Wox1s+NX05S9OcAEL4JZ04VZox2NS0U+RtCMjSxzXhLFWekdShUPZ+P8ax3zCO2xcPrp6XJQ== - dependencies: - btoa "^1.2.1" - clone "^2.1.1" - eth-query "^2.1.2" - eth-rpc-errors "^3.0.0" - eth-sig-util "^1.4.2" - ethereumjs-util "^5.1.2" - json-rpc-engine "^5.3.0" - json-stable-stringify "^1.0.1" - node-fetch "^2.6.1" - pify "^3.0.0" - safe-event-emitter "^1.0.1" - -eth-lib@0.2.8: - version "0.2.8" - resolved "https://registry.yarnpkg.com/eth-lib/-/eth-lib-0.2.8.tgz#b194058bef4b220ad12ea497431d6cb6aa0623c8" - integrity sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw== - dependencies: - bn.js "^4.11.6" - elliptic "^6.4.0" - xhr-request-promise "^0.1.2" - -eth-lib@^0.1.26: - version "0.1.29" - resolved "https://registry.yarnpkg.com/eth-lib/-/eth-lib-0.1.29.tgz#0c11f5060d42da9f931eab6199084734f4dbd1d9" - integrity sha512-bfttrr3/7gG4E02HoWTDUcDDslN003OlOoBxk9virpAZQ1ja/jDgwkWB8QfJF7ojuEowrqy+lzp9VcJG7/k5bQ== - dependencies: - bn.js "^4.11.6" - elliptic "^6.4.0" - nano-json-stream-parser "^0.1.2" - servify "^0.1.12" - ws "^3.0.0" - xhr-request-promise "^0.1.2" - -eth-query@^2.1.0, eth-query@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/eth-query/-/eth-query-2.1.2.tgz#d6741d9000106b51510c72db92d6365456a6da5e" - integrity sha512-srES0ZcvwkR/wd5OQBRA1bIJMww1skfGS0s8wlwK3/oNP4+wnds60krvu5R1QbpRQjMmpG5OMIWro5s7gvDPsA== - dependencies: - json-rpc-random-id "^1.0.0" - xtend "^4.0.1" - -eth-rpc-errors@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/eth-rpc-errors/-/eth-rpc-errors-3.0.0.tgz#d7b22653c70dbf9defd4ef490fd08fe70608ca10" - integrity sha512-iPPNHPrLwUlR9xCSYm7HHQjWBasor3+KZfRvwEWxMz3ca0yqnlBeJrnyphkGIXZ4J7AMAaOLmwy4AWhnxOiLxg== - dependencies: - fast-safe-stringify "^2.0.6" - -eth-rpc-errors@^4.0.2: - version "4.0.3" - resolved "https://registry.yarnpkg.com/eth-rpc-errors/-/eth-rpc-errors-4.0.3.tgz#6ddb6190a4bf360afda82790bb7d9d5e724f423a" - integrity sha512-Z3ymjopaoft7JDoxZcEb3pwdGh7yiYMhOwm2doUt6ASXlMavpNlK6Cre0+IMl2VSGyEU9rkiperQhp5iRxn5Pg== - dependencies: - fast-safe-stringify "^2.0.6" - -eth-sig-util@^1.4.2: - version "1.4.2" - resolved "https://registry.yarnpkg.com/eth-sig-util/-/eth-sig-util-1.4.2.tgz#8d958202c7edbaae839707fba6f09ff327606210" - integrity sha512-iNZ576iTOGcfllftB73cPB5AN+XUQAT/T8xzsILsghXC1o8gJUqe3RHlcDqagu+biFpYQ61KQrZZJza8eRSYqw== - dependencies: - ethereumjs-abi "git+https://github.com/ethereumjs/ethereumjs-abi.git" - ethereumjs-util "^5.1.1" - 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" @@ -4079,16 +3140,6 @@ ethereum-bloom-filters@^1.0.6: dependencies: js-sha3 "^0.8.0" -ethereum-common@0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/ethereum-common/-/ethereum-common-0.2.0.tgz#13bf966131cce1eeade62a1b434249bb4cb120ca" - integrity sha512-XOnAR/3rntJgbCdGhqdaLIxDLWKLmsZOGhHdBKadEr6gEnJLH52k93Ou+TUdFaPN3hJc3isBZBal3U/XZ15abA== - -ethereum-common@^0.0.18: - version "0.0.18" - resolved "https://registry.yarnpkg.com/ethereum-common/-/ethereum-common-0.0.18.tgz#2fdc3576f232903358976eb39da783213ff9523f" - integrity sha512-EoltVQTRNg2Uy4o84qpa2aXymXDJhxm7eos/ACOg0DG4baAbMjhbdAEsx9GeE8sC3XCxnYvrrzZDH8D8MtA2iQ== - 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" @@ -4110,16 +3161,6 @@ ethereum-cryptography@0.1.3, ethereum-cryptography@^0.1.3: secp256k1 "^4.0.1" setimmediate "^1.0.5" -ethereum-cryptography@1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/ethereum-cryptography/-/ethereum-cryptography-1.1.2.tgz#74f2ac0f0f5fe79f012c889b3b8446a9a6264e6d" - integrity sha512-XDSJlg4BD+hq9N2FjvotwUET9Tfxpxc3kWGE2AqUG5vcbeunnbImVk3cj6e/xT3phdW21mE8R5IugU4fspQDcQ== - dependencies: - "@noble/hashes" "1.1.2" - "@noble/secp256k1" "1.6.3" - "@scure/bip32" "1.1.0" - "@scure/bip39" "1.1.0" - ethereum-cryptography@^1.0.3: version "1.2.0" resolved "https://registry.yarnpkg.com/ethereum-cryptography/-/ethereum-cryptography-1.2.0.tgz#5ccfa183e85fdaf9f9b299a79430c044268c9b3a" @@ -4131,19 +3172,14 @@ ethereum-cryptography@^1.0.3: "@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== + version "2.1.3" + resolved "https://registry.yarnpkg.com/ethereum-cryptography/-/ethereum-cryptography-2.1.3.tgz#1352270ed3b339fe25af5ceeadcf1b9c8e30768a" + integrity sha512-BlwbIL7/P45W8FGW2r7LGuvoEZ+7PWsniMvQ4p5s2xCyw9tmaDlpfsN9HjAucbF+t/qpVHwZUisgfK24TCW8aA== dependencies: - "@noble/curves" "1.1.0" - "@noble/hashes" "1.3.1" - "@scure/bip32" "1.3.1" - "@scure/bip39" "1.2.1" - -ethereum-protocol@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/ethereum-protocol/-/ethereum-protocol-1.0.1.tgz#b7d68142f4105e0ae7b5e178cf42f8d4dc4b93cf" - integrity sha512-3KLX1mHuEsBW0dKG+c6EOJS1NBNqdCICvZW9sInmZTt5aY0oxmHVggYRE0lJu1tcnMD1K+AKHdLi6U43Awm1Vg== + "@noble/curves" "1.3.0" + "@noble/hashes" "1.3.3" + "@scure/bip32" "1.3.3" + "@scure/bip39" "1.2.2" ethereum-waffle@^4.0.10: version "4.0.10" @@ -4165,65 +3201,6 @@ ethereumjs-abi@0.6.8, ethereumjs-abi@^0.6.8: bn.js "^4.11.8" ethereumjs-util "^6.0.0" -"ethereumjs-abi@git+https://github.com/ethereumjs/ethereumjs-abi.git": - version "0.6.8" - resolved "git+https://github.com/ethereumjs/ethereumjs-abi.git#ee3994657fa7a427238e6ba92a84d0b529bbcde0" - dependencies: - bn.js "^4.11.8" - ethereumjs-util "^6.0.0" - -ethereumjs-account@^2.0.3: - version "2.0.5" - resolved "https://registry.yarnpkg.com/ethereumjs-account/-/ethereumjs-account-2.0.5.tgz#eeafc62de544cb07b0ee44b10f572c9c49e00a84" - integrity sha512-bgDojnXGjhMwo6eXQC0bY6UK2liSFUSMwwylOmQvZbSl/D7NXQ3+vrGO46ZeOgjGfxXmgIeVNDIiHw7fNZM4VA== - dependencies: - ethereumjs-util "^5.0.0" - rlp "^2.0.0" - safe-buffer "^5.1.1" - -ethereumjs-block@^1.2.2: - version "1.7.1" - resolved "https://registry.yarnpkg.com/ethereumjs-block/-/ethereumjs-block-1.7.1.tgz#78b88e6cc56de29a6b4884ee75379b6860333c3f" - integrity sha512-B+sSdtqm78fmKkBq78/QLKJbu/4Ts4P2KFISdgcuZUPDm9x+N7qgBPIIFUGbaakQh8bzuquiRVbdmvPKqbILRg== - dependencies: - async "^2.0.1" - ethereum-common "0.2.0" - ethereumjs-tx "^1.2.2" - ethereumjs-util "^5.0.0" - merkle-patricia-tree "^2.1.2" - -ethereumjs-block@~2.2.0: - version "2.2.2" - resolved "https://registry.yarnpkg.com/ethereumjs-block/-/ethereumjs-block-2.2.2.tgz#c7654be7e22df489fda206139ecd63e2e9c04965" - integrity sha512-2p49ifhek3h2zeg/+da6XpdFR3GlqY3BIEiqxGF8j9aSRIgkb7M1Ky+yULBKJOu8PAZxfhsYA+HxUk2aCQp3vg== - dependencies: - async "^2.0.1" - ethereumjs-common "^1.5.0" - ethereumjs-tx "^2.1.1" - ethereumjs-util "^5.0.0" - merkle-patricia-tree "^2.1.2" - -ethereumjs-common@^1.1.0, ethereumjs-common@^1.5.0: - version "1.5.2" - resolved "https://registry.yarnpkg.com/ethereumjs-common/-/ethereumjs-common-1.5.2.tgz#2065dbe9214e850f2e955a80e650cb6999066979" - integrity sha512-hTfZjwGX52GS2jcVO6E2sx4YuFnf0Fhp5ylo4pEPhEffNln7vS59Hr5sLnp3/QCazFLluuBZ+FZ6J5HTp0EqCA== - -ethereumjs-tx@^1.2.2: - version "1.3.7" - resolved "https://registry.yarnpkg.com/ethereumjs-tx/-/ethereumjs-tx-1.3.7.tgz#88323a2d875b10549b8347e09f4862b546f3d89a" - integrity sha512-wvLMxzt1RPhAQ9Yi3/HKZTn0FZYpnsmQdbKYfUUpi4j1SEIcbkd9tndVjcPrufY3V7j2IebOpC00Zp2P/Ay2kA== - dependencies: - ethereum-common "^0.0.18" - ethereumjs-util "^5.0.0" - -ethereumjs-tx@^2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/ethereumjs-tx/-/ethereumjs-tx-2.1.2.tgz#5dfe7688bf177b45c9a23f86cf9104d47ea35fed" - integrity sha512-zZEK1onCeiORb0wyCXUvg94Ve5It/K6GD1K+26KfFKodiBiS6d9lfCXlUKGBBdQ+bv7Day+JK0tj1K+BeNFRAw== - dependencies: - ethereumjs-common "^1.5.0" - ethereumjs-util "^6.0.0" - ethereumjs-util@6.2.1, 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" @@ -4248,20 +3225,7 @@ ethereumjs-util@7.1.3: ethereum-cryptography "^0.1.3" rlp "^2.2.4" -ethereumjs-util@^5.0.0, ethereumjs-util@^5.1.1, ethereumjs-util@^5.1.2, ethereumjs-util@^5.1.5: - version "5.2.1" - resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz#a833f0e5fca7e5b361384dc76301a721f537bf65" - integrity sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ== - dependencies: - bn.js "^4.11.0" - create-hash "^1.1.2" - elliptic "^6.5.2" - ethereum-cryptography "^0.1.3" - ethjs-util "^0.1.3" - rlp "^2.0.0" - safe-buffer "^5.1.1" - -ethereumjs-util@^7.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: +ethereumjs-util@^7.1.0, ethereumjs-util@^7.1.1, 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== @@ -4272,38 +3236,7 @@ ethereumjs-util@^7.1.0, ethereumjs-util@^7.1.1, ethereumjs-util@^7.1.2, ethereum ethereum-cryptography "^0.1.3" rlp "^2.2.4" -ethereumjs-vm@^2.3.4: - version "2.6.0" - resolved "https://registry.yarnpkg.com/ethereumjs-vm/-/ethereumjs-vm-2.6.0.tgz#76243ed8de031b408793ac33907fb3407fe400c6" - integrity sha512-r/XIUik/ynGbxS3y+mvGnbOKnuLo40V5Mj1J25+HEO63aWYREIqvWeRO/hnROlMBE5WoniQmPmhiaN0ctiHaXw== - dependencies: - async "^2.1.2" - async-eventemitter "^0.2.2" - ethereumjs-account "^2.0.3" - ethereumjs-block "~2.2.0" - ethereumjs-common "^1.1.0" - ethereumjs-util "^6.0.0" - fake-merkle-patricia-tree "^1.0.1" - functional-red-black-tree "^1.0.1" - merkle-patricia-tree "^2.3.2" - rustbn.js "~0.2.0" - safe-buffer "^5.1.1" - -ethereumjs-wallet@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/ethereumjs-wallet/-/ethereumjs-wallet-1.0.2.tgz#2c000504b4c71e8f3782dabe1113d192522e99b6" - integrity sha512-CCWV4RESJgRdHIvFciVQFnCHfqyhXWchTPlkfp28Qc53ufs+doi5I/cV2+xeK9+qEo25XCWfP9MiL+WEPAZfdA== - dependencies: - aes-js "^3.1.2" - bs58check "^2.1.2" - ethereum-cryptography "^0.1.3" - ethereumjs-util "^7.1.2" - randombytes "^2.1.0" - scrypt-js "^3.0.1" - utf8 "^3.0.0" - uuid "^8.3.2" - -ethers@^5.6.8, ethers@^5.7.0, ethers@^5.7.1, ethers@^5.7.2: +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== @@ -4347,7 +3280,7 @@ ethjs-unit@0.1.6: bn.js "4.11.6" number-to-bn "1.7.0" -ethjs-util@0.1.6, ethjs-util@^0.1.3, ethjs-util@^0.1.6: +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== @@ -4355,16 +3288,6 @@ ethjs-util@0.1.6, ethjs-util@^0.1.3, ethjs-util@^0.1.6: is-hex-prefixed "1.0.0" strip-hex-prefix "1.0.0" -eventemitter3@4.0.4: - version "4.0.4" - resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.4.tgz#b5463ace635a083d018bdc7c917b4c5f10a85384" - integrity sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ== - -events@^3.0.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" - integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== - evp_bytestokey@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" @@ -4386,50 +3309,6 @@ execa@^1.0.0: signal-exit "^3.0.0" strip-eof "^1.0.0" -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" @@ -4445,13 +3324,6 @@ extsprintf@^1.2.0: resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.1.tgz#8d172c064867f235c0c84a596806d279bf4bcc07" integrity sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA== -fake-merkle-patricia-tree@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/fake-merkle-patricia-tree/-/fake-merkle-patricia-tree-1.0.1.tgz#4b8c3acfb520afadf9860b1f14cd8ce3402cddd3" - integrity sha512-Tgq37lkc9pUIgIKw5uitNUKcgcYL3R6JvXtKQbOf/ZSavXbidsksgp/pAY6p//uhw0I4yoMsvTSovvVIsk/qxA== - dependencies: - checkpoint-store "^1.1.0" - fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" @@ -4483,15 +3355,10 @@ fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6: resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== -fast-safe-stringify@^2.0.6: - version "2.1.1" - resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz#c406a83b6e70d9e35ce3b30a81141df30aeba884" - integrity sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA== - 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== + version "1.17.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.17.0.tgz#ca5e1a90b5e68f97fc8b61330d5819b82f5fab03" + integrity sha512-zGygtijUMT7jnk3h26kUms3BkSDp4IfIKjmnqI2tvx6nuBfiF1UqOxbnLfzdv+apBy+53oaImsKtMw/xYbW+1w== dependencies: reusify "^1.0.4" @@ -4509,19 +3376,6 @@ fill-range@^7.0.1: 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" @@ -4552,9 +3406,9 @@ find-up@^3.0.0: locate-path "^3.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== + version "3.2.0" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.2.0.tgz#2c0c2d5040c99b1632771a9d105725c0115363ee" + integrity sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw== dependencies: flatted "^3.2.9" keyv "^4.5.3" @@ -4577,10 +3431,10 @@ fmix@^0.1.0: 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== +follow-redirects@^1.12.1, follow-redirects@^1.14.0, follow-redirects@^1.15.4: + version "1.15.5" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.5.tgz#54d4d6d062c0fa7d9d17feb008461550e3ba8020" + integrity sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw== for-each@^0.3.3: version "0.3.3" @@ -4594,10 +3448,10 @@ forever-agent@~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== +forge-std@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/forge-std/-/forge-std-1.1.2.tgz#f4a0eda103538d56f9c563f3cd1fa2fd01bd9378" + integrity sha512-Wfb0iAS9PcfjMKtGpWQw9mXzJxrWD62kJCUqqLcyuI0+VRtJ3j20XembjF3kS20qELYdXft1vD/SPFVWVKMFOw== form-data@^2.2.0: version "2.5.1" @@ -4626,11 +3480,6 @@ form-data@~2.3.2: 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" @@ -4641,11 +3490,6 @@ fp-ts@^1.0.0: 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" @@ -4666,15 +3510,6 @@ fs-extra@^10.0.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" @@ -4703,13 +3538,6 @@ fs-extra@^9.1.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" @@ -4777,9 +3605,9 @@ ganache@7.4.3: utf-8-validate "5.0.7" ganache@^7.1.0: - version "7.9.1" - resolved "https://registry.yarnpkg.com/ganache/-/ganache-7.9.1.tgz#94f8518215c7989ff5fd542db80bd47d7c7da786" - integrity sha512-Tqhd4J3cpiLeYTD6ek/zlchSB107IVPMIm4ypyg+xz1sdkeALUnYYZnmY4Bdjqj3i6QwtlZPCu7U4qKy7HlWTA== + version "7.9.2" + resolved "https://registry.yarnpkg.com/ganache/-/ganache-7.9.2.tgz#77f506ad2735dd9109696ffa1834a9dd2f806449" + integrity sha512-7gsVVDpO9AhrFyDMWWl7SpMsPpqGcnAzjxz3k32LheIPNd64p2XsY9GYRdhWmKuryb60W1iaWPZWDkFKlbRWHA== dependencies: "@trufflesuite/bigint-buffer" "1.1.10" "@trufflesuite/uws-js-unofficial" "20.30.0-unofficial.0" @@ -4829,18 +3657,6 @@ get-stream@^4.0.0: dependencies: pump "^3.0.0" -get-stream@^5.1.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" - integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== - dependencies: - pump "^3.0.0" - -get-stream@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" - integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== - get-symbol-description@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz#7fdb81c900101fbd564dd5f1a30af5aadc1e58d6" @@ -4959,18 +3775,10 @@ global-prefix@^3.0.0: 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.19.0: - version "13.23.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-13.23.0.tgz#ef31673c926a0976e1f61dab4dca57e0c0a8af02" - integrity sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA== +globals@^13.19.0, globals@^13.24.0: + version "13.24.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.24.0.tgz#8432a19d78ce0c1e833949c36adb345400bb1171" + integrity sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ== dependencies: type-fest "^0.20.2" @@ -5014,42 +3822,6 @@ gopd@^1.0.1: 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" @@ -5085,15 +3857,10 @@ har-validator@~5.1.3: ajv "^6.12.3" har-schema "^2.0.0" -hardhat-deploy-ethers@^0.3.0-beta.11: - 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== - 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== + version "0.11.45" + resolved "https://registry.yarnpkg.com/hardhat-deploy/-/hardhat-deploy-0.11.45.tgz#bed86118175a38a03bb58aba2ce1ed5e80a20bc8" + integrity sha512-aC8UNaq3JcORnEUIwV945iJuvBwi65tjHVDU3v6mOcqik7WAzHVCJ7cwmkkipsHrWysrB5YvGF1q9S1vIph83w== dependencies: "@ethersproject/abi" "^5.7.0" "@ethersproject/abstract-signer" "^5.7.0" @@ -5120,35 +3887,7 @@ hardhat-deploy@^0.11.26: qs "^6.9.4" zksync-web3 "^0.14.3" -hardhat-deploy@^0.9.3: - version "0.9.29" - resolved "https://registry.yarnpkg.com/hardhat-deploy/-/hardhat-deploy-0.9.29.tgz#b1177d4f3077f335ad3f50c55825d9417ec75968" - integrity sha512-8tIGszPFmOaXtyloCbASiZPvoAgLNGGL/Ubys3YW/oj4dvoPa8G6YDyaOCdsAhsENZ+QgR280NFSG9JdN7SU9Q== - dependencies: - "@ethersproject/abi" "^5.4.0" - "@ethersproject/abstract-signer" "^5.4.1" - "@ethersproject/address" "^5.4.0" - "@ethersproject/bignumber" "^5.4.1" - "@ethersproject/bytes" "^5.4.0" - "@ethersproject/constants" "^5.4.0" - "@ethersproject/contracts" "^5.4.1" - "@ethersproject/providers" "^5.4.4" - "@ethersproject/solidity" "^5.4.0" - "@ethersproject/transactions" "^5.4.0" - "@ethersproject/wallet" "^5.4.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" - form-data "^4.0.0" - fs-extra "^10.0.0" - match-all "^1.2.6" - murmur-128 "^0.2.1" - qs "^6.9.4" - -hardhat-gas-reporter@^1.0.7, hardhat-gas-reporter@^1.0.9: +hardhat-gas-reporter@^1.0.9: 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== @@ -5157,17 +3896,10 @@ hardhat-gas-reporter@^1.0.7, hardhat-gas-reporter@^1.0.9: 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.13.0, hardhat@^2.14.0, hardhat@^2.9.5: - version "2.19.0" - resolved "https://registry.yarnpkg.com/hardhat/-/hardhat-2.19.0.tgz#1e08658863550ba351788ea128e544ff80584a31" - integrity sha512-kMpwovOEfrFRQXEopCP+JTcKVwSYVj8rnXE0LynxDqnh06yvyKCQknmXL6IVYTHQL6Csysc/yNbCHQbjSeJGpA== +hardhat@^2.14.0: + version "2.19.4" + resolved "https://registry.yarnpkg.com/hardhat/-/hardhat-2.19.4.tgz#5112c30295d8be2e18e55d847373c50483ed1902" + integrity sha512-fTQJpqSt3Xo9Mn/WrdblNGAfcANM6XC3tAEi6YogB4s02DmTf93A8QsGb8uR0KR8TFcpcS8lgiW4ugAIYpnbrQ== dependencies: "@ethersproject/abi" "^5.1.2" "@metamask/eth-sig-util" "^4.0.0" @@ -5238,7 +3970,7 @@ has-flag@^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: +has-property-descriptors@^1.0.0, has-property-descriptors@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz#52ba30b6c5ec87fd89fa574bc1c39125c6f65340" integrity sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg== @@ -5320,11 +4052,6 @@ http-basic@^8.1.1: 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" @@ -5336,11 +4063,6 @@ http-errors@2.0.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" @@ -5357,22 +4079,6 @@ http-signature@~1.2.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" @@ -5393,22 +4099,15 @@ iconv-lite@0.4.24: 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@^5.1.1, 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== + version "5.3.0" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.0.tgz#67418ae40d34d6999c95ff56016759c718c82f78" + integrity sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg== immediate@^3.2.3: version "3.3.0" @@ -5421,9 +4120,9 @@ immediate@~3.2.3: 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== + version "4.3.5" + resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.3.5.tgz#f8b436e66d59f99760dc577f5c99a4fd2a5cc5a0" + integrity sha512-8eabxkth9gZatlwl5TBuJnCsoTADlL6ftEr7A4qgdaTsPyreilDSnUk57SO+jfKcNtxPa22U5KK6DSeAYhpBJw== import-fresh@^3.2.1, import-fresh@^3.3.0: version "3.3.0" @@ -5492,19 +4191,6 @@ io-ts@1.10.4: 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" @@ -5546,6 +4232,13 @@ is-buffer@^2.0.5: resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.5.tgz#ebc252e400d22ff8d77fa09888821a24a658c191" integrity sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ== +is-builtin-module@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-3.2.1.tgz#f03271717d8654cfcaf07ab0463faa3571581169" + integrity sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A== + dependencies: + builtin-modules "^3.3.0" + is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7: version "1.2.7" resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" @@ -5570,11 +4263,6 @@ is-extglob@^2.1.1: resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== -is-fn@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-fn/-/is-fn-1.0.0.tgz#9543d5de7bcf5b08a22ec8a20bae6e286d510d8c" - integrity sha512-XoFPJQmsAShb3jEQRfzf2rqXavq7fIqF/jOekp308JlThqrODnMpweVSGilKTCXELfLhltGP2AGgbQGVP8F1dg== - 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" @@ -5585,18 +4273,6 @@ is-fullwidth-code-point@^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" @@ -5670,14 +4346,14 @@ is-symbol@^1.0.2, is-symbol@^1.0.3: 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: +is-typed-array@^1.1.10, is-typed-array@^1.1.12, 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: +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== @@ -5699,11 +4375,6 @@ is-weakref@^1.0.2: dependencies: call-bind "^1.0.2" -isarray@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" - integrity sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ== - isarray@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" @@ -5734,11 +4405,6 @@ js-sha3@0.8.0, js-sha3@^0.8.0: resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840" integrity sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q== -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-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" @@ -5759,11 +4425,6 @@ js-yaml@4.1.0, js-yaml@^4.1.0: 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" @@ -5786,27 +4447,6 @@ json-parse-even-better-errors@^2.3.0: 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-rpc-engine@^5.3.0: - version "5.4.0" - resolved "https://registry.yarnpkg.com/json-rpc-engine/-/json-rpc-engine-5.4.0.tgz#75758609d849e1dba1e09021ae473f3ab63161e5" - integrity sha512-rAffKbPoNDjuRnXkecTjnsE3xLLrb00rEkdgalINhaYVYIxDwWtvYBr9UFbhTvPB1B2qUOLoFd/cV6f4Q7mh7g== - dependencies: - eth-rpc-errors "^3.0.0" - safe-event-emitter "^1.0.1" - -json-rpc-engine@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/json-rpc-engine/-/json-rpc-engine-6.1.0.tgz#bf5ff7d029e1c1bf20cb6c0e9f348dcd8be5a393" - integrity sha512-NEdLrtrq1jUZyfjkr9OCz9EzCNhnRyWtt1PAnvnhwy6e8XETS0Dtc+ZNCO2gvuAoKsIn2+vCSowXTYE4CkgnAQ== - dependencies: - "@metamask/safe-event-emitter" "^2.0.0" - eth-rpc-errors "^4.0.2" - -json-rpc-random-id@^1.0.0, json-rpc-random-id@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json-rpc-random-id/-/json-rpc-random-id-1.0.1.tgz#ba49d96aded1444dbb8da3d203748acbbcdec8c8" - integrity sha512-RJ9YYNCkhVDBuP4zN5BBtYAzEl03yq/jIIsyif0JY9qyJuQQZNeDK7anAPKKlyEtLSj2s8h6hNh2F8zO5q7ScA== - 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" @@ -5827,13 +4467,6 @@ json-stable-stringify-without-jsonify@^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-stable-stringify@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.2.tgz#e06f23128e0bbe342dc996ed5a19e28b57b580e0" - integrity sha512-eunSSaEnxV12z+Z73y/j5N37/In40GK4GmsSy+tEHJMxknvqnA7/djeYtAgW0GsWHUfg+847WJjKaEylk2y09g== - dependencies: - jsonify "^0.0.1" - 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" @@ -5869,11 +4502,6 @@ jsonfile@^6.0.1: optionalDependencies: graceful-fs "^4.1.6" -jsonify@^0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.1.tgz#2aa3111dae3d34a0f151c63f3a45d995d9420978" - integrity sha512-2/Ki0GcmuqSrgFyelQq9M05y7PS0mEwuIzrf3f1fPqkVDVRvZrPZtVSMHxdgo8Aq0sxAOb/cr2aqqA3LeWHVPg== - jsonschema@^1.2.4: version "1.4.1" resolved "https://registry.yarnpkg.com/jsonschema/-/jsonschema-1.4.1.tgz#cc4c3f0077fb4542982973d8a083b6b34f482dab" @@ -5915,7 +4543,7 @@ keccak@^3.0.0, keccak@^3.0.2: node-gyp-build "^4.2.0" readable-stream "^3.6.0" -keyv@^4.0.0, keyv@^4.5.3: +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== @@ -5948,11 +4576,6 @@ level-codec@^9.0.0: dependencies: buffer "^5.6.0" -level-codec@~7.0.0: - version "7.0.1" - resolved "https://registry.yarnpkg.com/level-codec/-/level-codec-7.0.1.tgz#341f22f907ce0f16763f24bddd681e395a0fb8a7" - integrity sha512-Ua/R9B9r3RasXdRmOtd+t9TCOEIIlts+TN/7XTT2unhDaL6sJn83S3rUyljbr6lVtw49N3/yA0HHjpV6Kzb2aQ== - level-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" @@ -5965,13 +4588,6 @@ level-concat-iterator@~2.0.0: resolved "https://registry.yarnpkg.com/level-concat-iterator/-/level-concat-iterator-2.0.1.tgz#1d1009cf108340252cb38c51f9727311193e6263" integrity sha512-OTKKOqeav2QWcERMJR7IS9CUo1sHnke2C0gkSmcR7QuEtFNLLzHQAvnMw8ykvEcv0Qtkg0p7FOwP1v9e5Smdcw== -level-errors@^1.0.3: - version "1.1.2" - resolved "https://registry.yarnpkg.com/level-errors/-/level-errors-1.1.2.tgz#4399c2f3d3ab87d0625f7e3676e2d807deff404d" - integrity sha512-Sw/IJwWbPKF5Ai4Wz60B52yj0zYeqzObLh8k1Tk88jVmD51cJSKWSYpRyhVIvFzZdvsPqlH5wfhp/yxdsaQH4w== - dependencies: - errno "~0.1.1" - level-errors@^2.0.0, level-errors@~2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/level-errors/-/level-errors-2.0.1.tgz#2132a677bf4e679ce029f517c2f17432800c05c8" @@ -5979,23 +4595,6 @@ level-errors@^2.0.0, level-errors@~2.0.0: dependencies: errno "~0.1.1" -level-errors@~1.0.3: - version "1.0.5" - resolved "https://registry.yarnpkg.com/level-errors/-/level-errors-1.0.5.tgz#83dbfb12f0b8a2516bdc9a31c4876038e227b859" - integrity sha512-/cLUpQduF6bNrWuAC4pwtUKA5t669pCsCi2XbmojG2tFeOr9j6ShtdDCtFFQO1DRt+EVZhx9gPzP9G2bUaG4ig== - dependencies: - errno "~0.1.1" - -level-iterator-stream@~1.3.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/level-iterator-stream/-/level-iterator-stream-1.3.1.tgz#e43b78b1a8143e6fa97a4f485eb8ea530352f2ed" - integrity sha512-1qua0RHNtr4nrZBgYlpV0qHHeHpcRRWTxEZJ8xsemoHAXNL5tbooh4tPEEqIqsbWCAJBmUmkwYK/sW5OrFjWWw== - dependencies: - inherits "^2.0.1" - level-errors "^1.0.3" - readable-stream "^1.0.33" - xtend "^4.0.0" - 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" @@ -6046,14 +4645,6 @@ level-transcoder@^1.0.1: buffer "^6.0.3" module-error "^1.0.1" -level-ws@0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/level-ws/-/level-ws-0.0.0.tgz#372e512177924a00424b0b43aef2bb42496d228b" - integrity sha512-XUTaO/+Db51Uiyp/t7fCMGVFOTdtLS/NIACxE/GHsij15mKzxksZifKVjlXDF41JMUP/oM1Oc4YNGdKnc3dVLw== - dependencies: - readable-stream "~1.0.15" - xtend "~2.1.1" - level-ws@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/level-ws/-/level-ws-2.0.0.tgz#207a07bcd0164a0ec5d62c304b4615c54436d339" @@ -6064,10 +4655,11 @@ level-ws@^2.0.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== + version "8.0.1" + resolved "https://registry.yarnpkg.com/level/-/level-8.0.1.tgz#737161db1bc317193aca4e7b6f436e7e1df64379" + integrity sha512-oPBGkheysuw7DmzFQYyFe8NAia5jFLAgEnkgWnK3OXAuJr8qFT+xBQIwokAZPME2bhPFzS8hlYcL16m8UZrtwQ== dependencies: + abstract-level "^1.0.4" browser-level "^1.0.1" classic-level "^1.2.0" @@ -6080,19 +4672,6 @@ leveldown@6.1.0: napi-macros "~2.0.0" node-gyp-build "^4.3.0" -levelup@^1.2.1: - version "1.3.9" - resolved "https://registry.yarnpkg.com/levelup/-/levelup-1.3.9.tgz#2dbcae845b2bb2b6bea84df334c475533bbd82ab" - integrity sha512-VVGHfKIlmw8w1XqpGOAGwq6sZm2WwWLmlDcULkKWQXEA5EopA8OBNJ2Ck2v6bdk8HeEZSbCSEgzXadyQFm76sQ== - dependencies: - deferred-leveldown "~1.2.1" - level-codec "~7.0.0" - level-errors "~1.0.3" - level-iterator-stream "~1.3.0" - prr "~1.0.1" - semver "~5.4.1" - xtend "~4.0.0" - levelup@^4.3.2: version "4.4.0" resolved "https://registry.yarnpkg.com/levelup/-/levelup-4.4.0.tgz#f89da3a228c38deb49c48f88a70fb71f01cafed6" @@ -6153,11 +4732,6 @@ lodash.camelcase@^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.debounce@^4.0.8: - version "4.0.8" - resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" - integrity sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow== - lodash.merge@^4.6.2: version "4.6.2" resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" @@ -6188,16 +4762,6 @@ loupe@^2.3.6: dependencies: get-func-name "^2.0.1" -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" @@ -6258,11 +4822,6 @@ md5.js@^1.3.4: 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== - mem@^4.0.0: version "4.3.0" resolved "https://registry.yarnpkg.com/mem/-/mem-4.3.0.tgz#461af497bc4ae09608cdb2e60eefb69bff744178" @@ -6272,18 +4831,6 @@ mem@^4.0.0: mimic-fn "^2.0.0" p-is-promise "^2.0.0" -memdown@^1.0.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/memdown/-/memdown-1.4.1.tgz#b4e4e192174664ffbae41361aa500f3119efe215" - integrity sha512-iVrGHZB8i4OQfM155xx8akvG9FIj+ht14DX5CQkCTG4EHzZ3d3sgckIf/Lm9ivZalEsFuEVnWv2B2WZvbrro2w== - dependencies: - abstract-leveldown "~2.7.1" - functional-red-black-tree "^1.0.1" - immediate "^3.2.3" - inherits "~2.0.1" - ltgt "~2.2.0" - safe-buffer "~5.1.1" - memdown@^5.0.0: version "5.1.0" resolved "https://registry.yarnpkg.com/memdown/-/memdown-5.1.0.tgz#608e91a9f10f37f5b5fe767667a8674129a833cb" @@ -6310,30 +4857,11 @@ memorystream@^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@^2.1.2, merkle-patricia-tree@^2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/merkle-patricia-tree/-/merkle-patricia-tree-2.3.2.tgz#982ca1b5a0fde00eed2f6aeed1f9152860b8208a" - integrity sha512-81PW5m8oz/pz3GvsAwbauj7Y00rqm81Tzad77tHBwU7pIAtN+TJnMSOJhxBKflSVYhptMMb9RskhqHqrSm1V+g== - dependencies: - async "^1.4.2" - ethereumjs-util "^5.0.0" - level-ws "0.0.0" - levelup "^1.2.1" - memdown "^1.0.0" - readable-stream "^2.0.0" - rlp "^2.0.0" - semaphore ">=1.0.1" - 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" @@ -6357,11 +4885,6 @@ merkletreejs@^0.3.9: treeify "^1.1.0" web3-utils "^1.3.4" -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" @@ -6388,40 +4911,18 @@ mime-db@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: +mime-types@^2.1.12, mime-types@~2.1.19: version "2.1.35" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== dependencies: mime-db "1.52.0" -mime@1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" - integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== - mimic-fn@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== -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" @@ -6446,6 +4947,13 @@ minimatch@5.0.1: dependencies: brace-expansion "^2.0.1" +minimatch@9.0.3: + version "9.0.3" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.3.tgz#a6e00c3de44c3a542bfaae70abfc22420a6da825" + integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg== + dependencies: + brace-expansion "^2.0.1" + minimatch@^5.0.1: version "5.1.6" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96" @@ -6458,34 +4966,7 @@ minimist@^1.2.0, minimist@^1.2.5, minimist@^1.2.6: 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: +mkdirp@0.5.x, mkdirp@^0.5.1: version "0.5.6" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== @@ -6504,7 +4985,7 @@ mnemonist@^0.38.0: dependencies: obliterator "^2.0.0" -mocha@10.2.0, mocha@^10.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== @@ -6531,11 +5012,6 @@ mocha@10.2.0, mocha@^10.0.0, mocha@^10.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" @@ -6556,46 +5032,6 @@ ms@2.1.3, ms@^2.1.1: 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" @@ -6605,11 +5041,6 @@ murmur-128@^0.2.1: fmix "^0.1.0" imul "^1.0.0" -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" @@ -6630,21 +5061,11 @@ natural-compare@^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== - nice-try@^1.0.4: version "1.0.5" resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" @@ -6662,7 +5083,7 @@ node-emoji@^1.10.0: dependencies: lodash "^4.17.21" -node-fetch@^2.6.0, node-fetch@^2.6.1, node-fetch@^2.6.12, node-fetch@^2.6.7: +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== @@ -6680,14 +5101,9 @@ node-gyp-build@4.4.0: 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== - -node-releases@^2.0.13: - version "2.0.13" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.13.tgz#d5ed1627c23e3461e819b02e57b75e4899b1c81d" - integrity sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ== + version "4.8.0" + resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.8.0.tgz#3fee9c1731df4581a3f9ead74664369ff00d26dd" + integrity sha512-u6fs2AEUljNho3EYTJNBfImO5QTo/J/1Etd+NVdCj7qWKUSN/bSLkZwhDv7I+w/MSC6qJ4cknepkAYykDdK8og== nofilter@^3.1.0: version "3.1.0" @@ -6706,11 +5122,6 @@ normalize-path@^3.0.0, normalize-path@~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== - npm-run-path@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" @@ -6731,7 +5142,7 @@ oauth-sign@~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: +object-assign@^4.1.0: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== @@ -6746,18 +5157,13 @@ object-keys@^1.1.1: resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== -object-keys@~0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-0.4.0.tgz#28a6aae7428dd2c3a92f3d95f21335dd204e0336" - integrity sha512-ncrLw+X55z7bkl5PnUvHwFK9FcGuFYo9gtjws2XtSzL+aZ8tm830P60WJ0dSmFVaSalWieW5MD7kEdnXda9yJw== - 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== + version "4.1.5" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.5.tgz#3a833f9ab7fdb80fc9e8d2300c803d216d8fdbb0" + integrity sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ== dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" + call-bind "^1.0.5" + define-properties "^1.2.1" has-symbols "^1.0.3" object-keys "^1.1.1" @@ -6794,20 +5200,6 @@ obliterator@^2.0.0: 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" @@ -6858,16 +5250,6 @@ os-tmpdir@~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-defer@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c" @@ -6954,11 +5336,6 @@ parse-cache-control@^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@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" @@ -6969,11 +5346,6 @@ parse-json@^5.2.0: json-parse-even-better-errors "^2.3.0" lines-and-columns "^1.1.6" -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== - path-browserify@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-1.0.1.tgz#d98454a9c3753d5790860f16f68867b9e46be1fd" @@ -7009,11 +5381,6 @@ path-parse@^1.0.6, path-parse@^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@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" @@ -7040,31 +5407,16 @@ performance-now@^2.1.0: resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" integrity sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow== -picocolors@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" - integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== - 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@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" - integrity sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg== - 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== -pify@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-5.0.0.tgz#1f5eca3f5e87ebec28cc6d54a0e4aaf00acc127f" - integrity sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA== - pinst@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/pinst/-/pinst-3.0.0.tgz#80dec0a85f1f993c6084172020f3dbf512897eec" @@ -7075,11 +5427,6 @@ pluralize@^8.0.0: resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-8.0.0.tgz#1a6fa16a38d12a1901e0320fa017051c539ce3b1" integrity sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA== -precond@0.2: - version "0.2.3" - resolved "https://registry.yarnpkg.com/precond/-/precond-0.2.3.tgz#aa9591bcaa24923f1e0f4849d240f47efc1075ac" - integrity sha512-QCYG84SgGyGzqJ/vlMsxeXd/pgL/I94ixdNFyh1PusWmTCyVfPJjZ1K1jvHtsbfnXQs2TSkEP2fR7QiMZAnKFQ== - prelude-ls@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" @@ -7098,13 +5445,13 @@ prettier-linter-helpers@^1.0.0: 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== + version "1.3.1" + resolved "https://registry.yarnpkg.com/prettier-plugin-solidity/-/prettier-plugin-solidity-1.3.1.tgz#59944d3155b249f7f234dee29f433524b9a4abcf" + integrity sha512-MN4OP5I2gHAzHZG1wcuJl0FsLS3c4Cc5494bbg+6oQWBPuEamjwDvmGfFMZ6NFzsh3Efd9UUxeT7ImgjNH4ozA== dependencies: - "@solidity-parser/parser" "^0.16.0" - semver "^7.3.8" - solidity-comments-extractor "^0.0.7" + "@solidity-parser/parser" "^0.17.0" + semver "^7.5.4" + solidity-comments-extractor "^0.0.8" prettier@^2.3.1, prettier@^2.6.2, prettier@^2.8.3: version "2.8.8" @@ -7116,19 +5463,6 @@ process-nextick-args@~2.0.0: 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== - -promise-to-callback@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/promise-to-callback/-/promise-to-callback-1.0.0.tgz#5d2a749010bfb67d963598fcd3960746a68feef7" - integrity sha512-uhMIZmKM5ZteDMfLgJnoSq9GCwsNKrYau73Awf1jIy6/eUcuuZ3P+CD9zUv0kJsIUbU+x6uLNIhXhLHDs1pNPA== - dependencies: - is-fn "^1.0.0" - set-immediate-shim "^1.0.1" - promise@^8.0.0: version "8.3.0" resolved "https://registry.yarnpkg.com/promise/-/promise-8.3.0.tgz#8cb333d1edeb61ef23869fbb8a4ea0279ab60e0a" @@ -7136,14 +5470,6 @@ promise@^8.0.0: 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" @@ -7167,11 +5493,6 @@ pump@^3.0.0: 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" @@ -7182,13 +5503,6 @@ punycode@^2.1.0, punycode@^2.1.1: resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== -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" @@ -7201,25 +5515,11 @@ qs@~6.5.2: 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" @@ -7227,22 +5527,7 @@ randombytes@^2.0.1, randombytes@^2.1.0: 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: +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== @@ -7252,17 +5537,7 @@ raw-body@2.5.2, raw-body@^2.4.1: iconv-lite "0.4.24" unpipe "1.0.0" -readable-stream@^1.0.33: - version "1.1.14" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" - integrity sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ== - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.1" - isarray "0.0.1" - string_decoder "~0.10.x" - -readable-stream@^2.0.0, readable-stream@^2.2.2, readable-stream@^2.2.9: +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== @@ -7284,16 +5559,6 @@ readable-stream@^3.1.0, readable-stream@^3.4.0, readable-stream@^3.6.0: string_decoder "^1.1.1" util-deprecate "^1.0.1" -readable-stream@~1.0.15: - version "1.0.34" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" - integrity sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg== - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.1" - isarray "0.0.1" - string_decoder "~0.10.x" - readdirp@~3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" @@ -7320,11 +5585,6 @@ reduce-flatten@^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-tree@~0.1.1: version "0.1.27" resolved "https://registry.yarnpkg.com/regexp-tree/-/regexp-tree-0.1.27.tgz#2198f0ef54518ffa743fe74d983b56ffd631b6cd" @@ -7358,7 +5618,7 @@ req-from@^2.0.0: dependencies: resolve-from "^3.0.0" -request@^2.79.0, request@^2.85.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== @@ -7399,11 +5659,6 @@ require-main-filename@^2.0.0: resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== -resolve-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" @@ -7431,7 +5686,7 @@ resolve@1.17.0: dependencies: path-parse "^1.0.6" -resolve@^1.1.6, resolve@^1.10.1, resolve@^1.14.2, resolve@^1.22.2, resolve@^1.22.4: +resolve@^1.1.6, resolve@^1.10.1, resolve@^1.22.2, 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== @@ -7440,13 +5695,6 @@ resolve@^1.1.6, resolve@^1.10.1, resolve@^1.14.2, resolve@^1.22.2, resolve@^1.22 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" @@ -7481,7 +5729,7 @@ rlp@2.2.6: dependencies: bn.js "^4.11.1" -rlp@^2.0.0, rlp@^2.2.3, rlp@^2.2.4: +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== @@ -7508,16 +5756,16 @@ rustbn.js@~0.2.0: 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== + version "1.1.0" + resolved "https://registry.yarnpkg.com/safe-array-concat/-/safe-array-concat-1.1.0.tgz#8d0cae9cb806d6d1c06e08ab13d847293ebe0692" + integrity sha512-ZdQ0Jeb9Ofti4hbt5lX3T2JcAamT9hfzYU1MNB+z/jaEbB6wfFfPIR/zEORmZqobkCCJhSjodobH6WHNmJ97dg== dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.2.1" + call-bind "^1.0.5" + get-intrinsic "^1.2.2" 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: +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.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== @@ -7527,20 +5775,13 @@ safe-buffer@~5.1.0, safe-buffer@~5.1.1: resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== -safe-event-emitter@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/safe-event-emitter/-/safe-event-emitter-1.0.1.tgz#5b692ef22329ed8f69fdce607e50ca734f6f20af" - integrity sha512-e1wFe99A91XYYxoQbcq2ZJUWurxEyP8vfz7A7vuUe1s95q8r5ebraVaA1BukYJcpM6V16ugWoD9vngi8Ccu5fg== - dependencies: - events "^3.0.0" - safe-regex-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== + version "1.0.2" + resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.0.2.tgz#3ba32bdb3ea35f940ee87e5087c60ee786c3f6c5" + integrity sha512-83S9w6eFq12BBIJYvjMux6/dkirb8+4zJRA9cxNBVb7Wq5fJBW+Xze48WqR8pxua7bDuAaaAxtVVd4Idjp1dBQ== dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.1.3" + call-bind "^1.0.5" + get-intrinsic "^1.2.2" is-regex "^1.1.4" safe-regex@^2.1.1: @@ -7575,7 +5816,7 @@ sc-istanbul@^0.4.5: which "^1.1.1" wordwrap "^1.0.0" -scrypt-js@3.0.1, scrypt-js@^3.0.0, scrypt-js@^3.0.1: +scrypt-js@3.0.1, scrypt-js@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-3.0.1.tgz#d314a57c2aef69d1ad98a138a21fe9eafa9ee312" integrity sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA== @@ -7599,11 +5840,6 @@ semaphore-async-await@^1.5.1: resolved "https://registry.yarnpkg.com/semaphore-async-await/-/semaphore-async-await-1.5.1.tgz#857bef5e3644601ca4b9570b87e9df5ca12974fa" integrity sha512-b/ptP11hETwYWpeilHXXQiV5UJNJl7ZWWooKRE5eBIYWoom6dZ0SluCIdCtKycsMtZgKWE01/qAw6jblw1YVhg== -semaphore@>=1.0.1, semaphore@^1.0.3: - version "1.1.0" - resolved "https://registry.yarnpkg.com/semaphore/-/semaphore-1.1.0.tgz#aaad8b86b20fe8e9b32b16dc2ee682a8cd26a8aa" - integrity sha512-O4OZEaNtkMd/K0i6js9SL+gqy0ZCBMgUvlSqHKi4IBdjhe7wB8pwztUk1BbZ1fmrvpwFrPbHzqd2w5pTcJH6LA== - semver@^5.5.0: version "5.7.2" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" @@ -7614,37 +5850,13 @@ semver@^6.1.0, semver@^6.3.0, semver@^6.3.1: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== -semver@^7.0.0, semver@^7.3.4, semver@^7.3.8, semver@^7.5.2, semver@^7.5.3, semver@^7.5.4: +semver@^7.0.0, semver@^7.3.4, semver@^7.5.2, semver@^7.5.3, 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" -semver@~5.4.1: - version "5.4.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e" - integrity sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg== - -send@0.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" - serialize-javascript@6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" @@ -7652,41 +5864,21 @@ serialize-javascript@6.0.0: 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== + version "1.2.0" + resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.2.0.tgz#2f81dc6c16c7059bda5ab7c82c11f03a515ed8e1" + integrity sha512-4DBHDoyHlM1IRPGYcoxexgh67y4ueR53FKV1yyxwFMY7aCqcN/38M1+SwZ/qJQ8iLv7+ck385ot4CcisOAPT9w== dependencies: define-data-property "^1.1.1" - get-intrinsic "^1.2.1" + function-bind "^1.1.2" + get-intrinsic "^1.2.2" gopd "^1.0.1" - has-property-descriptors "^1.0.0" + has-property-descriptors "^1.0.1" set-function-name@^2.0.0: version "2.0.1" @@ -7697,11 +5889,6 @@ set-function-name@^2.0.0: functions-have-names "^1.2.3" has-property-descriptors "^1.0.0" -set-immediate-shim@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61" - integrity sha512-Li5AOqrZWCVA2n5kryzEmqai6bKSIvpz5oUJHPVj6+dsbD3X1ixtsY5tEnsaNpH3pFAHmG8eIHUrtEtohrg+UQ== - setimmediate@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" @@ -7775,20 +5962,6 @@ signal-exit@^3.0.0: resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== -simple-concat@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.1.tgz#f46976082ba35c2263f1c8ab5edfe26c41c9552f" - integrity sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q== - -simple-get@^2.7.0: - version "2.8.2" - resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-2.8.2.tgz#5708fb0919d440657326cd5fe7d2599d07705019" - integrity sha512-Ijd/rV5o+mSBBs4F/x9oDPtTx9Zb6X9brmnXvMW4J7IR15ngi9q5xxqWBKU744jTZiaXtxaPL7uHG6vtN8kUkw== - dependencies: - decompress-response "^3.3.0" - once "^1.3.1" - simple-concat "^1.0.0" - slash@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" @@ -7803,11 +5976,6 @@ slice-ansi@^4.0.0: astral-regex "^2.0.0" is-fullwidth-code-point "^3.0.0" -solady@^0.0.90: - version "0.0.90" - resolved "https://registry.yarnpkg.com/solady/-/solady-0.0.90.tgz#2075349dfa6909b05ed04031f3b609ddbcd73598" - integrity sha512-NSc0mkfJo2CeKfFfyED1qbBQ8ofvDFxpBb0BLJ/wx2ZN7vCAYl8sp/j6TIIMdPb0BDvOKl2Rie9dVum+KIKeVA== - solc@0.7.3: version "0.7.3" resolved "https://registry.yarnpkg.com/solc/-/solc-0.7.3.tgz#04646961bd867a744f63d2b4e3c0701ffdc7d78a" @@ -7837,9 +6005,9 @@ solc@0.8.15: tmp "0.0.33" 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== + version "0.8.24" + resolved "https://registry.yarnpkg.com/solc/-/solc-0.8.24.tgz#6e5693d28208d00a20ff2bdabc1dec85a5329bbb" + integrity sha512-G5yUqjTUPc8Np74sCFwfsevhBPlUifUOfhYrgyu6CmYlC6feSw0YS6eZW47XDT23k3JYdKx5nJ+Q7whCEmNcoA== dependencies: command-exists "^1.2.8" commander "^8.1.0" @@ -7882,24 +6050,25 @@ solhint@^3.3.7: prettier "^2.8.3" solidity-bytes-utils@^0.8.0: - version "0.8.0" - resolved "https://registry.yarnpkg.com/solidity-bytes-utils/-/solidity-bytes-utils-0.8.0.tgz#9d985a3c4aee68fbd532a9a065edade1c132442f" - integrity sha512-r109ZHEf7zTMm1ENW6/IJFDWilFR/v0BZnGuFgDHJUV80ByobnV2k3txvwQaJ9ApL+6XAfwqsw5VFzjALbQPCw== + version "0.8.2" + resolved "https://registry.yarnpkg.com/solidity-bytes-utils/-/solidity-bytes-utils-0.8.2.tgz#763d6a02fd093e93b3a97b742e97d540e66c29bd" + integrity sha512-cqXPYAV2auhpdKSTPuqji0CwpSceZDu95CzqSM/9tDJ2MoMaMsdHTpOIWtVw31BIqqGPNmIChCswzbw0tHaMTw== dependencies: - "@truffle/hdwallet-provider" latest + ds-test "github:dapphub/ds-test" + forge-std "^1.1.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-comments-extractor@^0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/solidity-comments-extractor/-/solidity-comments-extractor-0.0.8.tgz#f6e148ab0c49f30c1abcbecb8b8df01ed8e879f8" + integrity sha512-htM7Vn6LhHreR+EglVMd2s+sZhcXAirB1Zlyrv5zBuTxieCvjfnRpd7iZk75m/u6NOlEyQ94C6TWbBn2cY7w8g== 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== + version "0.8.6" + resolved "https://registry.yarnpkg.com/solidity-coverage/-/solidity-coverage-0.8.6.tgz#c7b18dc9edfeba11064726c37d96265f689c9478" + integrity sha512-vV03mA/0nNMskOdVwNarUcqk0N/aYdelxAbf6RZ5l84FcYHbqDTr2JXyeYMp4bT48qHtAQjnKrygW1FrECyWNw== dependencies: "@ethersproject/abi" "^5.0.9" - "@solidity-parser/parser" "^0.16.0" + "@solidity-parser/parser" "^0.18.0" chalk "^2.4.2" death "^1.1.0" detect-port "^1.3.0" @@ -7910,7 +6079,7 @@ solidity-coverage@^0.8.2: globby "^10.0.1" jsonschema "^1.2.4" lodash "^4.17.15" - mocha "10.2.0" + mocha "^10.2.0" node-emoji "^1.10.0" pify "^4.0.1" recursive-readdir "^2.2.2" @@ -7979,11 +6148,6 @@ statuses@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" @@ -8049,11 +6213,6 @@ string_decoder@^1.1.1: dependencies: safe-buffer "~5.2.0" -string_decoder@~0.10.x: - version "0.10.31" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" - integrity sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ== - string_decoder@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" @@ -8137,23 +6296,6 @@ supports-preserve-symlinks-flag@^1.0.0: resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== -swarm-js@^0.1.40: - version "0.1.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" @@ -8191,19 +6333,6 @@ table@^6.8.0, table@^6.8.1: 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" - text-table@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" @@ -8226,16 +6355,6 @@ then-request@^6.0.0: 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== - tmp@0.0.33: version "0.0.33" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" @@ -8243,11 +6362,6 @@ tmp@0.0.33: dependencies: os-tmpdir "~1.0.2" -to-fast-properties@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" - integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== - 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" @@ -8255,11 +6369,6 @@ to-regex-range@^5.0.1: 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" @@ -8304,9 +6413,9 @@ ts-essentials@^7.0.1: integrity sha512-8+gr5+lqO3G84KdiTSMRLtuyJ+nTBVRKuCrK4lidMPdVeEp0uqC875uE5NMcaA7YYMN7XsNiFQuMvasF8HT/xQ== ts-node@^10.9.1: - version "10.9.1" - resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.1.tgz#e73de9102958af9e1f0b168a6ff320e25adcff4b" - integrity sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw== + version "10.9.2" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.2.tgz#70f021c9e185bccdca820e26dc413805c101c71f" + integrity sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ== dependencies: "@cspotcode/source-map-support" "^0.8.0" "@tsconfig/node10" "^1.0.7" @@ -8322,10 +6431,10 @@ ts-node@^10.9.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== +tsconfig-paths@^3.15.0: + version "3.15.0" + resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz#5299ec605e55b1abb23ec939ef15edaf483070d4" + integrity sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg== dependencies: "@types/json5" "^0.0.29" json5 "^1.0.2" @@ -8337,11 +6446,6 @@ tslib@^1.9.3: resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== -tslib@^2.0.0: - version "2.6.2" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" - integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== - tsort@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/tsort/-/tsort-0.0.1.tgz#e2280f5e817f8bf4275657fd0f9aebd44f5a2786" @@ -8403,24 +6507,6 @@ type-fest@^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.1.1: version "8.3.2" resolved "https://registry.yarnpkg.com/typechain/-/typechain-8.3.2.tgz#1090dd8d9c57b6ef2aed3640a516bdbf01b00d73" @@ -8476,27 +6562,15 @@ typed-array-length@^1.0.4: 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.3.5: - version "4.9.5" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a" - integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== - typescript@^5.2.2: - version "5.2.2" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.2.2.tgz#5ebb5e5a5b75f085f22bc3f8460fba308310fa78" - integrity sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w== + version "5.3.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.3.3.tgz#b3ce6ba258e72e6305ba66f5c9b452aaee3ffe37" + integrity sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw== typical@^4.0.0: version "4.0.0" @@ -8513,11 +6587,6 @@ uglify-js@^3.1.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" @@ -8534,9 +6603,9 @@ undici-types@~5.26.4: 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== + version "5.28.2" + resolved "https://registry.yarnpkg.com/undici/-/undici-5.28.2.tgz#fea200eac65fc7ecaff80a023d1a0543423b4c91" + integrity sha512-wh1pHJHnUeQV5Xa8/kyQhO7WFa8M34l026L5P/+2TYiakvGy5Rdc8jWZVyG7ieht/0WgJLEd3kcU5gKx+6GC8w== dependencies: "@fastify/busboy" "^2.0.0" @@ -8550,19 +6619,11 @@ universalify@^2.0.0: 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: +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== -update-browserslist-db@^1.0.13: - version "1.0.13" - resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz#3c5e4f5c083661bd38ef64b6328c26ed6c8248c4" - integrity sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg== - dependencies: - escalade "^3.1.1" - picocolors "^1.0.0" - uri-js@^4.2.2: version "4.4.1" resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" @@ -8570,11 +6631,6 @@ uri-js@^4.2.2: 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" @@ -8597,14 +6653,7 @@ utf-8-validate@6.0.3: 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: +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== @@ -8614,22 +6663,6 @@ util-deprecate@^1.0.1, util-deprecate@~1.0.1: 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@^3.3.2: version "3.4.0" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" @@ -8640,26 +6673,11 @@ uuid@^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== -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" @@ -8669,250 +6687,6 @@ verror@1.10.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-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-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-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-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-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@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-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-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-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-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-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-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@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-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-provider-engine@16.0.3: - version "16.0.3" - resolved "https://registry.yarnpkg.com/web3-provider-engine/-/web3-provider-engine-16.0.3.tgz#8ff93edf3a8da2f70d7f85c5116028c06a0d9f07" - integrity sha512-Q3bKhGqLfMTdLvkd4TtkGYJHcoVQ82D1l8jTIwwuJp/sAp7VHnRYb9YJ14SW/69VMWoOhSpPLZV2tWb9V0WJoA== - dependencies: - "@ethereumjs/tx" "^3.3.0" - async "^2.5.0" - backoff "^2.5.0" - clone "^2.0.0" - cross-fetch "^2.1.0" - eth-block-tracker "^4.4.2" - eth-json-rpc-filters "^4.2.1" - eth-json-rpc-infura "^5.1.0" - eth-json-rpc-middleware "^6.0.0" - eth-rpc-errors "^3.0.0" - eth-sig-util "^1.4.2" - ethereumjs-block "^1.2.2" - ethereumjs-util "^5.1.5" - ethereumjs-vm "^2.3.4" - json-stable-stringify "^1.0.1" - promise-to-callback "^1.0.0" - readable-stream "^2.2.9" - request "^2.85.0" - semaphore "^1.0.3" - ws "^5.1.1" - xhr "^2.2.0" - xtend "^4.0.1" - -web3-providers-http@1.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-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-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-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-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.3.4, web3-utils@^1.3.6: version "1.10.3" resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.10.3.tgz#f1db99c82549c7d9f8348f04ffe4e0188b449714" @@ -8927,41 +6701,11 @@ web3-utils@^1.3.4, web3-utils@^1.3.6: 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" - 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-fetch@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz#dde6a5df315f9d39991aa17621853d720b85566f" - integrity sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng== - whatwg-url@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" @@ -8986,7 +6730,7 @@ which-module@^2.0.0: resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.1.tgz#776b1fe35d90aebe99e8ac15eb24093389a4a409" integrity sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ== -which-typed-array@^1.1.11, which-typed-array@^1.1.13, which-typed-array@^1.1.2: +which-typed-array@^1.1.11, which-typed-array@^1.1.13: 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== @@ -9067,69 +6811,16 @@ ws@8.13.0: resolved "https://registry.yarnpkg.com/ws/-/ws-8.13.0.tgz#9a9fb92f93cf41512a0735c8f4dd09b8a1211cd0" integrity sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA== -ws@^3.0.0: - version "3.3.3" - resolved "https://registry.yarnpkg.com/ws/-/ws-3.3.3.tgz#f1cf84fe2d5e901ebce94efaece785f187a228f2" - integrity sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA== - dependencies: - async-limiter "~1.0.0" - safe-buffer "~5.1.0" - ultron "~1.1.0" - -ws@^5.1.1: - version "5.2.3" - resolved "https://registry.yarnpkg.com/ws/-/ws-5.2.3.tgz#05541053414921bc29c63bee14b8b0dd50b07b3d" - integrity sha512-jZArVERrMsKUatIdnLzqvcfydI85dvd/Fp1u/VOpfdDWQ4c9qWXe+VIeAbQ5FrDwciAkr+lzofXLz3Kuf26AOA== - dependencies: - async-limiter "~1.0.0" - ws@^7.4.6: version "7.5.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.2.0, xhr@^2.3.3: - version "2.6.0" - resolved "https://registry.yarnpkg.com/xhr/-/xhr-2.6.0.tgz#b69d4395e792b4173d6b7df077f0fc5e4e2b249d" - integrity sha512-/eCGLb5rxjx5e3mF1A7s+pLlR6CGyqWN91fv1JgER5mVWg1MZmlhBvy9kjcsOdRk8RrIujotWyJamfyrp+WIcA== - dependencies: - global "~4.4.0" - is-function "^1.0.1" - parse-headers "^2.0.0" - xtend "^4.0.0" - -xtend@^4.0.0, xtend@^4.0.1, xtend@^4.0.2, 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== -xtend@~2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/xtend/-/xtend-2.1.2.tgz#6efecc2a4dad8e6962c4901b337ce7ba87b5d28b" - integrity sha512-vMNKzr2rHP9Dp/e1NQFnLQlwlhp9L/LfvnsVdHxN1f+uggyVI3i08uD14GPvCToPkdsRfyPqIyYGmIk58V98ZQ== - dependencies: - object-keys "~0.4.0" - y18n@^4.0.0: version "4.0.3" resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.3.tgz#b5f259c82cd6e336921efd7bfd8bf560de9eeedf" @@ -9140,12 +6831,7 @@ y18n@^5.0.5: 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: +yallist@^3.0.2: version "3.1.1" resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==